2021-12-25 02:16:58 +01:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2022-06-19 21:56:10 +02:00
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
2021-12-25 02:16:58 +01:00
|
|
|
"fmt"
|
2022-06-19 21:56:10 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"strings"
|
2021-12-25 02:16:58 +01:00
|
|
|
"testing"
|
2022-06-22 17:17:09 +02:00
|
|
|
|
2022-07-12 04:10:19 +02:00
|
|
|
"lbryio/lbry-id/auth"
|
2022-08-01 17:50:16 +02:00
|
|
|
"lbryio/lbry-id/server/paths"
|
2022-07-12 04:10:19 +02:00
|
|
|
"lbryio/lbry-id/store"
|
|
|
|
"lbryio/lbry-id/wallet"
|
2021-12-25 02:16:58 +01:00
|
|
|
)
|
|
|
|
|
2022-08-01 17:50:16 +02:00
|
|
|
const TestPort = 8090
|
|
|
|
|
2021-12-25 02:16:58 +01:00
|
|
|
// Implementing interfaces for stubbed out packages
|
|
|
|
|
2022-07-28 01:45:09 +02:00
|
|
|
type SendVerificationEmailCall struct {
|
|
|
|
Email auth.Email
|
|
|
|
Token auth.VerifyTokenString
|
|
|
|
}
|
|
|
|
|
|
|
|
type TestMail struct {
|
|
|
|
SendVerificationEmailError error
|
|
|
|
SendVerificationEmailCall *SendVerificationEmailCall
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *TestMail) SendVerificationEmail(email auth.Email, token auth.VerifyTokenString) error {
|
|
|
|
m.SendVerificationEmailCall = &SendVerificationEmailCall{email, token}
|
|
|
|
return m.SendVerificationEmailError
|
|
|
|
}
|
|
|
|
|
2022-07-24 00:13:56 +02:00
|
|
|
type TestEnv struct {
|
|
|
|
env map[string]string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *TestEnv) Getenv(key string) string {
|
|
|
|
return e.env[key]
|
|
|
|
}
|
|
|
|
|
2021-12-25 02:16:58 +01:00
|
|
|
type TestAuth struct {
|
2022-07-28 01:45:09 +02:00
|
|
|
TestNewAuthTokenString auth.AuthTokenString
|
|
|
|
TestNewVerifyTokenString auth.VerifyTokenString
|
|
|
|
FailGenToken bool
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-07-28 01:45:09 +02:00
|
|
|
func (a *TestAuth) NewAuthToken(userId auth.UserId, deviceId auth.DeviceId, scope auth.AuthScope) (*auth.AuthToken, error) {
|
2021-12-25 02:16:58 +01:00
|
|
|
if a.FailGenToken {
|
|
|
|
return nil, fmt.Errorf("Test error: fail to generate token")
|
|
|
|
}
|
2022-07-28 01:45:09 +02:00
|
|
|
return &auth.AuthToken{Token: a.TestNewAuthTokenString, UserId: userId, DeviceId: deviceId, Scope: scope}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *TestAuth) NewVerifyTokenString() (auth.VerifyTokenString, error) {
|
|
|
|
if a.FailGenToken {
|
|
|
|
return "", fmt.Errorf("Test error: fail to generate token")
|
|
|
|
}
|
|
|
|
return a.TestNewVerifyTokenString, nil
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-06-21 22:59:20 +02:00
|
|
|
type SetWalletCall struct {
|
|
|
|
EncryptedWallet wallet.EncryptedWallet
|
|
|
|
Sequence wallet.Sequence
|
|
|
|
Hmac wallet.WalletHmac
|
|
|
|
}
|
|
|
|
|
2022-07-06 20:02:34 +02:00
|
|
|
type ChangePasswordNoWalletCall struct {
|
2022-07-15 21:36:11 +02:00
|
|
|
Email auth.Email
|
|
|
|
OldPassword auth.Password
|
|
|
|
NewPassword auth.Password
|
|
|
|
ClientSaltSeed auth.ClientSaltSeed
|
2022-07-06 20:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type ChangePasswordWithWalletCall struct {
|
|
|
|
EncryptedWallet wallet.EncryptedWallet
|
|
|
|
Sequence wallet.Sequence
|
|
|
|
Hmac wallet.WalletHmac
|
|
|
|
Email auth.Email
|
|
|
|
OldPassword auth.Password
|
|
|
|
NewPassword auth.Password
|
2022-07-15 21:36:11 +02:00
|
|
|
ClientSaltSeed auth.ClientSaltSeed
|
2022-07-06 20:02:34 +02:00
|
|
|
}
|
|
|
|
|
2022-07-26 16:16:44 +02:00
|
|
|
type CreateAccountCall struct {
|
|
|
|
Email auth.Email
|
|
|
|
Password auth.Password
|
|
|
|
ClientSaltSeed auth.ClientSaltSeed
|
2022-08-14 04:15:19 +02:00
|
|
|
VerifyToken *auth.VerifyTokenString
|
2022-07-26 16:16:44 +02:00
|
|
|
}
|
|
|
|
|
2022-06-21 00:10:54 +02:00
|
|
|
// Whether functions are called, and sometimes what they're called with
|
2022-06-19 22:40:16 +02:00
|
|
|
type TestStoreFunctionsCalled struct {
|
2022-07-28 01:45:09 +02:00
|
|
|
SaveToken auth.AuthTokenString
|
|
|
|
GetToken auth.AuthTokenString
|
2022-07-06 20:02:34 +02:00
|
|
|
GetUserId bool
|
2022-07-26 16:16:44 +02:00
|
|
|
CreateAccount *CreateAccountCall
|
2022-07-30 02:49:00 +02:00
|
|
|
UpdateVerifyTokenString bool
|
2022-07-26 22:36:57 +02:00
|
|
|
VerifyAccount bool
|
2022-07-06 20:02:34 +02:00
|
|
|
SetWallet SetWalletCall
|
|
|
|
GetWallet bool
|
|
|
|
ChangePasswordWithWallet ChangePasswordWithWalletCall
|
|
|
|
ChangePasswordNoWallet ChangePasswordNoWalletCall
|
2022-07-15 21:36:11 +02:00
|
|
|
GetClientSaltSeed auth.Email
|
2022-06-17 18:52:17 +02:00
|
|
|
}
|
|
|
|
|
2022-06-19 22:40:16 +02:00
|
|
|
type TestStoreFunctionsErrors struct {
|
2022-07-06 20:02:34 +02:00
|
|
|
SaveToken error
|
|
|
|
GetToken error
|
|
|
|
GetUserId error
|
|
|
|
CreateAccount error
|
2022-07-30 02:49:00 +02:00
|
|
|
UpdateVerifyTokenString error
|
2022-07-26 22:36:57 +02:00
|
|
|
VerifyAccount error
|
2022-07-06 20:02:34 +02:00
|
|
|
SetWallet error
|
|
|
|
GetWallet error
|
|
|
|
ChangePasswordWithWallet error
|
|
|
|
ChangePasswordNoWallet error
|
2022-07-15 21:36:11 +02:00
|
|
|
GetClientSaltSeed error
|
2022-06-19 22:40:16 +02:00
|
|
|
}
|
|
|
|
|
2021-12-25 02:16:58 +01:00
|
|
|
type TestStore struct {
|
2022-06-17 18:52:17 +02:00
|
|
|
// Fake store functions will set these to `true` as they are called
|
2022-06-19 22:40:16 +02:00
|
|
|
Called TestStoreFunctionsCalled
|
2021-12-25 02:16:58 +01:00
|
|
|
|
2022-06-19 22:40:16 +02:00
|
|
|
// Fake store functions will return the errors (including `nil`) specified in
|
|
|
|
// the test setup
|
|
|
|
Errors TestStoreFunctionsErrors
|
2022-06-20 00:54:59 +02:00
|
|
|
|
2022-07-28 01:45:09 +02:00
|
|
|
TestAuthToken auth.AuthToken
|
2022-06-20 00:54:59 +02:00
|
|
|
|
|
|
|
TestEncryptedWallet wallet.EncryptedWallet
|
|
|
|
TestSequence wallet.Sequence
|
|
|
|
TestHmac wallet.WalletHmac
|
2022-07-15 21:36:11 +02:00
|
|
|
|
|
|
|
TestClientSaltSeed auth.ClientSaltSeed
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-06-21 00:10:54 +02:00
|
|
|
func (s *TestStore) SaveToken(authToken *auth.AuthToken) error {
|
|
|
|
s.Called.SaveToken = authToken.Token
|
2022-06-19 22:40:16 +02:00
|
|
|
return s.Errors.SaveToken
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-07-28 01:45:09 +02:00
|
|
|
func (s *TestStore) GetToken(token auth.AuthTokenString) (*auth.AuthToken, error) {
|
2022-06-21 00:10:54 +02:00
|
|
|
s.Called.GetToken = token
|
2022-06-20 00:54:59 +02:00
|
|
|
return &s.TestAuthToken, s.Errors.GetToken
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-06-07 19:25:14 +02:00
|
|
|
func (s *TestStore) GetUserId(auth.Email, auth.Password) (auth.UserId, error) {
|
2022-06-17 18:52:17 +02:00
|
|
|
s.Called.GetUserId = true
|
2022-06-19 22:40:16 +02:00
|
|
|
return 0, s.Errors.GetUserId
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-08-14 04:15:19 +02:00
|
|
|
func (s *TestStore) CreateAccount(email auth.Email, password auth.Password, seed auth.ClientSaltSeed, verifyToken *auth.VerifyTokenString) error {
|
2022-07-26 16:16:44 +02:00
|
|
|
s.Called.CreateAccount = &CreateAccountCall{
|
|
|
|
Email: email,
|
|
|
|
Password: password,
|
2022-07-28 01:45:09 +02:00
|
|
|
ClientSaltSeed: seed,
|
|
|
|
VerifyToken: verifyToken,
|
2022-07-26 16:16:44 +02:00
|
|
|
}
|
2022-06-19 22:40:16 +02:00
|
|
|
return s.Errors.CreateAccount
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-07-30 02:49:00 +02:00
|
|
|
func (s *TestStore) UpdateVerifyTokenString(auth.Email, auth.VerifyTokenString) (err error) {
|
|
|
|
s.Called.UpdateVerifyTokenString = true
|
|
|
|
return s.Errors.UpdateVerifyTokenString
|
|
|
|
}
|
|
|
|
|
2022-07-26 22:36:57 +02:00
|
|
|
func (s *TestStore) VerifyAccount(auth.VerifyTokenString) (err error) {
|
|
|
|
s.Called.VerifyAccount = true
|
|
|
|
return s.Errors.VerifyAccount
|
|
|
|
}
|
|
|
|
|
2022-06-09 23:04:49 +02:00
|
|
|
func (s *TestStore) SetWallet(
|
2022-06-07 19:25:14 +02:00
|
|
|
UserId auth.UserId,
|
2022-06-09 23:04:49 +02:00
|
|
|
encryptedWallet wallet.EncryptedWallet,
|
|
|
|
sequence wallet.Sequence,
|
|
|
|
hmac wallet.WalletHmac,
|
2022-06-23 21:22:31 +02:00
|
|
|
) (err error) {
|
2022-06-21 22:59:20 +02:00
|
|
|
s.Called.SetWallet = SetWalletCall{encryptedWallet, sequence, hmac}
|
2022-06-23 21:22:31 +02:00
|
|
|
return s.Errors.SetWallet
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-06-09 23:04:49 +02:00
|
|
|
func (s *TestStore) GetWallet(userId auth.UserId) (encryptedWallet wallet.EncryptedWallet, sequence wallet.Sequence, hmac wallet.WalletHmac, err error) {
|
2022-06-17 18:52:17 +02:00
|
|
|
s.Called.GetWallet = true
|
2022-06-19 22:40:16 +02:00
|
|
|
err = s.Errors.GetWallet
|
2022-06-20 00:54:59 +02:00
|
|
|
if err == nil {
|
|
|
|
encryptedWallet = s.TestEncryptedWallet
|
|
|
|
sequence = s.TestSequence
|
|
|
|
hmac = s.TestHmac
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-07-06 20:02:34 +02:00
|
|
|
func (s *TestStore) ChangePasswordWithWallet(
|
|
|
|
email auth.Email,
|
|
|
|
oldPassword auth.Password,
|
|
|
|
newPassword auth.Password,
|
2022-07-15 21:36:11 +02:00
|
|
|
clientSaltSeed auth.ClientSaltSeed,
|
2022-07-06 20:02:34 +02:00
|
|
|
encryptedWallet wallet.EncryptedWallet,
|
|
|
|
sequence wallet.Sequence,
|
|
|
|
hmac wallet.WalletHmac,
|
|
|
|
) (err error) {
|
|
|
|
s.Called.ChangePasswordWithWallet = ChangePasswordWithWalletCall{
|
|
|
|
EncryptedWallet: encryptedWallet,
|
|
|
|
Sequence: sequence,
|
|
|
|
Hmac: hmac,
|
|
|
|
Email: email,
|
|
|
|
OldPassword: oldPassword,
|
|
|
|
NewPassword: newPassword,
|
2022-07-15 21:36:11 +02:00
|
|
|
ClientSaltSeed: clientSaltSeed,
|
2022-07-06 20:02:34 +02:00
|
|
|
}
|
|
|
|
return s.Errors.ChangePasswordWithWallet
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *TestStore) ChangePasswordNoWallet(
|
|
|
|
email auth.Email,
|
|
|
|
oldPassword auth.Password,
|
|
|
|
newPassword auth.Password,
|
2022-07-15 21:36:11 +02:00
|
|
|
clientSaltSeed auth.ClientSaltSeed,
|
2022-07-06 20:02:34 +02:00
|
|
|
) (err error) {
|
|
|
|
s.Called.ChangePasswordNoWallet = ChangePasswordNoWalletCall{
|
2022-07-15 21:36:11 +02:00
|
|
|
Email: email,
|
|
|
|
OldPassword: oldPassword,
|
|
|
|
NewPassword: newPassword,
|
|
|
|
ClientSaltSeed: clientSaltSeed,
|
2022-07-06 20:02:34 +02:00
|
|
|
}
|
|
|
|
return s.Errors.ChangePasswordNoWallet
|
|
|
|
}
|
|
|
|
|
2022-07-15 21:36:11 +02:00
|
|
|
func (s *TestStore) GetClientSaltSeed(email auth.Email) (seed auth.ClientSaltSeed, err error) {
|
|
|
|
s.Called.GetClientSaltSeed = email
|
|
|
|
err = s.Errors.GetClientSaltSeed
|
|
|
|
if err == nil {
|
|
|
|
seed = s.TestClientSaltSeed
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-06-21 17:52:03 +02:00
|
|
|
// expectStatusCode: A helper to call in functions that test that request
|
|
|
|
// handlers responded with a certain status code. Cuts down on noise.
|
|
|
|
func expectStatusCode(t *testing.T, w *httptest.ResponseRecorder, expectedStatusCode int) {
|
2022-06-19 22:57:37 +02:00
|
|
|
if want, got := expectedStatusCode, w.Result().StatusCode; want != got {
|
2022-06-21 17:52:03 +02:00
|
|
|
t.Errorf("StatusCode: expected %s (%d), got %s (%d)", http.StatusText(want), want, http.StatusText(got), got)
|
2022-06-19 22:57:37 +02:00
|
|
|
}
|
2022-06-21 17:52:03 +02:00
|
|
|
}
|
2022-06-19 22:57:37 +02:00
|
|
|
|
2022-06-21 17:52:03 +02:00
|
|
|
// expectErrorString: A helper to call in functions that test that request
|
|
|
|
// handlers failed with a certain error string. Cuts down on noise.
|
2022-06-22 17:37:03 +02:00
|
|
|
func expectErrorString(t *testing.T, body []byte, expectedErrorString string) {
|
|
|
|
if len(body) == 0 {
|
|
|
|
// Nothing to decode
|
|
|
|
if expectedErrorString == "" {
|
|
|
|
return // Nothing expected either, we're all good
|
|
|
|
}
|
|
|
|
t.Errorf("Error String: expected %s, got an empty body (no JSON to decode)", expectedErrorString)
|
|
|
|
}
|
2022-06-19 22:57:37 +02:00
|
|
|
|
|
|
|
var result ErrorResponse
|
|
|
|
if err := json.Unmarshal(body, &result); err != nil {
|
2022-06-21 17:52:03 +02:00
|
|
|
t.Fatalf("Error decoding error message: %s: `%s`", err, body)
|
2022-06-19 22:57:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if want, got := expectedErrorString, result.Error; want != got {
|
|
|
|
t.Errorf("Error String: expected %s, got %s", want, got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-22 17:17:09 +02:00
|
|
|
func TestServerHelperCheckAuth(t *testing.T) {
|
|
|
|
tt := []struct {
|
|
|
|
name string
|
|
|
|
requiredScope auth.AuthScope
|
|
|
|
userScope auth.AuthScope
|
|
|
|
|
|
|
|
tokenExpected bool
|
|
|
|
expectedStatusCode int
|
|
|
|
expectedErrorString string
|
|
|
|
|
|
|
|
storeErrors TestStoreFunctionsErrors
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "success",
|
|
|
|
// Just check that scope checks exist. The more detailed specific tests
|
|
|
|
// go in the auth module
|
|
|
|
requiredScope: auth.AuthScope("banana"),
|
|
|
|
userScope: auth.AuthScope("*"),
|
|
|
|
|
|
|
|
// not that it's a full request but as of now no error yet means 200 by default
|
|
|
|
expectedStatusCode: 200,
|
|
|
|
tokenExpected: true,
|
|
|
|
}, {
|
|
|
|
name: "auth token not found",
|
|
|
|
requiredScope: auth.AuthScope("banana"),
|
|
|
|
userScope: auth.AuthScope("*"),
|
|
|
|
|
|
|
|
expectedStatusCode: http.StatusUnauthorized,
|
|
|
|
expectedErrorString: http.StatusText(http.StatusUnauthorized) + ": Token Not Found",
|
|
|
|
|
2022-07-26 22:36:57 +02:00
|
|
|
storeErrors: TestStoreFunctionsErrors{GetToken: store.ErrNoTokenForUserDevice},
|
2022-06-22 17:17:09 +02:00
|
|
|
}, {
|
|
|
|
name: "unknown auth token db error",
|
|
|
|
requiredScope: auth.AuthScope("banana"),
|
|
|
|
userScope: auth.AuthScope("*"),
|
|
|
|
|
|
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
|
|
expectedErrorString: http.StatusText(http.StatusInternalServerError),
|
|
|
|
|
|
|
|
storeErrors: TestStoreFunctionsErrors{GetToken: fmt.Errorf("Some random DB Error!")},
|
|
|
|
}, {
|
|
|
|
name: "auth scope failure",
|
|
|
|
requiredScope: auth.AuthScope("banana"),
|
|
|
|
userScope: auth.AuthScope("carrot"),
|
|
|
|
|
|
|
|
expectedStatusCode: http.StatusForbidden,
|
|
|
|
expectedErrorString: http.StatusText(http.StatusForbidden) + ": Scope",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
testStore := TestStore{
|
|
|
|
Errors: tc.storeErrors,
|
2022-07-28 01:45:09 +02:00
|
|
|
TestAuthToken: auth.AuthToken{Token: auth.AuthTokenString("seekrit"), Scope: tc.userScope},
|
2022-06-22 17:17:09 +02:00
|
|
|
}
|
2022-08-01 17:50:16 +02:00
|
|
|
s := Server{&TestAuth{}, &testStore, &TestEnv{}, &TestMail{}, TestPort}
|
2022-06-22 17:17:09 +02:00
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
authToken := s.checkAuth(w, testStore.TestAuthToken.Token, tc.requiredScope)
|
|
|
|
if tc.tokenExpected && (*authToken != testStore.TestAuthToken) {
|
|
|
|
t.Errorf("Expected checkAuth to return a valid AuthToken")
|
|
|
|
}
|
|
|
|
if !tc.tokenExpected && (authToken != nil) {
|
|
|
|
t.Errorf("Expected checkAuth not to return a valid AuthToken")
|
|
|
|
}
|
2022-06-22 17:37:03 +02:00
|
|
|
body, _ := ioutil.ReadAll(w.Body)
|
|
|
|
|
2022-06-22 17:17:09 +02:00
|
|
|
expectStatusCode(t, w, tc.expectedStatusCode)
|
2022-06-22 17:37:03 +02:00
|
|
|
expectErrorString(t, body, tc.expectedErrorString)
|
2022-06-22 17:17:09 +02:00
|
|
|
})
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServerHelperGetGetDataSuccess(t *testing.T) {
|
2022-06-22 23:56:29 +02:00
|
|
|
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
success := getGetData(w, req)
|
|
|
|
if !success {
|
|
|
|
t.Errorf("getGetData failed unexpectedly")
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
func TestServerHelperGetGetDataErrors(t *testing.T) {
|
2022-06-23 21:22:31 +02:00
|
|
|
// Only error right now is if you do a POST request
|
2022-06-22 23:56:29 +02:00
|
|
|
req := httptest.NewRequest(http.MethodPost, "/test", nil)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
success := getGetData(w, req)
|
|
|
|
if success {
|
|
|
|
t.Errorf("getGetData succeeded unexpectedly")
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
|
|
|
|
2022-06-19 21:56:10 +02:00
|
|
|
type TestReqStruct struct{ key string }
|
|
|
|
|
2022-07-11 15:42:08 +02:00
|
|
|
func (t *TestReqStruct) validate() error {
|
|
|
|
if t.key == "" {
|
|
|
|
return fmt.Errorf("TestReq Error")
|
|
|
|
} else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2022-06-19 21:56:10 +02:00
|
|
|
|
2021-12-25 02:16:58 +01:00
|
|
|
func TestServerHelperGetPostDataSuccess(t *testing.T) {
|
2022-06-19 21:56:10 +02:00
|
|
|
requestBody := []byte(`{}`)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBuffer(requestBody))
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
success := getPostData(w, req, &TestReqStruct{key: "hi"})
|
|
|
|
if !success {
|
|
|
|
t.Errorf("getPostData failed unexpectedly")
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|
2022-06-19 21:56:10 +02:00
|
|
|
|
2022-06-19 23:51:40 +02:00
|
|
|
// Test getPostData, including requestOverhead and any other mini-helpers it calls.
|
2021-12-25 02:16:58 +01:00
|
|
|
func TestServerHelperGetPostDataErrors(t *testing.T) {
|
2022-06-19 21:56:10 +02:00
|
|
|
tt := []struct {
|
|
|
|
name string
|
|
|
|
method string
|
|
|
|
requestBody string
|
|
|
|
expectedStatusCode int
|
|
|
|
expectedErrorString string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "bad method",
|
|
|
|
method: http.MethodGet,
|
|
|
|
requestBody: "",
|
|
|
|
expectedStatusCode: http.StatusMethodNotAllowed,
|
|
|
|
expectedErrorString: http.StatusText(http.StatusMethodNotAllowed),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "request body too large",
|
|
|
|
method: http.MethodPost,
|
2022-06-19 23:49:05 +02:00
|
|
|
requestBody: fmt.Sprintf(`{"key": "%s"}`, strings.Repeat("a", 100000)),
|
2022-06-19 21:56:10 +02:00
|
|
|
expectedStatusCode: http.StatusRequestEntityTooLarge,
|
|
|
|
expectedErrorString: http.StatusText(http.StatusRequestEntityTooLarge),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "malformed request body JSON",
|
|
|
|
method: http.MethodPost,
|
|
|
|
requestBody: "{",
|
|
|
|
expectedStatusCode: http.StatusBadRequest,
|
2022-06-19 23:49:05 +02:00
|
|
|
expectedErrorString: http.StatusText(http.StatusBadRequest) + ": Error parsing JSON",
|
2022-06-19 21:56:10 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "body JSON failed validation",
|
|
|
|
method: http.MethodPost,
|
|
|
|
requestBody: "{}",
|
|
|
|
expectedStatusCode: http.StatusBadRequest,
|
2022-07-11 15:42:08 +02:00
|
|
|
expectedErrorString: http.StatusText(http.StatusBadRequest) + ": Request failed validation: TestReq Error",
|
2022-06-19 21:56:10 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
// Make request
|
2022-08-01 17:50:16 +02:00
|
|
|
req := httptest.NewRequest(tc.method, paths.PathAuthToken, bytes.NewBuffer([]byte(tc.requestBody)))
|
2022-06-19 21:56:10 +02:00
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
success := getPostData(w, req, &TestReqStruct{})
|
|
|
|
if success {
|
|
|
|
t.Errorf("getPostData succeeded unexpectedly")
|
|
|
|
}
|
2022-06-22 17:37:03 +02:00
|
|
|
body, _ := ioutil.ReadAll(w.Body)
|
2022-06-19 21:56:10 +02:00
|
|
|
|
2022-06-21 17:52:03 +02:00
|
|
|
expectStatusCode(t, w, tc.expectedStatusCode)
|
2022-06-22 17:37:03 +02:00
|
|
|
expectErrorString(t, body, tc.expectedErrorString)
|
2022-06-19 21:56:10 +02:00
|
|
|
})
|
|
|
|
}
|
2021-12-25 02:16:58 +01:00
|
|
|
}
|