package main import ( "bytes" "encoding/json" "fmt" "github.com/stretchr/testify/assert" "go-nkode/core" "go-nkode/util" "io" "net/http" "strings" "testing" ) func TestApi(t *testing.T) { base := "http://localhost:8080" newCustomerBody := core.NewCustomerPost{ NKodePolicy: core.NewDefaultNKodePolicy(), } kp := core.KeypadDimension{ AttrsPerKey: 14, NumbOfKeys: 10, } var customerResp core.CreateNewCustomerResp testApiPost(t, base+core.CreateNewCustomer, newCustomerBody, &customerResp) userEmail := "test_username" + util.GenerateRandomString(12) + "@example.com" signupInterfaceBody := core.GenerateSignupRestInterfacePost{ CustomerId: customerResp.CustomerId, AttrsPerKey: kp.AttrsPerKey, NumbOfKeys: kp.NumbOfKeys, UserEmail: strings.ToUpper(userEmail), // should be case-insensitive Reset: false, } var signupInterfaceResp core.GenerateSignupResetInterfaceResp testApiPost(t, base+core.GenerateSignupResetInterface, signupInterfaceBody, &signupInterfaceResp) assert.Len(t, signupInterfaceResp.SvgInterface, kp.TotalAttrs()) passcodeLen := 4 setInterface := signupInterfaceResp.UserIdxInterface userPasscode := setInterface[:passcodeLen] kpSet := core.KeypadDimension{NumbOfKeys: kp.NumbOfKeys, AttrsPerKey: kp.NumbOfKeys} setKeySelection, err := core.SelectKeyByAttrIdx(setInterface, userPasscode, kpSet) assert.NoError(t, err) setNKodeBody := core.SetNKodePost{ CustomerId: customerResp.CustomerId, SessionId: signupInterfaceResp.SessionId, KeySelection: setKeySelection, } var setNKodeResp core.SetNKodeResp testApiPost(t, base+core.SetNKode, setNKodeBody, &setNKodeResp) confirmInterface := setNKodeResp.UserInterface confirmKeySelection, err := core.SelectKeyByAttrIdx(confirmInterface, userPasscode, kpSet) assert.NoError(t, err) confirmNKodeBody := core.ConfirmNKodePost{ CustomerId: customerResp.CustomerId, KeySelection: confirmKeySelection, SessionId: signupInterfaceResp.SessionId, } testApiPost(t, base+core.ConfirmNKode, confirmNKodeBody, nil) loginInterfaceBody := core.GetLoginInterfacePost{ CustomerId: customerResp.CustomerId, UserEmail: userEmail, } var loginInterfaceResp core.GetLoginInterfaceResp testApiPost(t, base+core.GetLoginInterface, loginInterfaceBody, &loginInterfaceResp) assert.Equal(t, loginInterfaceResp.AttrsPerKey, kp.AttrsPerKey) assert.Equal(t, loginInterfaceResp.NumbOfKeys, kp.NumbOfKeys) loginKeySelection, err := core.SelectKeyByAttrIdx(loginInterfaceResp.UserIdxInterface, userPasscode, kp) assert.NoError(t, err) loginBody := core.LoginPost{ CustomerId: customerResp.CustomerId, UserEmail: userEmail, KeySelection: loginKeySelection, } var jwtTokens core.AuthenticationTokens testApiPost(t, base+core.Login, loginBody, &jwtTokens) refreshClaims, err := core.ParseRegisteredClaimToken(jwtTokens.RefreshToken) assert.Equal(t, refreshClaims.Subject, userEmail) accessClaims, err := core.ParseRegisteredClaimToken(jwtTokens.AccessToken) assert.Equal(t, accessClaims.Subject, userEmail) renewBody := core.RenewAttributesPost{CustomerId: customerResp.CustomerId} testApiPost(t, base+core.RenewAttributes, renewBody, nil) loginKeySelection, err = core.SelectKeyByAttrIdx(loginInterfaceResp.UserIdxInterface, userPasscode, kp) assert.NoError(t, err) loginBody = core.LoginPost{ CustomerId: customerResp.CustomerId, UserEmail: userEmail, KeySelection: loginKeySelection, } testApiPost(t, base+core.Login, loginBody, &jwtTokens) var randomSvgInterfaceResp core.RandomSvgInterfaceResp testApiGet(t, base+core.RandomSvgInterface, &randomSvgInterfaceResp, "") assert.Equal(t, core.KeypadMax.TotalAttrs(), len(randomSvgInterfaceResp.Svgs)) var refreshTokenResp core.RefreshTokenResp testApiGet(t, base+core.RefreshToken, &refreshTokenResp, jwtTokens.RefreshToken) accessClaims, err = core.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) } }