mirror of https://github.com/jlelse/GoBlog
Unit and integration tests for Telegram
This commit is contained in:
parent
9c9a217c07
commit
c9af4e7efa
2
app.go
2
app.go
|
@ -36,7 +36,7 @@ type goBlog struct {
|
|||
pPostHooks []postHookFunc
|
||||
pUpdateHooks []postHookFunc
|
||||
pDeleteHooks []postHookFunc
|
||||
// HTTP
|
||||
// HTTP Routers
|
||||
d *dynamicHandler
|
||||
privateMode bool
|
||||
privateModeHandler []func(http.Handler) http.Handler
|
||||
|
|
|
@ -4,6 +4,10 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func (a *goBlog) setInMemoryDatabase() {
|
||||
a.db, _ = a.openDatabase(":memory:", false)
|
||||
}
|
||||
|
||||
func Test_database(t *testing.T) {
|
||||
t.Run("Basic Database Test", func(t *testing.T) {
|
||||
app := &goBlog{}
|
||||
|
|
|
@ -5,7 +5,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var appHttpClient = &http.Client{
|
||||
type httpClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
var appHttpClient httpClient = &http.Client{
|
||||
Timeout: 5 * time.Minute,
|
||||
Transport: &http.Transport{
|
||||
DisableKeepAlives: true,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type fakeHttpClient struct {
|
||||
req *http.Request
|
||||
res *http.Response
|
||||
err error
|
||||
enabled bool
|
||||
// internal
|
||||
alt httpClient
|
||||
mx sync.Mutex
|
||||
}
|
||||
|
||||
var fakeAppHttpClient *fakeHttpClient
|
||||
|
||||
func init() {
|
||||
fakeAppHttpClient = &fakeHttpClient{
|
||||
alt: appHttpClient,
|
||||
}
|
||||
appHttpClient = fakeAppHttpClient
|
||||
}
|
||||
|
||||
func (c *fakeHttpClient) Do(req *http.Request) (*http.Response, error) {
|
||||
if !c.enabled {
|
||||
return c.alt.Do(req)
|
||||
}
|
||||
c.req = req
|
||||
return c.res, c.err
|
||||
}
|
||||
|
||||
func (c *fakeHttpClient) clean() {
|
||||
c.req = nil
|
||||
c.err = nil
|
||||
c.res = nil
|
||||
}
|
||||
|
||||
func (c *fakeHttpClient) setFakeResponse(statusCode int, body string, err error) {
|
||||
c.clean()
|
||||
c.err = err
|
||||
c.res = &http.Response{
|
||||
StatusCode: statusCode,
|
||||
Body: io.NopCloser(strings.NewReader(body)),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *fakeHttpClient) lock(enabled bool) {
|
||||
c.mx.Lock()
|
||||
c.clean()
|
||||
c.enabled = enabled
|
||||
}
|
||||
|
||||
func (c *fakeHttpClient) unlock() {
|
||||
c.enabled = false
|
||||
c.clean()
|
||||
c.mx.Unlock()
|
||||
}
|
|
@ -30,11 +30,9 @@ func (a *goBlog) sendNotification(text string) {
|
|||
log.Println("Failed to save notification:", err.Error())
|
||||
}
|
||||
if an := a.cfg.Notifications; an != nil {
|
||||
if tg := an.Telegram; tg != nil && tg.Enabled {
|
||||
err := sendTelegramMessage(n.Text, "", tg.BotToken, tg.ChatID)
|
||||
if err != nil {
|
||||
log.Println("Failed to send Telegram notification:", err.Error())
|
||||
}
|
||||
err := an.Telegram.send(n.Text, "")
|
||||
if err != nil {
|
||||
log.Println("Failed to send Telegram notification:", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
telegram.go
44
telegram.go
|
@ -14,24 +14,27 @@ import (
|
|||
const telegramBaseURL = "https://api.telegram.org/bot"
|
||||
|
||||
func (a *goBlog) initTelegram() {
|
||||
enable := false
|
||||
for _, b := range a.cfg.Blogs {
|
||||
if tg := b.Telegram; tg != nil && tg.Enabled && tg.BotToken != "" && tg.ChatID != "" {
|
||||
enable = true
|
||||
}
|
||||
}
|
||||
if enable {
|
||||
a.pPostHooks = append(a.pPostHooks, func(p *post) {
|
||||
if p.isPublishedSectionPost() {
|
||||
tgPost(a.cfg.Blogs[p.Blog].Telegram, p.title(), a.fullPostURL(p), a.shortPostURL(p))
|
||||
a.pPostHooks = append(a.pPostHooks, func(p *post) {
|
||||
if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() && p.isPublishedSectionPost() {
|
||||
if html := tg.generateHTML(p.title(), a.fullPostURL(p), a.shortPostURL(p)); html != "" {
|
||||
if err := tg.send(html, "HTML"); err != nil {
|
||||
log.Printf("Failed to send post to Telegram: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func tgPost(tg *configTelegram, title, fullURL, shortURL string) {
|
||||
func (tg *configTelegram) enabled() bool {
|
||||
if tg == nil || !tg.Enabled || tg.BotToken == "" || tg.ChatID == "" {
|
||||
return
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (tg *configTelegram) generateHTML(title, fullURL, shortURL string) string {
|
||||
if !tg.enabled() {
|
||||
return ""
|
||||
}
|
||||
replacer := strings.NewReplacer("<", "<", ">", ">", "&", "&")
|
||||
var message bytes.Buffer
|
||||
|
@ -48,19 +51,20 @@ func tgPost(tg *configTelegram, title, fullURL, shortURL string) {
|
|||
message.WriteString(replacer.Replace(shortURL))
|
||||
message.WriteString("</a>")
|
||||
}
|
||||
if err := sendTelegramMessage(message.String(), "HTML", tg.BotToken, tg.ChatID); err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
return message.String()
|
||||
}
|
||||
|
||||
func sendTelegramMessage(message, mode, token, chat string) error {
|
||||
func (tg *configTelegram) send(message, mode string) error {
|
||||
if !tg.enabled() {
|
||||
return nil
|
||||
}
|
||||
params := url.Values{}
|
||||
params.Add("chat_id", chat)
|
||||
params.Add("chat_id", tg.ChatID)
|
||||
params.Add("text", message)
|
||||
if mode != "" {
|
||||
params.Add("parse_mode", mode)
|
||||
}
|
||||
tgURL, err := url.Parse(telegramBaseURL + token + "/sendMessage")
|
||||
tgURL, err := url.Parse(telegramBaseURL + tg.BotToken + "/sendMessage")
|
||||
if err != nil {
|
||||
return errors.New("failed to create Telegram request")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test_configTelegram_enabled(t *testing.T) {
|
||||
if (&configTelegram{}).enabled() == true {
|
||||
t.Error("Telegram shouldn't be enabled")
|
||||
}
|
||||
|
||||
if (&configTelegram{
|
||||
Enabled: true,
|
||||
}).enabled() == true {
|
||||
t.Error("Telegram shouldn't be enabled")
|
||||
}
|
||||
|
||||
if (&configTelegram{
|
||||
Enabled: true,
|
||||
ChatID: "abc",
|
||||
}).enabled() == true {
|
||||
t.Error("Telegram shouldn't be enabled")
|
||||
}
|
||||
|
||||
if (&configTelegram{
|
||||
Enabled: true,
|
||||
BotToken: "abc",
|
||||
}).enabled() == true {
|
||||
t.Error("Telegram shouldn't be enabled")
|
||||
}
|
||||
|
||||
if (&configTelegram{
|
||||
Enabled: true,
|
||||
BotToken: "abc",
|
||||
ChatID: "abc",
|
||||
}).enabled() != true {
|
||||
t.Error("Telegram should be enabled")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_configTelegram_generateHTML(t *testing.T) {
|
||||
tg := &configTelegram{
|
||||
Enabled: true,
|
||||
ChatID: "abc",
|
||||
BotToken: "abc",
|
||||
}
|
||||
|
||||
// Without Instant View
|
||||
|
||||
expected := "Title\n\n<a href=\"https://example.com/s/1\">https://example.com/s/1</a>"
|
||||
if got := tg.generateHTML("Title", "https://example.com/test", "https://example.com/s/1"); got != expected {
|
||||
t.Errorf("Wrong result, got: %v", got)
|
||||
}
|
||||
|
||||
// With Instant View
|
||||
|
||||
tg.InstantViewHash = "abc"
|
||||
expected = "Title\n\n<a href=\"https://t.me/iv?rhash=abc&url=https%3A%2F%2Fexample.com%2Ftest\">https://example.com/s/1</a>"
|
||||
if got := tg.generateHTML("Title", "https://example.com/test", "https://example.com/s/1"); got != expected {
|
||||
t.Errorf("Wrong result, got: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_configTelegram_send(t *testing.T) {
|
||||
fakeAppHttpClient.lock(true)
|
||||
defer fakeAppHttpClient.unlock()
|
||||
|
||||
tg := &configTelegram{
|
||||
Enabled: true,
|
||||
ChatID: "chatid",
|
||||
BotToken: "bottoken",
|
||||
}
|
||||
|
||||
fakeAppHttpClient.setFakeResponse(200, "", nil)
|
||||
|
||||
err := tg.send("Message", "HTML")
|
||||
if err != nil {
|
||||
t.Errorf("Error: %v", err)
|
||||
}
|
||||
|
||||
if fakeAppHttpClient.req == nil {
|
||||
t.Error("Empty request")
|
||||
}
|
||||
if fakeAppHttpClient.err != nil {
|
||||
t.Error("Error in request")
|
||||
}
|
||||
if fakeAppHttpClient.req.Method != http.MethodPost {
|
||||
t.Error("Wrong method")
|
||||
}
|
||||
if u := fakeAppHttpClient.req.URL.String(); u != "https://api.telegram.org/botbottoken/sendMessage?chat_id=chatid&parse_mode=HTML&text=Message" {
|
||||
t.Errorf("Wrong request URL, got: %v", u)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_goBlog_initTelegram(t *testing.T) {
|
||||
app := &goBlog{
|
||||
pPostHooks: []postHookFunc{},
|
||||
}
|
||||
|
||||
app.initTelegram()
|
||||
|
||||
if len(app.pPostHooks) != 1 {
|
||||
t.Error("Hook not registered")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_telegram(t *testing.T) {
|
||||
t.Run("Send post to Telegram", func(t *testing.T) {
|
||||
fakeAppHttpClient.lock(true)
|
||||
defer fakeAppHttpClient.unlock()
|
||||
|
||||
fakeAppHttpClient.setFakeResponse(200, "", nil)
|
||||
|
||||
app := &goBlog{
|
||||
pPostHooks: []postHookFunc{},
|
||||
cfg: &config{
|
||||
Server: &configServer{
|
||||
PublicAddress: "https://example.com",
|
||||
},
|
||||
Blogs: map[string]*configBlog{
|
||||
"en": {
|
||||
Telegram: &configTelegram{
|
||||
Enabled: true,
|
||||
ChatID: "chatid",
|
||||
BotToken: "bottoken",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
app.setInMemoryDatabase()
|
||||
|
||||
app.initTelegram()
|
||||
|
||||
p := &post{
|
||||
Path: "/test",
|
||||
Parameters: map[string][]string{
|
||||
"title": {"Title"},
|
||||
},
|
||||
Published: time.Now().String(),
|
||||
Section: "test",
|
||||
Blog: "en",
|
||||
Status: statusPublished,
|
||||
}
|
||||
|
||||
app.pPostHooks[0](p)
|
||||
|
||||
if u := fakeAppHttpClient.req.URL.String(); u != "https://api.telegram.org/botbottoken/sendMessage?chat_id=chatid&parse_mode=HTML&text=Title%0A%0A%3Ca+href%3D%22https%3A%2F%2Fexample.com%2Fs%2F1%22%3Ehttps%3A%2F%2Fexample.com%2Fs%2F1%3C%2Fa%3E" {
|
||||
t.Errorf("Wrong request URL, got: %v", u)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Telegram disabled", func(t *testing.T) {
|
||||
fakeAppHttpClient.lock(true)
|
||||
defer fakeAppHttpClient.unlock()
|
||||
|
||||
fakeAppHttpClient.setFakeResponse(200, "", nil)
|
||||
|
||||
app := &goBlog{
|
||||
pPostHooks: []postHookFunc{},
|
||||
cfg: &config{
|
||||
Server: &configServer{
|
||||
PublicAddress: "https://example.com",
|
||||
},
|
||||
Blogs: map[string]*configBlog{
|
||||
"en": {},
|
||||
},
|
||||
},
|
||||
}
|
||||
app.setInMemoryDatabase()
|
||||
|
||||
app.initTelegram()
|
||||
|
||||
p := &post{
|
||||
Path: "/test",
|
||||
Parameters: map[string][]string{
|
||||
"title": {"Title"},
|
||||
},
|
||||
Published: time.Now().String(),
|
||||
Section: "test",
|
||||
Blog: "en",
|
||||
Status: statusPublished,
|
||||
}
|
||||
|
||||
app.pPostHooks[0](p)
|
||||
|
||||
if fakeAppHttpClient.req != nil {
|
||||
t.Error("There should be no request")
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue