I <3 TESTS

This commit is contained in:
grumbulon 2023-01-30 23:23:35 -05:00
parent 5e8ba819bc
commit 78671549c3
4 changed files with 192 additions and 5 deletions

View file

@ -109,7 +109,7 @@ func API() http.Handler {
api.Use(jwtauth.Authenticator)
api.With(setDBMiddleware).Post("/upload", ReceiveFile)
api.With(setDBMiddleware).Post("/parse", ZoneFiles)
api.With(setDBMiddleware).Post("/parse", ParseZoneFiles)
})
// Open routes

View file

@ -1,11 +1,16 @@
package api
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
"time"
@ -13,6 +18,7 @@ import (
"git.freecumextremist.com/grumbulon/pomme/internal"
"git.freecumextremist.com/grumbulon/pomme/internal/db"
"github.com/go-chi/chi/v5"
"github.com/go-chi/jwtauth/v5"
"github.com/stretchr/testify/assert"
"golang.org/x/crypto/bcrypt"
)
@ -26,9 +32,22 @@ type response struct {
type accountTest struct {
username string
password string
token string
url string
}
func makeTestToken(username string) (tokenString string, err error) {
claim := map[string]interface{}{"username": username, "admin": false}
jwtauth.SetExpiry(claim, time.Now().Add(time.Hour))
if _, tokenString, err = tokenAuth.Encode(claim); err == nil {
return
}
return "", fmt.Errorf("unable to generate JWT: %w", err)
}
func TestAPI(t *testing.T) {
config, err := internal.ReadConfig()
if err != nil {
@ -63,7 +82,7 @@ func TestAPI(t *testing.T) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(tester.password), bcrypt.DefaultCost)
if err != nil {
return
assert.NotNil(t, err)
}
db.Create(&internal.User{Username: tester.username, HashedPassword: string(hashedPassword)})
@ -71,14 +90,25 @@ func TestAPI(t *testing.T) {
tester.TestMakeAccount(t)
tester.TestLogin(t)
tester.TestLogout(t)
tester.TestUpload(t)
}
func Init(url string) accountTest {
return accountTest{
username: autoUname(),
user := autoUname()
token, err := makeTestToken(user)
if err != nil {
return accountTest{}
}
test := accountTest{
username: user,
password: "merde",
url: url,
token: token,
}
return test
}
func (a *accountTest) TestMakeAccount(t *testing.T) {
@ -172,3 +202,148 @@ func (a *accountTest) TestLogout(t *testing.T) {
assert.Equal(t, http.StatusOK, target.Status)
}
}
type expectedValues struct {
response int
}
func (a *accountTest) TestUpload(t *testing.T) {
testCases := []struct {
name string
file string
contentType string
fileContents []byte
expected expectedValues
}{
{
name: "Should fail to upload an empty file",
file: "badzonefile",
contentType: "audio/aac",
expected: expectedValues{
response: http.StatusInternalServerError,
},
},
{
name: "Should upload a valid file",
file: "zonefile",
contentType: "multipart/form-data",
fileContents: []byte{},
expected: expectedValues{
response: http.StatusCreated,
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var (
f *os.File
target response
err error
buf = new(bytes.Buffer)
w = multipart.NewWriter(buf)
)
switch tc.name {
case "Should fail to upload an empty file":
f, err = os.CreateTemp(".", tc.file)
if err != nil {
assert.NotNil(t, err)
}
default:
f, err = os.CreateTemp(".", "zonefile")
if err != nil {
assert.NotNil(t, err)
}
if err = os.WriteFile(f.Name(), zonebytes, 0o600); err != nil {
assert.NotNil(t, err)
}
}
defer os.Remove(f.Name()) //nolint: errcheck
client := http.Client{}
part, err := w.CreateFormFile("file", filepath.Base(f.Name()))
if err != nil {
assert.NotNil(t, err)
}
b, err := os.ReadFile(f.Name())
if err != nil {
assert.NotNil(t, err)
}
_, err = part.Write(b)
if err != nil {
assert.NotNil(t, err)
}
err = w.Close()
if err != nil {
assert.NotNil(t, err)
}
if req, err := http.NewRequest(http.MethodPost, a.url+`/api/upload`, buf); err == nil {
switch tc.name {
case "Should fail to upload an empty file":
req.Header.Add("Content-Type", tc.contentType)
default:
req.Header.Add("Content-Type", w.FormDataContentType())
}
req.Header.Add("Authorization", `Bearer:`+a.token)
req.Header.Add("User-Agent", "pomme-api-test-slave")
resp, err := client.Do(req)
if err != nil {
assert.NotNil(t, err)
}
respBody, _ := io.ReadAll(resp.Body)
err = json.Unmarshal(respBody, &target)
if err != nil {
assert.NotNil(t, err)
}
assert.Equal(t, tc.expected.response, target.Status)
}
if tc.name == "Should upload a valid file" {
parse(t, f.Name(), a)
}
})
}
}
func parse(t *testing.T, fname string, a *accountTest) {
var target response
client := http.Client{}
form := url.Values{}
form.Add("filename", filepath.Clean(fname))
if req, err := http.NewRequest(http.MethodPost, a.url+`/api/parse`, strings.NewReader(form.Encode())); err == nil {
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Authorization", `Bearer:`+a.token)
req.Header.Add("User-Agent", "pomme-api-test-slave")
resp, err := client.Do(req)
if err != nil {
assert.NotNil(t, err)
}
respBody, _ := io.ReadAll(resp.Body)
err = json.Unmarshal(respBody, &target)
if err != nil {
assert.NotNil(t, err)
}
assert.Equal(t, http.StatusOK, target.Status)
}
}

File diff suppressed because one or more lines are too long

View file

@ -13,6 +13,7 @@ import (
"git.freecumextremist.com/grumbulon/pomme/internal"
"git.freecumextremist.com/grumbulon/pomme/internal/util"
"github.com/go-chi/jwtauth/v5"
"github.com/go-chi/render"
"github.com/miekg/dns"
"gorm.io/gorm"
)
@ -140,7 +141,7 @@ func ReceiveFile(w http.ResponseWriter, r *http.Request) {
// @Security Bearer
//
// @Router /api/parse [post]
func ZoneFiles(w http.ResponseWriter, r *http.Request) {
func ParseZoneFiles(w http.ResponseWriter, r *http.Request) {
var result internal.ZoneRequest
_, claims, _ := jwtauth.FromContext(r.Context())
@ -187,6 +188,12 @@ func ZoneFiles(w http.ResponseWriter, r *http.Request) {
return
}
resp := internal.Response{
Message: "Successfully parsed zonefile",
HTTPResponse: http.StatusOK,
}
render.JSON(w, r, resp)
}
func newZoneRequest(filename string, user string) *ZoneRequest {