Files
go-nkode/cmd/main_test.go
2025-01-21 01:19:27 -06:00

162 lines
5.4 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"go-nkode/internal/api"
"go-nkode/internal/models"
"go-nkode/pkg/nkode-core/entities"
security2 "go-nkode/pkg/nkode-core/security"
"io"
"net/http"
"strings"
"testing"
)
func TestApi(t *testing.T) {
base := "http://localhost:8080"
newCustomerBody := models.NewCustomerPost{
NKodePolicy: entities.NewDefaultNKodePolicy(),
}
kp := entities.KeypadDimension{
AttrsPerKey: 14,
NumbOfKeys: 10,
}
var customerResp models.CreateNewCustomerResp
testApiPost(t, base+api.CreateNewCustomer, newCustomerBody, &customerResp)
userEmail := "test_username" + security2.GenerateRandomString(12) + "@example.com"
signupInterfaceBody := models.GenerateSignupRestInterfacePost{
CustomerId: customerResp.CustomerId,
AttrsPerKey: kp.AttrsPerKey,
NumbOfKeys: kp.NumbOfKeys,
UserEmail: strings.ToUpper(userEmail), // should be case-insensitive
Reset: false,
}
var signupInterfaceResp entities.SignupResetInterface
testApiPost(t, base+api.GenerateSignupResetInterface, signupInterfaceBody, &signupInterfaceResp)
assert.Len(t, signupInterfaceResp.SvgInterface, kp.TotalAttrs())
passcodeLen := 4
setInterface := signupInterfaceResp.UserIdxInterface
userPasscode := setInterface[:passcodeLen]
kpSet := entities.KeypadDimension{NumbOfKeys: kp.NumbOfKeys, AttrsPerKey: kp.NumbOfKeys}
setKeySelection, err := entities.SelectKeyByAttrIdx(setInterface, userPasscode, kpSet)
assert.NoError(t, err)
setNKodeBody := models.SetNKodePost{
CustomerId: customerResp.CustomerId,
SessionId: signupInterfaceResp.SessionId,
KeySelection: setKeySelection,
}
var setNKodeResp models.SetNKodeResp
testApiPost(t, base+api.SetNKode, setNKodeBody, &setNKodeResp)
confirmInterface := setNKodeResp.UserInterface
confirmKeySelection, err := entities.SelectKeyByAttrIdx(confirmInterface, userPasscode, kpSet)
assert.NoError(t, err)
confirmNKodeBody := models.ConfirmNKodePost{
CustomerId: customerResp.CustomerId,
KeySelection: confirmKeySelection,
SessionId: signupInterfaceResp.SessionId,
}
testApiPost(t, base+api.ConfirmNKode, confirmNKodeBody, nil)
loginInterfaceBody := models.GetLoginInterfacePost{
CustomerId: customerResp.CustomerId,
UserEmail: userEmail,
}
var loginInterfaceResp entities.LoginInterface
testApiPost(t, base+api.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp)
assert.Equal(t, loginInterfaceResp.AttrsPerKey, kp.AttrsPerKey)
assert.Equal(t, loginInterfaceResp.NumbOfKeys, kp.NumbOfKeys)
loginKeySelection, err := entities.SelectKeyByAttrIdx(loginInterfaceResp.UserIdxInterface, userPasscode, kp)
assert.NoError(t, err)
loginBody := models.LoginPost{
CustomerId: customerResp.CustomerId,
UserEmail: userEmail,
KeySelection: loginKeySelection,
}
var jwtTokens security2.AuthenticationTokens
testApiPost(t, base+api.Login, loginBody, &jwtTokens)
refreshClaims, err := security2.ParseRegisteredClaimToken(jwtTokens.RefreshToken)
assert.Equal(t, refreshClaims.Subject, userEmail)
accessClaims, err := security2.ParseRegisteredClaimToken(jwtTokens.AccessToken)
assert.Equal(t, accessClaims.Subject, userEmail)
renewBody := models.RenewAttributesPost{CustomerId: customerResp.CustomerId}
testApiPost(t, base+api.RenewAttributes, renewBody, nil)
loginKeySelection, err = entities.SelectKeyByAttrIdx(loginInterfaceResp.UserIdxInterface, userPasscode, kp)
assert.NoError(t, err)
loginBody = models.LoginPost{
CustomerId: customerResp.CustomerId,
UserEmail: userEmail,
KeySelection: loginKeySelection,
}
testApiPost(t, base+api.Login, loginBody, &jwtTokens)
var randomSvgInterfaceResp models.RandomSvgInterfaceResp
testApiGet(t, base+api.RandomSvgInterface, &randomSvgInterfaceResp, "")
assert.Equal(t, entities.KeypadMax.TotalAttrs(), len(randomSvgInterfaceResp.Svgs))
var refreshTokenResp models.RefreshTokenResp
testApiGet(t, base+api.RefreshToken, &refreshTokenResp, jwtTokens.RefreshToken)
accessClaims, err = security2.ParseRegisteredClaimToken(refreshTokenResp.AccessToken)
assert.NoError(t, err)
assert.Equal(t, accessClaims.Subject, userEmail)
}
func Unmarshal(t *testing.T, resp *http.Response, data any) {
responseBody, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
err = json.Unmarshal(responseBody, data)
assert.NoError(t, err)
}
func Marshal(t *testing.T, data any) *bytes.Reader {
jsonBytes, err := json.Marshal(data)
assert.NoError(t, err)
reader := bytes.NewReader(jsonBytes)
return reader
}
func testApiPost(t *testing.T, endpointStr string, postBody any, respBody any) {
reader := Marshal(t, postBody)
resp, err := http.Post(endpointStr, "application/json", reader)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
if respBody != nil {
Unmarshal(t, resp, respBody)
}
}
func testApiGet(t *testing.T, endpointStr string, respBody any, bearerToken string) {
req, err := http.NewRequest("GET", endpointStr, nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
// Add the Bearer token to the Authorization header
if bearerToken != "" {
req.Header.Set("Authorization", "Bearer "+bearerToken)
}
// Make the HTTP request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
assert.NoError(t, err)
assert.Equal(t, resp.StatusCode, http.StatusOK)
if respBody != nil {
Unmarshal(t, resp, respBody)
}
}