250 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"git.32bit.cafe/32bitcafe/guestbook/internal/assert"
 | 
						|
)
 | 
						|
 | 
						|
func TestPing(t *testing.T) {
 | 
						|
	app := newTestApplication(t)
 | 
						|
	ts := newTestServer(t, app.routes())
 | 
						|
	defer ts.Close()
 | 
						|
 | 
						|
	code, _, body := ts.get(t, "/ping")
 | 
						|
 | 
						|
	assert.Equal(t, code, http.StatusOK)
 | 
						|
	assert.Equal(t, body, "OK")
 | 
						|
}
 | 
						|
 | 
						|
func TestGetGuestbookView(t *testing.T) {
 | 
						|
	app := newTestApplication(t)
 | 
						|
	ts := newTestServer(t, app.routes())
 | 
						|
	defer ts.Close()
 | 
						|
 | 
						|
	tests := []struct {
 | 
						|
		name     string
 | 
						|
		urlPath  string
 | 
						|
		wantCode int
 | 
						|
		wantBody string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:     "Valid id",
 | 
						|
			urlPath:  fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(1)),
 | 
						|
			wantCode: http.StatusOK,
 | 
						|
			wantBody: "Guestbook for Example",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "Non-existent ID",
 | 
						|
			urlPath:  fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(2)),
 | 
						|
			wantCode: http.StatusNotFound,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "String ID",
 | 
						|
			urlPath:  "/websites/abcd/guestbook",
 | 
						|
			wantCode: http.StatusNotFound,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			code, _, body := ts.get(t, tt.urlPath)
 | 
						|
			assert.Equal(t, code, tt.wantCode)
 | 
						|
			if tt.wantBody != "" {
 | 
						|
				assert.StringContains(t, body, tt.wantBody)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestPostGuestbookCommentCreate(t *testing.T) {
 | 
						|
	app := newTestApplication(t)
 | 
						|
	ts := newTestServer(t, app.routes())
 | 
						|
	defer ts.Close()
 | 
						|
 | 
						|
	_, _, body := ts.get(t, fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(1)))
 | 
						|
	validCSRFToken := extractCSRFToken(t, body)
 | 
						|
 | 
						|
	const (
 | 
						|
		validAuthorName  = "John Test"
 | 
						|
		validAuthorEmail = "test@example.com"
 | 
						|
		validAuthorSite  = "example.com"
 | 
						|
		validContent     = "This is a comment"
 | 
						|
	)
 | 
						|
 | 
						|
	tests := []struct {
 | 
						|
		name        string
 | 
						|
		authorName  string
 | 
						|
		authorEmail string
 | 
						|
		authorSite  string
 | 
						|
		content     string
 | 
						|
		csrfToken   string
 | 
						|
		wantCode    int
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:        "Valid input",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			csrfToken:   validCSRFToken,
 | 
						|
			wantCode:    http.StatusSeeOther,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank name",
 | 
						|
			authorName:  "",
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			csrfToken:   validCSRFToken,
 | 
						|
			wantCode:    http.StatusUnprocessableEntity,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank email",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: "",
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			csrfToken:   validCSRFToken,
 | 
						|
			wantCode:    http.StatusSeeOther,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank site",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  "",
 | 
						|
			content:     validContent,
 | 
						|
			csrfToken:   validCSRFToken,
 | 
						|
			wantCode:    http.StatusSeeOther,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank content",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     "",
 | 
						|
			csrfToken:   validCSRFToken,
 | 
						|
			wantCode:    http.StatusUnprocessableEntity,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			form := url.Values{}
 | 
						|
			form.Add("authorname", tt.authorName)
 | 
						|
			form.Add("authoremail", tt.authorEmail)
 | 
						|
			form.Add("authorsite", tt.authorSite)
 | 
						|
			form.Add("content", tt.content)
 | 
						|
			form.Add("csrf_token", tt.csrfToken)
 | 
						|
			code, _, body := ts.postForm(t, fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(1)), form)
 | 
						|
			assert.Equal(t, code, tt.wantCode)
 | 
						|
			assert.Equal(t, body, body)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestPostGuestbookCommentCreateRemote(t *testing.T) {
 | 
						|
	app := newTestApplication(t)
 | 
						|
	ts := newTestServer(t, app.routes())
 | 
						|
	defer ts.Close()
 | 
						|
 | 
						|
	const (
 | 
						|
		validAuthorName  = "John Test"
 | 
						|
		validAuthorEmail = "test@example.com"
 | 
						|
		validAuthorSite  = "example.com"
 | 
						|
		validContent     = "This is a comment"
 | 
						|
	)
 | 
						|
 | 
						|
	tests := []struct {
 | 
						|
		name        string
 | 
						|
		authorName  string
 | 
						|
		authorEmail string
 | 
						|
		authorSite  string
 | 
						|
		content     string
 | 
						|
		wantCode    int
 | 
						|
		wantBody    string
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:        "Valid input",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			wantCode:    http.StatusOK,
 | 
						|
			wantBody:    "Comment successfully posted",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank name",
 | 
						|
			authorName:  "",
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			wantCode:    http.StatusOK,
 | 
						|
			wantBody:    "An error occurred",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank email",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: "",
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     validContent,
 | 
						|
			wantCode:    http.StatusOK,
 | 
						|
			wantBody:    "Comment successfully posted",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank site",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  "",
 | 
						|
			content:     validContent,
 | 
						|
			wantCode:    http.StatusOK,
 | 
						|
			wantBody:    "Comment successfully posted",
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Blank content",
 | 
						|
			authorName:  validAuthorName,
 | 
						|
			authorEmail: validAuthorEmail,
 | 
						|
			authorSite:  validAuthorSite,
 | 
						|
			content:     "",
 | 
						|
			wantCode:    http.StatusOK,
 | 
						|
			wantBody:    "An error occurred",
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
 | 
						|
			form := url.Values{}
 | 
						|
			form.Add("authorname", tt.authorName)
 | 
						|
			form.Add("authoremail", tt.authorEmail)
 | 
						|
			form.Add("authorsite", tt.authorSite)
 | 
						|
			form.Add("content", tt.content)
 | 
						|
			r, err := http.NewRequest("POST", ts.URL, strings.NewReader(form.Encode()))
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
			r.URL.Path = fmt.Sprintf("/websites/%s/guestbook/comments/create/remote", shortIdToSlug(1))
 | 
						|
			r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
						|
			r.Header.Set("Origin", "http://example.com")
 | 
						|
 | 
						|
			resp, err := ts.Client().Do(r)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
 | 
						|
			defer resp.Body.Close()
 | 
						|
			body, err := io.ReadAll(resp.Body)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
			body = bytes.TrimSpace(body)
 | 
						|
			assert.Equal(t, resp.StatusCode, tt.wantCode)
 | 
						|
			assert.StringContains(t, string(body), tt.wantBody)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |