From 4857a82493dfb283e4616c4a1947b1d1786e2ea6 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Mon, 8 Nov 2021 14:32:02 +0100 Subject: [PATCH] Add automatic test for contact submissions and some other small improvements --- contact.go | 89 ++++++++++++------------- contact_test.go | 75 +++++++++++++++++++++ go.mod | 6 +- go.sum | 12 ++-- httpClient.go | 23 +++++-- httpClient_test.go | 7 +- main.go | 2 +- mediaCompression.go | 6 ++ mediaCompression_test.go | 4 +- pkgs/mocksmtp/mocksmtp.go | 118 +++++++++++++++++++++++++++++++++ pkgs/mocksmtp/mocksmtp_test.go | 32 +++++++++ telegram_test.go | 6 +- 12 files changed, 306 insertions(+), 74 deletions(-) create mode 100644 contact_test.go create mode 100644 pkgs/mocksmtp/mocksmtp.go create mode 100644 pkgs/mocksmtp/mocksmtp_test.go diff --git a/contact.go b/contact.go index 875faaf..180361f 100644 --- a/contact.go +++ b/contact.go @@ -26,68 +26,38 @@ func (a *goBlog) serveContactForm(w http.ResponseWriter, r *http.Request) { } func (a *goBlog) sendContactSubmission(w http.ResponseWriter, r *http.Request) { - // Get form values - // Name - formName := cleanHTMLText(r.FormValue("name")) - // Email - formEmail := cleanHTMLText(r.FormValue("email")) - // Website - formWebsite := cleanHTMLText(r.FormValue("website")) + // Get blog + blog, bc := a.getBlog(r) + // Get form values and build message + var message bytes.Buffer // Message formMessage := cleanHTMLText(r.FormValue("message")) if formMessage == "" { a.serveError(w, r, "Message is empty", http.StatusBadRequest) return } - // Build message - var message bytes.Buffer - if formName != "" { - _, _ = fmt.Fprintf(&message, "Name: %s", formName) - _, _ = fmt.Fprintln(&message) + // Name + if formName := cleanHTMLText(r.FormValue("name")); formName != "" { + _, _ = fmt.Fprintf(&message, "Name: %s\n", formName) } + // Email + formEmail := cleanHTMLText(r.FormValue("email")) if formEmail != "" { - _, _ = fmt.Fprintf(&message, "Email: %s", formEmail) - _, _ = fmt.Fprintln(&message) + _, _ = fmt.Fprintf(&message, "Email: %s\n", formEmail) } - if formWebsite != "" { - _, _ = fmt.Fprintf(&message, "Website: %s", formWebsite) - _, _ = fmt.Fprintln(&message) + // Website + if formWebsite := cleanHTMLText(r.FormValue("website")); formWebsite != "" { + _, _ = fmt.Fprintf(&message, "Website: %s\n", formWebsite) } + // Add line break if message is not empty if message.Len() > 0 { - _, _ = fmt.Fprintln(&message) + _, _ = fmt.Fprintf(&message, "\n") } + // Add message text to message _, _ = message.WriteString(formMessage) // Send submission - blog, bc := a.getBlog(r) - if cc := bc.Contact; cc != nil && cc.SMTPHost != "" && cc.EmailFrom != "" && cc.EmailTo != "" { - // Build email - var email bytes.Buffer - if ef := cc.EmailFrom; ef != "" { - _, _ = fmt.Fprintf(&email, "From: %s <%s>", defaultIfEmpty(bc.Title, "GoBlog"), cc.EmailFrom) - _, _ = fmt.Fprintln(&email) - } - _, _ = fmt.Fprintf(&email, "To: %s", cc.EmailTo) - _, _ = fmt.Fprintln(&email) - if formEmail != "" { - _, _ = fmt.Fprintf(&email, "Reply-To: %s", formEmail) - _, _ = fmt.Fprintln(&email) - } - _, _ = fmt.Fprintf(&email, "Date: %s", time.Now().UTC().Format(time.RFC1123Z)) - _, _ = fmt.Fprintln(&email) - _, _ = fmt.Fprintln(&email, "Subject: New message") - _, _ = fmt.Fprintln(&email) - _, _ = fmt.Fprintln(&email, message.String()) - // Send email - auth := smtp.PlainAuth("", cc.SMTPUser, cc.SMTPPassword, cc.SMTPHost) - port := cc.SMTPPort - if port == 0 { - port = 587 - } - if err := smtp.SendMail(cc.SMTPHost+":"+strconv.Itoa(port), auth, cc.EmailFrom, []string{cc.EmailTo}, email.Bytes()); err != nil { - log.Println("Failed to send mail:", err.Error()) - } - } else { - log.Println("New contact submission not send as email, config missing") + if err := a.sendContactEmail(bc.Contact, message.String(), formEmail); err != nil { + log.Println(err.Error()) } // Send notification a.sendNotification(message.String()) @@ -99,3 +69,26 @@ func (a *goBlog) sendContactSubmission(w http.ResponseWriter, r *http.Request) { }, }) } + +func (a *goBlog) sendContactEmail(cc *configContact, body, replyTo string) error { + // Check required config + if cc == nil || cc.SMTPHost == "" || cc.EmailFrom == "" || cc.EmailTo == "" { + return fmt.Errorf("email not send as config is missing") + } + // Build email + var email bytes.Buffer + _, _ = fmt.Fprintf(&email, "To: %s\n", cc.EmailTo) + if replyTo != "" { + _, _ = fmt.Fprintf(&email, "Reply-To: %s\n", replyTo) + } + _, _ = fmt.Fprintf(&email, "Date: %s\n", time.Now().UTC().Format(time.RFC1123Z)) + _, _ = fmt.Fprintf(&email, "Subject: New message\n\n") + _, _ = fmt.Fprintf(&email, "%s\n", body) + // Send email using SMTP + auth := smtp.PlainAuth("", cc.SMTPUser, cc.SMTPPassword, cc.SMTPHost) + port := cc.SMTPPort + if port == 0 { + port = 587 + } + return smtp.SendMail(cc.SMTPHost+":"+strconv.Itoa(port), auth, cc.EmailFrom, []string{cc.EmailTo}, email.Bytes()) +} diff --git a/contact_test.go b/contact_test.go new file mode 100644 index 0000000..0b43195 --- /dev/null +++ b/contact_test.go @@ -0,0 +1,75 @@ +package main + +import ( + "context" + "net/http" + "net/http/httptest" + "net/url" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.goblog.app/app/pkgs/contenttype" + "go.goblog.app/app/pkgs/mocksmtp" +) + +func Test_contact(t *testing.T) { + + // Start the SMTP server + port, rd, err := mocksmtp.StartMockSMTPServer() + require.NoError(t, err) + + // Init everything + app := &goBlog{ + cfg: &config{ + Db: &configDb{ + File: filepath.Join(t.TempDir(), "test.db"), + }, + Server: &configServer{ + PublicAddress: "https://example.com", + }, + Blogs: map[string]*configBlog{ + "en": { + Lang: "en", + // Config for contact + Contact: &configContact{ + Enabled: true, + SMTPPort: port, + SMTPHost: "127.0.0.1", + SMTPUser: "user", + SMTPPassword: "pass", + EmailTo: "to@example.org", + EmailFrom: "from@example.org", + }, + }, + }, + DefaultBlog: "en", + User: &configUser{}, + }, + } + _ = app.initDatabase(false) + app.initComponents(false) + + // Make contact form request + rec := httptest.NewRecorder() + data := url.Values{} + data.Add("name", "Test User") + data.Add("email", "test@example.net") + data.Add("website", "https://test.example.com") + data.Add("message", "This is a test contact message") + req := httptest.NewRequest(http.MethodPost, "/contact", strings.NewReader(data.Encode())) + req.Header.Add(contentType, contenttype.WWWForm) + app.sendContactSubmission(rec, req.WithContext(context.WithValue(req.Context(), blogKey, "en"))) + require.Equal(t, http.StatusOK, rec.Result().StatusCode) + + // Check sent mail + received, err := rd() + require.NoError(t, err) + assert.Contains(t, received, "This is a test contact message") + assert.Contains(t, received, "test@example.net") + assert.Contains(t, received, "https://test.example.com") + assert.Contains(t, received, "Test User") + +} diff --git a/go.mod b/go.mod index f83043a..a81c2c8 100644 --- a/go.mod +++ b/go.mod @@ -41,11 +41,11 @@ require ( github.com/thoas/go-funk v0.9.1 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2 - github.com/yuin/goldmark v1.4.2 + github.com/yuin/goldmark v1.4.3 // master github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 + golang.org/x/net v0.0.0-20211105192438-b53810dc28af golang.org/x/sync v0.0.0-20210220032951-036812b2e83c gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b tailscale.com v1.16.2 @@ -99,7 +99,7 @@ require ( go4.org/intern v0.0.0-20210108033219-3eb7198706b2 // indirect go4.org/mem v0.0.0-20201119185036-c04c5a6ff174 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 // indirect - golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect + golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect golang.zx2c4.com/wireguard v0.0.0-20210905140043-2ef39d47540c // indirect diff --git a/go.sum b/go.sum index 5eef9b8..2ed7a97 100644 --- a/go.sum +++ b/go.sum @@ -459,8 +459,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.2 h1:5qVKCqCRBaGz8EepBTi7pbIw8gGCFnB1Mi6kXU4dYv8= -github.com/yuin/goldmark v1.4.2/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= +github.com/yuin/goldmark v1.4.3 h1:eTEYYWtQLjK7+WK45Tk81OTkp/0UvAyqUj8flU0nTO4= +github.com/yuin/goldmark v1.4.3/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38 h1:XZjLcLoTPNZuxppY3gwhRqo/T2XF6JMGFFdkAjX3w1w= github.com/yuin/goldmark-emoji v1.0.2-0.20210607094911-0487583eca38/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -582,8 +582,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU= -golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211105192438-b53810dc28af h1:SMeNJG/vclJ5wyBBd4xupMsSJIHTd1coW9g7q6KOjmY= +golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -682,8 +682,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 h1:G2DDmludOQZoWbpCr7OKDxnl478ZBGMcOhrv+ooX/Q4= +golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w= diff --git a/httpClient.go b/httpClient.go index 6eee87a..e183855 100644 --- a/httpClient.go +++ b/httpClient.go @@ -9,11 +9,20 @@ type httpClient interface { Do(req *http.Request) (*http.Response, error) } -func getHTTPClient() httpClient { - return &http.Client{ - Timeout: 5 * time.Minute, - Transport: &http.Transport{ - DisableKeepAlives: true, - }, - } +type appHttpClient struct { + hc *http.Client +} + +var _ httpClient = &appHttpClient{} + +func (c *appHttpClient) Do(req *http.Request) (*http.Response, error) { + if c.hc == nil { + c.hc = &http.Client{ + Timeout: 5 * time.Minute, + Transport: &http.Transport{ + DisableKeepAlives: true, + }, + } + } + return c.hc.Do(req) } diff --git a/httpClient_test.go b/httpClient_test.go index 06f144d..b236f91 100644 --- a/httpClient_test.go +++ b/httpClient_test.go @@ -6,11 +6,14 @@ import ( ) type fakeHttpClient struct { + httpClient req *http.Request res *http.Response handler http.Handler } +var _ httpClient = &fakeHttpClient{} + func (c *fakeHttpClient) Do(req *http.Request) (*http.Response, error) { if c.handler == nil { return nil, nil @@ -39,7 +42,3 @@ func (c *fakeHttpClient) setFakeResponse(statusCode int, body string) { _, _ = rw.Write([]byte(body)) })) } - -func getFakeHTTPClient() *fakeHttpClient { - return &fakeHttpClient{} -} diff --git a/main.go b/main.go index 33e0a55..4f9816f 100644 --- a/main.go +++ b/main.go @@ -50,7 +50,7 @@ func main() { initGC() app := &goBlog{ - httpClient: getHTTPClient(), + httpClient: &appHttpClient{}, } // Initialize config diff --git a/mediaCompression.go b/mediaCompression.go index 43efbf8..742ea44 100644 --- a/mediaCompression.go +++ b/mediaCompression.go @@ -53,6 +53,8 @@ type shortpixel struct { key string } +var _ mediaCompression = &shortpixel{} + func (sp *shortpixel) compress(url string, upload mediaStorageSaveFunc, hc httpClient) (location string, err error) { // Check url fileExtension, allowed := urlHasExt(url, "jpg", "jpeg", "png") @@ -107,6 +109,8 @@ type tinify struct { key string } +var _ mediaCompression = &tinify{} + func (tf *tinify) compress(url string, upload mediaStorageSaveFunc, hc httpClient) (location string, err error) { // Check url fileExtension, allowed := urlHasExt(url, "jpg", "jpeg", "png") @@ -182,6 +186,8 @@ func (tf *tinify) compress(url string, upload mediaStorageSaveFunc, hc httpClien type cloudflare struct { } +var _ mediaCompression = &cloudflare{} + func (cf *cloudflare) compress(url string, upload mediaStorageSaveFunc, hc httpClient) (location string, err error) { // Check url _, allowed := urlHasExt(url, "jpg", "jpeg", "png") diff --git a/mediaCompression_test.go b/mediaCompression_test.go index 6cc2eda..0182cdc 100644 --- a/mediaCompression_test.go +++ b/mediaCompression_test.go @@ -27,7 +27,7 @@ func Test_compress(t *testing.T) { } t.Run("Cloudflare", func(t *testing.T) { - fakeClient := getFakeHTTPClient() + fakeClient := &fakeHttpClient{} fakeClient.setHandler(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { assert.Equal(t, "https://www.cloudflare.com/cdn-cgi/image/f=jpeg,q=75,metadata=none,fit=scale-down,w=2000,h=3000/https://example.com/original.jpg", r.URL.String()) @@ -43,7 +43,7 @@ func Test_compress(t *testing.T) { }) t.Run("Shortpixel", func(t *testing.T) { - fakeClient := getFakeHTTPClient() + fakeClient := &fakeHttpClient{} fakeClient.setHandler(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { assert.Equal(t, "https://api.shortpixel.com/v2/reducer-sync.php", r.URL.String()) diff --git a/pkgs/mocksmtp/mocksmtp.go b/pkgs/mocksmtp/mocksmtp.go new file mode 100644 index 0000000..91997c4 --- /dev/null +++ b/pkgs/mocksmtp/mocksmtp.go @@ -0,0 +1,118 @@ +// This package contains code to mock an SMTP server and test mail sending. + +package mocksmtp + +import ( + "bufio" + "bytes" + "fmt" + "net" + "net/textproto" + "strconv" +) + +// Inspired by https://play.golang.org/p/8mfrqNVWTPK + +type ReceivedGetter func() (string, error) + +func StartMockSMTPServer() (port int, rg ReceivedGetter, err error) { + + // Default server responses + serverResponses := []string{ + "220 smtp.example.com Service ready", + "250-ELHO -> ok", + "250-Show Options for ESMTP", + "250-8BITMIME", + "250-SIZE", + "250-AUTH LOGIN PLAIN", + "250 HELP", + "235 AUTH -> ok", + "250 MAIL FROM -> ok", + "250 RCPT TO -> ok", + "354 DATA", + "250 ... -> ok", + "221 QUIT", + } + + // Channel to check if error occured or done + var errOrDone = make(chan error) + + // Received data buffer + var buffer bytes.Buffer + bufferWriter := bufio.NewWriter(&buffer) + + // Start server on random port + mockSmtpServer, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return 0, nil, err + } + + // Get port from listener + _, portStr, err := net.SplitHostPort(mockSmtpServer.Addr().String()) + if err != nil { + return 0, nil, err + } + port, err = strconv.Atoi(portStr) + if err != nil { + return 0, nil, err + } + + // Run mock SMTP server + go func() { + defer close(errOrDone) + defer bufferWriter.Flush() + defer mockSmtpServer.Close() + + conn, err := mockSmtpServer.Accept() + if err != nil { + errOrDone <- err + return + } + defer conn.Close() + + tc := textproto.NewConn(conn) + defer tc.Close() + + for _, res := range serverResponses { + if res == "" { + break + } + + _ = tc.PrintfLine("%s", res) + + if len(res) >= 4 && res[3] == '-' { + continue + } + + if res == "221 QUIT" { + return + } + + for { + msg, err := tc.ReadLine() + if err != nil { + errOrDone <- err + return + } + + _, _ = fmt.Fprintf(bufferWriter, "%s\n", msg) + + if res != "354 DATA" || msg == "." { + break + } + } + } + }() + + // Define function to get received data + getReceivedData := func() (string, error) { + err, hasErr := <-errOrDone + if hasErr { + return "", err + } + return buffer.String(), nil + } + + // Return port and function + return port, getReceivedData, nil +} diff --git a/pkgs/mocksmtp/mocksmtp_test.go b/pkgs/mocksmtp/mocksmtp_test.go new file mode 100644 index 0000000..81cac79 --- /dev/null +++ b/pkgs/mocksmtp/mocksmtp_test.go @@ -0,0 +1,32 @@ +package mocksmtp + +import ( + "fmt" + "net/smtp" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_mocksmtp(t *testing.T) { + // Start mock SMTP server + port, getRecievedData, err := StartMockSMTPServer() + require.NoError(t, err) + + // Send mail + err = smtp.SendMail( + fmt.Sprintf("127.0.0.1:%d", port), + smtp.PlainAuth("", "user", "pass", "127.0.0.1"), + "admin@smtp.example.com", + []string{"user@smtp.example.com"}, + []byte("From: admin@smtp.example.com\nTo: user@smtp.example.com\nSubject: Test\nMIME-version: 1.0\nContent-Type: text/html; charset=\"UTF-8\"\n\nThis is a test mail."), + ) + require.NoError(t, err) + + // Get received data + recievedData, err := getRecievedData() + require.NoError(t, err) + assert.Contains(t, recievedData, "From:") + assert.Contains(t, recievedData, "This is a test mail") +} diff --git a/telegram_test.go b/telegram_test.go index c9e11da..7797357 100644 --- a/telegram_test.go +++ b/telegram_test.go @@ -72,7 +72,7 @@ func Test_configTelegram_generateHTML(t *testing.T) { } func Test_configTelegram_send(t *testing.T) { - fakeClient := getFakeHTTPClient() + fakeClient := &fakeHttpClient{} tg := &configTelegram{ Enabled: true, @@ -108,7 +108,7 @@ func Test_goBlog_initTelegram(t *testing.T) { func Test_telegram(t *testing.T) { t.Run("Send post to Telegram", func(t *testing.T) { - fakeClient := getFakeHTTPClient() + fakeClient := &fakeHttpClient{} fakeClient.setFakeResponse(200, "") @@ -157,7 +157,7 @@ func Test_telegram(t *testing.T) { }) t.Run("Telegram disabled", func(t *testing.T) { - fakeClient := getFakeHTTPClient() + fakeClient := &fakeHttpClient{} fakeClient.setFakeResponse(200, "")