From c38f79490b4aabb29594f35521c3190ee5a4310a Mon Sep 17 00:00:00 2001 From: Aaron L Date: Mon, 14 May 2018 14:27:33 -0700 Subject: [PATCH] Increase testing coverage. - Missed some actual tests, added them. - Added a bunch of useless tests to increase coverage. Guilty as charged. --- client_state.go | 2 +- client_state_test.go | 37 ++++++++++++++ defaults/defaults_test.go | 39 +++++++++++++++ defaults/values_test.go | 100 +++++++++++++++++++++++++++++++++++++- internal/mocks/mocks.go | 72 +++++++++++++-------------- logout/logout_test.go | 32 ++++++++++++ mocks_test.go | 86 ++++++++++++++++++++++++++------ response_test.go | 43 ++++++++++++++++ storage_test.go | 64 ++++++++++++++++++++++++ user_test.go | 58 ++++++++++++++++++++++ values_test.go | 70 ++++++++++++++++++++++++++ 11 files changed, 550 insertions(+), 53 deletions(-) create mode 100644 defaults/defaults_test.go create mode 100644 response_test.go create mode 100644 storage_test.go create mode 100644 values_test.go diff --git a/client_state.go b/client_state.go index f3c4a4d..4644fa5 100644 --- a/client_state.go +++ b/client_state.go @@ -225,8 +225,8 @@ func (c *ClientStateResponseWriter) putClientState() error { // logging a user out. func DelKnownSession(w http.ResponseWriter) { DelSession(w, SessionKey) - DelSession(w, SessionLastAction) DelSession(w, SessionHalfAuthKey) + DelSession(w, SessionLastAction) } // DelKnownCookie deletes all known cookie variables, which can be used diff --git a/client_state_test.go b/client_state_test.go index a8735ac..a876b8c 100644 --- a/client_state_test.go +++ b/client_state_test.go @@ -159,3 +159,40 @@ func TestFlashClearer(t *testing.T) { t.Error("event was wrong", got) } } + +func TestDelKnown(t *testing.T) { + t.Parallel() + + csrw := &ClientStateResponseWriter{} + + DelKnownSession(csrw) + DelKnownCookie(csrw) + + mustBeDel := func(ev ClientStateEvent) { + t.Helper() + if ev.Kind != ClientStateEventDel { + t.Error("events should all be deletes") + } + } + + if len(csrw.sessionStateEvents) != 3 { + t.Error("should have deleted 3 session entries") + } + mustBeDel(csrw.sessionStateEvents[0]) + mustBeDel(csrw.sessionStateEvents[1]) + mustBeDel(csrw.sessionStateEvents[2]) + + for i, key := range []string{SessionKey, SessionHalfAuthKey, SessionLastAction} { + if sessionKey := csrw.sessionStateEvents[i].Key; key != sessionKey { + t.Errorf("%d) key was wrong, want: %s, got: %s", i, key, sessionKey) + } + } + + if len(csrw.cookieStateEvents) != 1 { + t.Error("should have deleted 1 cookie") + } + mustBeDel(csrw.cookieStateEvents[0]) + if key := csrw.cookieStateEvents[0].Key; key != CookieRemember { + t.Error("cookie key was wrong:", key) + } +} diff --git a/defaults/defaults_test.go b/defaults/defaults_test.go new file mode 100644 index 0000000..422109f --- /dev/null +++ b/defaults/defaults_test.go @@ -0,0 +1,39 @@ +package defaults + +import ( + "testing" + + "github.com/volatiletech/authboss" +) + +func TestSetCore(t *testing.T) { + t.Parallel() + + config := &authboss.Config{} + SetCore(config, false, false) + + if config.Core.Logger == nil { + t.Error("logger should be set") + } + if config.Core.Router == nil { + t.Error("router should be set") + } + if config.Core.ErrorHandler == nil { + t.Error("error handler should be set") + } + if config.Core.Responder == nil { + t.Error("responder should be set") + } + if config.Core.Redirector == nil { + t.Error("redirector should be set") + } + if config.Core.BodyReader == nil { + t.Error("bodyreader should be set") + } + if config.Core.Mailer == nil { + t.Error("mailer should be set") + } + if config.Core.Logger == nil { + t.Error("logger should be set") + } +} diff --git a/defaults/values_test.go b/defaults/values_test.go index 77fc3b1..c39bb7a 100644 --- a/defaults/values_test.go +++ b/defaults/values_test.go @@ -9,7 +9,7 @@ import ( "github.com/volatiletech/authboss/internal/mocks" ) -func TestHTTPBodyReader(t *testing.T) { +func TestHTTPBodyReaderLogin(t *testing.T) { t.Parallel() h := NewHTTPBodyReader(false, false) @@ -48,3 +48,101 @@ func TestHTTPBodyReaderJSON(t *testing.T) { t.Error("wrong password:", uv.GetPassword()) } } + +func TestHTTPBodyReaderConfirm(t *testing.T) { + t.Parallel() + + h := NewHTTPBodyReader(false, false) + r := mocks.Request("POST", FormValueConfirm, "token") + + validator, err := h.Read("confirm", r) + if err != nil { + t.Error(err) + } + + cv := validator.(authboss.ConfirmValuer) + if "token" != cv.GetToken() { + t.Error("token was wrong:", cv.GetToken()) + } +} + +func TestHTTPBodyReaderRecoverStart(t *testing.T) { + t.Parallel() + + h := NewHTTPBodyReader(false, false) + r := mocks.Request("POST", FormValueEmail, "email") + + validator, err := h.Read("recover_start", r) + if err != nil { + t.Error(err) + } + + rsv := validator.(authboss.RecoverStartValuer) + if pid := rsv.GetPID(); pid != "email" { + t.Error("token was wrong:", pid) + } +} + +func TestHTTPBodyReaderRecoverMiddle(t *testing.T) { + t.Parallel() + + h := NewHTTPBodyReader(false, false) + r := httptest.NewRequest("GET", "/?token=token", nil) + + validator, err := h.Read("recover_middle", r) + if err != nil { + t.Error(err) + } + + rmv := validator.(authboss.RecoverMiddleValuer) + if token := rmv.GetToken(); token != "token" { + t.Error("token was wrong:", token) + } +} + +func TestHTTPBodyReaderRecoverEnd(t *testing.T) { + t.Parallel() + + h := NewHTTPBodyReader(false, false) + r := mocks.Request("POST", "token", "token", "password", "password") + + validator, err := h.Read("recover_end", r) + if err != nil { + t.Error(err) + } + + rmv := validator.(authboss.RecoverEndValuer) + if token := rmv.GetToken(); token != "token" { + t.Error("token was wrong:", token) + } + if password := rmv.GetPassword(); password != "password" { + t.Error("password was wrong:", password) + } +} + +func TestHTTPBodyReaderRegister(t *testing.T) { + t.Parallel() + + h := NewHTTPBodyReader(false, false) + h.Whitelist["register"] = []string{"address"} + r := mocks.Request("POST", "email", "a@a.com", "password", "1234", "address", "555 go street") + + validator, err := h.Read("register", r) + if err != nil { + t.Error(err) + } + + rv := validator.(authboss.UserValuer) + if pid := rv.GetPID(); pid != "a@a.com" { + t.Error("pid was wrong:", pid) + } + if password := rv.GetPassword(); password != "1234" { + t.Error("password was wrong:", password) + } + + arb := validator.(authboss.ArbitraryValuer) + values := arb.GetValues() + if address := values["address"]; address != "555 go street" { + t.Error("address was wrong:", address) + } +} diff --git a/internal/mocks/mocks.go b/internal/mocks/mocks.go index 28028fc..3e756d5 100644 --- a/internal/mocks/mocks.go +++ b/internal/mocks/mocks.go @@ -36,111 +36,111 @@ type User struct { } // GetPID from user -func (m User) GetPID() string { return m.Email } +func (u User) GetPID() string { return u.Email } // GetEmail from user -func (m User) GetEmail() string { return m.Email } +func (u User) GetEmail() string { return u.Email } // GetUsername from user -func (m User) GetUsername() string { return m.Username } +func (u User) GetUsername() string { return u.Username } // GetPassword from user -func (m User) GetPassword() string { return m.Password } +func (u User) GetPassword() string { return u.Password } // GetRecoverToken from user -func (m User) GetRecoverToken() string { return m.RecoverToken } +func (u User) GetRecoverToken() string { return u.RecoverToken } // GetRecoverExpiry from user -func (m User) GetRecoverExpiry() time.Time { return m.RecoverTokenExpiry } +func (u User) GetRecoverExpiry() time.Time { return u.RecoverTokenExpiry } // GetConfirmToken from user -func (m User) GetConfirmToken() string { return m.ConfirmToken } +func (u User) GetConfirmToken() string { return u.ConfirmToken } // GetConfirmed from user -func (m User) GetConfirmed() bool { return m.Confirmed } +func (u User) GetConfirmed() bool { return u.Confirmed } // GetAttemptCount from user -func (m User) GetAttemptCount() int { return m.AttemptCount } +func (u User) GetAttemptCount() int { return u.AttemptCount } // GetLastAttempt from user -func (m User) GetLastAttempt() time.Time { return m.LastAttempt } +func (u User) GetLastAttempt() time.Time { return u.LastAttempt } // GetLocked from user -func (m User) GetLocked() time.Time { return m.Locked } +func (u User) GetLocked() time.Time { return u.Locked } // IsOAuth2User returns true if the user is an oauth2 user -func (m User) IsOAuth2User() bool { return len(m.OAuth2Provider) != 0 } +func (u User) IsOAuth2User() bool { return len(u.OAuth2Provider) != 0 } // GetOAuth2UID from user -func (m User) GetOAuth2UID() string { return m.OAuth2UID } +func (u User) GetOAuth2UID() string { return u.OAuth2UID } // GetOAuth2Provider from user -func (m User) GetOAuth2Provider() string { return m.OAuth2Provider } +func (u User) GetOAuth2Provider() string { return u.OAuth2Provider } // GetOAuth2AccessToken from user -func (m User) GetOAuth2AccessToken() string { return m.OAuth2Token } +func (u User) GetOAuth2AccessToken() string { return u.OAuth2Token } // GetOAuth2RefreshToken from user -func (m User) GetOAuth2RefreshToken() string { return m.OAuth2Refresh } +func (u User) GetOAuth2RefreshToken() string { return u.OAuth2Refresh } // GetOAuth2Expiry from user -func (m User) GetOAuth2Expiry() time.Time { return m.OAuth2Expiry } +func (u User) GetOAuth2Expiry() time.Time { return u.OAuth2Expiry } // GetArbitrary from user -func (m User) GetArbitrary() map[string]string { return m.Arbitrary } +func (u User) GetArbitrary() map[string]string { return u.Arbitrary } // PutPID into user -func (m *User) PutPID(email string) { m.Email = email } +func (u *User) PutPID(email string) { u.Email = email } // PutUsername into user -func (m *User) PutUsername(username string) { m.Username = username } +func (u *User) PutUsername(username string) { u.Username = username } // PutEmail into user -func (m *User) PutEmail(email string) { m.Email = email } +func (u *User) PutEmail(email string) { u.Email = email } // PutPassword into user -func (m *User) PutPassword(password string) { m.Password = password } +func (u *User) PutPassword(password string) { u.Password = password } // PutRecoverToken into user -func (m *User) PutRecoverToken(recoverToken string) { m.RecoverToken = recoverToken } +func (u *User) PutRecoverToken(recoverToken string) { u.RecoverToken = recoverToken } // PutRecoverExpiry into user -func (m *User) PutRecoverExpiry(recoverTokenExpiry time.Time) { - m.RecoverTokenExpiry = recoverTokenExpiry +func (u *User) PutRecoverExpiry(recoverTokenExpiry time.Time) { + u.RecoverTokenExpiry = recoverTokenExpiry } // PutConfirmToken into user -func (m *User) PutConfirmToken(confirmToken string) { m.ConfirmToken = confirmToken } +func (u *User) PutConfirmToken(confirmToken string) { u.ConfirmToken = confirmToken } // PutConfirmed into user -func (m *User) PutConfirmed(confirmed bool) { m.Confirmed = confirmed } +func (u *User) PutConfirmed(confirmed bool) { u.Confirmed = confirmed } // PutAttemptCount into user -func (m *User) PutAttemptCount(attemptCount int) { m.AttemptCount = attemptCount } +func (u *User) PutAttemptCount(attemptCount int) { u.AttemptCount = attemptCount } // PutLastAttempt into user -func (m *User) PutLastAttempt(attemptTime time.Time) { m.LastAttempt = attemptTime } +func (u *User) PutLastAttempt(attemptTime time.Time) { u.LastAttempt = attemptTime } // PutLocked into user -func (m *User) PutLocked(locked time.Time) { m.Locked = locked } +func (u *User) PutLocked(locked time.Time) { u.Locked = locked } // PutOAuth2UID into user -func (m *User) PutOAuth2UID(uid string) { m.OAuth2UID = uid } +func (u *User) PutOAuth2UID(uid string) { u.OAuth2UID = uid } // PutOAuth2Provider into user -func (m *User) PutOAuth2Provider(provider string) { m.OAuth2Provider = provider } +func (u *User) PutOAuth2Provider(provider string) { u.OAuth2Provider = provider } // PutOAuth2AccessToken into user -func (m *User) PutOAuth2AccessToken(token string) { m.OAuth2Token = token } +func (u *User) PutOAuth2AccessToken(token string) { u.OAuth2Token = token } // PutOAuth2RefreshToken into user -func (m *User) PutOAuth2RefreshToken(refresh string) { m.OAuth2Refresh = refresh } +func (u *User) PutOAuth2RefreshToken(refresh string) { u.OAuth2Refresh = refresh } // PutOAuth2Expiry into user -func (m *User) PutOAuth2Expiry(expiry time.Time) { m.OAuth2Expiry = expiry } +func (u *User) PutOAuth2Expiry(expiry time.Time) { u.OAuth2Expiry = expiry } // PutArbitrary into user -func (m *User) PutArbitrary(arb map[string]string) { m.Arbitrary = arb } +func (u *User) PutArbitrary(arb map[string]string) { u.Arbitrary = arb } // ServerStorer should be valid for any module storer defined in authboss. type ServerStorer struct { diff --git a/logout/logout_test.go b/logout/logout_test.go index dd093eb..0e7d993 100644 --- a/logout/logout_test.go +++ b/logout/logout_test.go @@ -31,6 +31,38 @@ func TestLogout(t *testing.T) { } } +func TestLogoutRoutes(t *testing.T) { + t.Parallel() + + ab := authboss.New() + router := &mocks.Router{} + errHandler := &mocks.ErrorHandler{} + ab.Config.Core.Router = router + ab.Config.Core.ErrorHandler = errHandler + + l := &Logout{} + ab.Config.Modules.LogoutMethod = "what" + if err := l.Init(ab); err == nil { + t.Error("should have failed to register the route") + } + + ab.Config.Modules.LogoutMethod = "GET" + if err := l.Init(ab); err != nil { + t.Error("should have failed to register the route") + } + if err := router.HasGets("/logout"); err != nil { + t.Error(err) + } + + ab.Config.Modules.LogoutMethod = "POST" + if err := l.Init(ab); err != nil { + t.Error("should have failed to register the route") + } + if err := router.HasPosts("/logout"); err != nil { + t.Error(err) + } +} + type testHarness struct { logout *Logout ab *authboss.Authboss diff --git a/mocks_test.go b/mocks_test.go index 42b850b..bd051d4 100644 --- a/mocks_test.go +++ b/mocks_test.go @@ -8,11 +8,31 @@ import ( "net/http" "net/url" "strings" + "time" ) type mockUser struct { Email string Password string + Username string + + RecoverToken string + RecoverTokenExpiry time.Time + + ConfirmToken string + Confirmed bool + + AttemptCount int + LastAttempt time.Time + Locked time.Time + + OAuth2UID string + OAuth2Provider string + OAuth2Token string + OAuth2Refresh string + OAuth2Expiry time.Time + + Arbitrary map[string]string } func newMockServerStorer() *mockServerStorer { @@ -70,21 +90,57 @@ func (m *mockServerStorer) UseRememberToken(pid, token string) error { return ErrTokenNotFound } -func (m *mockUser) PutPID(email string) { - m.Email = email +// This section of functions was purely for test coverage +func (m *mockServerStorer) New(ctx context.Context) User { panic("not impl") } +func (m *mockServerStorer) Create(ctx context.Context, user User) error { panic("not impl") } +func (m *mockServerStorer) NewFromOAuth2(ctx context.Context, provider string, details map[string]string) (OAuth2User, error) { + panic("not impl") } +func (m *mockServerStorer) LoadByConfirmToken(ctx context.Context, token string) (ConfirmableUser, error) { + panic("not impl") +} +func (m *mockServerStorer) LoadByRecoverToken(ctx context.Context, token string) (RecoverableUser, error) { + panic("not impl") +} +func (m *mockServerStorer) SaveOAuth2(ctx context.Context, user OAuth2User) error { panic("not impl") } -func (m *mockUser) PutPassword(password string) { - m.Password = password -} - -func (m *mockUser) GetPID() (email string) { - return m.Email -} - -func (m *mockUser) GetPassword() (password string) { - return m.Password +func (m mockUser) GetPID() string { return m.Email } +func (m mockUser) GetEmail() string { return m.Email } +func (m mockUser) GetUsername() string { return m.Username } +func (m mockUser) GetPassword() string { return m.Password } +func (m mockUser) GetRecoverToken() string { return m.RecoverToken } +func (m mockUser) GetRecoverExpiry() time.Time { return m.RecoverTokenExpiry } +func (m mockUser) GetConfirmToken() string { return m.ConfirmToken } +func (m mockUser) GetConfirmed() bool { return m.Confirmed } +func (m mockUser) GetAttemptCount() int { return m.AttemptCount } +func (m mockUser) GetLastAttempt() time.Time { return m.LastAttempt } +func (m mockUser) GetLocked() time.Time { return m.Locked } +func (m mockUser) IsOAuth2User() bool { return len(m.OAuth2Provider) != 0 } +func (m mockUser) GetOAuth2UID() string { return m.OAuth2UID } +func (m mockUser) GetOAuth2Provider() string { return m.OAuth2Provider } +func (m mockUser) GetOAuth2AccessToken() string { return m.OAuth2Token } +func (m mockUser) GetOAuth2RefreshToken() string { return m.OAuth2Refresh } +func (m mockUser) GetOAuth2Expiry() time.Time { return m.OAuth2Expiry } +func (m mockUser) GetArbitrary() map[string]string { return m.Arbitrary } +func (m *mockUser) PutPID(email string) { m.Email = email } +func (m *mockUser) PutUsername(username string) { m.Username = username } +func (m *mockUser) PutEmail(email string) { m.Email = email } +func (m *mockUser) PutPassword(password string) { m.Password = password } +func (m *mockUser) PutRecoverToken(recoverToken string) { m.RecoverToken = recoverToken } +func (m *mockUser) PutRecoverExpiry(recoverTokenExpiry time.Time) { + m.RecoverTokenExpiry = recoverTokenExpiry } +func (m *mockUser) PutConfirmToken(confirmToken string) { m.ConfirmToken = confirmToken } +func (m *mockUser) PutConfirmed(confirmed bool) { m.Confirmed = confirmed } +func (m *mockUser) PutAttemptCount(attemptCount int) { m.AttemptCount = attemptCount } +func (m *mockUser) PutLastAttempt(attemptTime time.Time) { m.LastAttempt = attemptTime } +func (m *mockUser) PutLocked(locked time.Time) { m.Locked = locked } +func (m *mockUser) PutOAuth2UID(uid string) { m.OAuth2UID = uid } +func (m *mockUser) PutOAuth2Provider(provider string) { m.OAuth2Provider = provider } +func (m *mockUser) PutOAuth2AccessToken(token string) { m.OAuth2Token = token } +func (m *mockUser) PutOAuth2RefreshToken(refresh string) { m.OAuth2Refresh = refresh } +func (m *mockUser) PutOAuth2Expiry(expiry time.Time) { m.OAuth2Expiry = expiry } +func (m *mockUser) PutArbitrary(arb map[string]string) { m.Arbitrary = arb } type mockClientStateReadWriter struct { state mockClientState @@ -178,9 +234,7 @@ type mockRenderer struct { expectName string } -func (m mockRenderer) Load(names ...string) error { - return nil -} +func (m mockRenderer) Load(names ...string) error { return nil } func (m mockRenderer) Render(ctx context.Context, name string, data HTMLData) ([]byte, string, error) { if len(m.expectName) != 0 && m.expectName != name { @@ -193,6 +247,8 @@ func (m mockRenderer) Render(ctx context.Context, name string, data HTMLData) ([ type mockEmailRenderer struct{} +func (m mockEmailRenderer) Load(names ...string) error { return nil } + func (m mockEmailRenderer) Render(ctx context.Context, name string, data HTMLData) ([]byte, string, error) { switch name { case "text": diff --git a/response_test.go b/response_test.go new file mode 100644 index 0000000..dd68a1f --- /dev/null +++ b/response_test.go @@ -0,0 +1,43 @@ +package authboss + +import ( + "context" + "testing" +) + +type testMailer struct{ sent bool } + +func (t *testMailer) Send(context.Context, Email) error { + t.sent = true + return nil +} + +func TestEmail(t *testing.T) { + t.Parallel() + + ab := New() + + mailer := &testMailer{} + renderer := &mockEmailRenderer{} + ab.Config.Core.Mailer = mailer + ab.Config.Core.MailRenderer = renderer + + email := Email{ + To: []string{"support@authboss.com"}, + Subject: "Send help", + } + + ro := EmailResponseOptions{ + Data: nil, + HTMLTemplate: "html", + TextTemplate: "text", + } + + if err := ab.Email(context.Background(), email, ro); err != nil { + t.Error(err) + } + + if !mailer.sent { + t.Error("the e-mail should have been sent") + } +} diff --git a/storage_test.go b/storage_test.go new file mode 100644 index 0000000..490bba3 --- /dev/null +++ b/storage_test.go @@ -0,0 +1,64 @@ +package authboss + +import ( + "context" + "testing" +) + +type testAssertionFailStorer struct{} + +func (testAssertionFailStorer) Load(ctx context.Context, key string) (User, error) { return nil, nil } +func (testAssertionFailStorer) Save(ctx context.Context, user User) error { return nil } + +func TestStorageAssertions(t *testing.T) { + t.Parallel() + + s := &mockServerStorer{} + fs := testAssertionFailStorer{} + + paniced := false + func() { + defer func() { + if r := recover(); r != nil { + paniced = true + } + }() + + EnsureCanCreate(s) + EnsureCanConfirm(s) + EnsureCanRecover(s) + EnsureCanRemember(s) + EnsureCanOAuth2(s) + }() + + if paniced { + t.Error("The mock storer should have included all interfaces and should not panic") + } + + didPanic := func(f func()) (paniced bool) { + defer func() { + if r := recover(); r != nil { + paniced = true + } + }() + + f() + return paniced + } + + if !didPanic(func() { EnsureCanCreate(fs) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { EnsureCanConfirm(fs) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { EnsureCanRecover(fs) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { EnsureCanRemember(fs) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { EnsureCanOAuth2(fs) }) { + t.Error("should have panic'd") + } +} diff --git a/user_test.go b/user_test.go index 5cda8bf..155d0ec 100644 --- a/user_test.go +++ b/user_test.go @@ -51,3 +51,61 @@ func TestOAuth2PIDs(t *testing.T) { t.Error("expected a panic when the pid doesn't start with oauth2") } } + +type testAssertionFailUser struct{} + +func (testAssertionFailUser) GetPID() string { return "" } +func (testAssertionFailUser) PutPID(string) {} + +func TestUserAssertions(t *testing.T) { + t.Parallel() + + u := &mockUser{} + fu := testAssertionFailUser{} + + paniced := false + func() { + defer func() { + if r := recover(); r != nil { + paniced = true + } + }() + + MustBeAuthable(u) + MustBeConfirmable(u) + MustBeLockable(u) + MustBeOAuthable(u) + MustBeRecoverable(u) + }() + + if paniced { + t.Error("The mock user should have included all interfaces and should not panic") + } + + didPanic := func(f func()) (paniced bool) { + defer func() { + if r := recover(); r != nil { + paniced = true + } + }() + + f() + return paniced + } + + if !didPanic(func() { MustBeAuthable(fu) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustBeConfirmable(fu) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustBeLockable(fu) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustBeOAuthable(fu) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustBeRecoverable(fu) }) { + t.Error("should have panic'd") + } +} diff --git a/values_test.go b/values_test.go new file mode 100644 index 0000000..35f2f66 --- /dev/null +++ b/values_test.go @@ -0,0 +1,70 @@ +package authboss + +import "testing" + +type testAssertionValues struct{} + +func (testAssertionValues) Validate() []error { return nil } +func (testAssertionValues) GetPID() string { return "" } +func (testAssertionValues) GetPassword() string { return "" } +func (testAssertionValues) GetToken() string { return "" } +func (testAssertionValues) GetShouldRemember() bool { return false } +func (testAssertionValues) GetValues() map[string]string { return nil } + +type testAssertionFailValues struct{} + +func (testAssertionFailValues) Validate() []error { return nil } + +func TestValueAssertions(t *testing.T) { + t.Parallel() + + v := testAssertionValues{} + fv := testAssertionFailValues{} + + paniced := false + func() { + defer func() { + if r := recover(); r != nil { + paniced = true + } + + }() + + MustHaveUserValues(v) + MustHaveConfirmValues(v) + MustHaveRecoverStartValues(v) + MustHaveRecoverMiddleValues(v) + MustHaveRecoverEndValues(v) + }() + + if paniced { + t.Error("The mock storer should have included all interfaces and should not panic") + } + + didPanic := func(f func()) (paniced bool) { + defer func() { + if r := recover(); r != nil { + paniced = true + } + }() + + f() + return paniced + } + + if !didPanic(func() { MustHaveUserValues(fv) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustHaveConfirmValues(fv) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustHaveRecoverStartValues(fv) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustHaveRecoverMiddleValues(fv) }) { + t.Error("should have panic'd") + } + if !didPanic(func() { MustHaveRecoverEndValues(fv) }) { + t.Error("should have panic'd") + } +}