1
0
mirror of https://github.com/volatiletech/authboss.git synced 2024-12-12 10:45:11 +02:00
authboss/internal/mocks/mocks.go
2015-08-02 11:51:35 -07:00

344 lines
7.1 KiB
Go

// Package mocks defines implemented interfaces for testing modules
package mocks
import (
"errors"
"io"
"net/http"
"net/url"
"strings"
"time"
"gopkg.in/authboss.v0"
)
// MockUser represents all possible fields a authboss User may have
type MockUser struct {
Username string
Email string
Password string
RecoverToken string
RecoverTokenExpiry time.Time
ConfirmToken string
Confirmed bool
Locked bool
AttemptNumber int
AttemptTime time.Time
OauthToken string
OauthRefresh string
OauthExpiry time.Time
}
// MockStorer should be valid for any module storer defined in authboss.
type MockStorer struct {
Users map[string]authboss.Attributes
Tokens map[string][]string
CreateErr string
PutErr string
GetErr string
AddTokenErr string
DelTokensErr string
UseTokenErr string
RecoverUserErr string
ConfirmUserErr string
}
// NewMockStorer constructor
func NewMockStorer() *MockStorer {
return &MockStorer{
Users: make(map[string]authboss.Attributes),
Tokens: make(map[string][]string),
}
}
// Create a new user
func (m *MockStorer) Create(key string, attr authboss.Attributes) error {
if len(m.CreateErr) > 0 {
return errors.New(m.CreateErr)
}
m.Users[key] = attr
return nil
}
// Put updates to a user
func (m *MockStorer) Put(key string, attr authboss.Attributes) error {
if len(m.PutErr) > 0 {
return errors.New(m.PutErr)
}
if _, ok := m.Users[key]; !ok {
m.Users[key] = attr
return nil
}
for k, v := range attr {
m.Users[key][k] = v
}
return nil
}
// Get a user
func (m *MockStorer) Get(key string) (result interface{}, err error) {
if len(m.GetErr) > 0 {
return nil, errors.New(m.GetErr)
}
userAttrs, ok := m.Users[key]
if !ok {
return nil, authboss.ErrUserNotFound
}
u := &MockUser{}
if err := userAttrs.Bind(u, true); err != nil {
panic(err)
}
return u, nil
}
// PutOAuth user
func (m *MockStorer) PutOAuth(uid, provider string, attr authboss.Attributes) error {
if len(m.PutErr) > 0 {
return errors.New(m.PutErr)
}
if _, ok := m.Users[uid+provider]; !ok {
m.Users[uid+provider] = attr
return nil
}
for k, v := range attr {
m.Users[uid+provider][k] = v
}
return nil
}
// GetOAuth user
func (m *MockStorer) GetOAuth(uid, provider string) (result interface{}, err error) {
if len(m.GetErr) > 0 {
return nil, errors.New(m.GetErr)
}
userAttrs, ok := m.Users[uid+provider]
if !ok {
return nil, authboss.ErrUserNotFound
}
u := &MockUser{}
if err := userAttrs.Bind(u, true); err != nil {
panic(err)
}
return u, nil
}
// AddToken for remember me
func (m *MockStorer) AddToken(key, token string) error {
if len(m.AddTokenErr) > 0 {
return errors.New(m.AddTokenErr)
}
arr := m.Tokens[key]
m.Tokens[key] = append(arr, token)
return nil
}
// DelTokens for a user
func (m *MockStorer) DelTokens(key string) error {
if len(m.DelTokensErr) > 0 {
return errors.New(m.DelTokensErr)
}
delete(m.Tokens, key)
return nil
}
// UseToken if it exists, deleting it in the process
func (m *MockStorer) UseToken(givenKey, token string) (err error) {
if len(m.UseTokenErr) > 0 {
return errors.New(m.UseTokenErr)
}
if arr, ok := m.Tokens[givenKey]; ok {
for _, tok := range arr {
if tok == token {
return nil
}
}
}
return authboss.ErrTokenNotFound
}
// RecoverUser by the token.
func (m *MockStorer) RecoverUser(token string) (result interface{}, err error) {
if len(m.RecoverUserErr) > 0 {
return nil, errors.New(m.RecoverUserErr)
}
for _, user := range m.Users {
if user["recover_token"] == token {
u := &MockUser{}
if err = user.Bind(u, false); err != nil {
panic(err)
}
return u, nil
}
}
return nil, authboss.ErrUserNotFound
}
// ConfirmUser via their token
func (m *MockStorer) ConfirmUser(confirmToken string) (result interface{}, err error) {
if len(m.ConfirmUserErr) > 0 {
return nil, errors.New(m.ConfirmUserErr)
}
for _, user := range m.Users {
if user["confirm_token"] == confirmToken {
u := &MockUser{}
if err = user.Bind(u, false); err != nil {
panic(err)
}
return u, nil
}
}
return nil, authboss.ErrUserNotFound
}
// MockFailStorer is used for testing module initialize functions that recover more than the base storer
type MockFailStorer struct{}
// Create fails
func (_ MockFailStorer) Create(_ string, _ authboss.Attributes) error {
return errors.New("fail storer: create")
}
// Put fails
func (_ MockFailStorer) Put(_ string, _ authboss.Attributes) error {
return errors.New("fail storer: put")
}
// Get fails
func (_ MockFailStorer) Get(_ string) (interface{}, error) {
return nil, errors.New("fail storer: get")
}
// MockClientStorer is used for testing the client stores on context
type MockClientStorer struct {
Values map[string]string
GetShouldFail bool
}
// NewMockClientStorer constructs a MockClientStorer
func NewMockClientStorer(data ...string) *MockClientStorer {
if len(data)%2 != 0 {
panic("It should be a key value list of arguments.")
}
values := make(map[string]string)
for i := 0; i < len(data)-1; i += 2 {
values[data[i]] = data[i+1]
}
return &MockClientStorer{Values: values}
}
// Get a key's value
func (m *MockClientStorer) Get(key string) (string, bool) {
if m.GetShouldFail {
return "", false
}
v, ok := m.Values[key]
return v, ok
}
// GetErr gets a key's value or err if not exist
func (m *MockClientStorer) GetErr(key string) (string, error) {
if m.GetShouldFail {
return "", authboss.ClientDataErr{key}
}
v, ok := m.Values[key]
if !ok {
return v, authboss.ClientDataErr{key}
}
return v, nil
}
// Put a value
func (m *MockClientStorer) Put(key, val string) { m.Values[key] = val }
// Del a key/value pair
func (m *MockClientStorer) Del(key string) { delete(m.Values, key) }
// MockRequest returns a new mock request with optional key-value body (form-post)
func MockRequest(method string, postKeyValues ...string) *http.Request {
var body io.Reader
if len(postKeyValues) > 0 {
urlValues := make(url.Values)
for i := 0; i < len(postKeyValues); i += 2 {
urlValues.Set(postKeyValues[i], postKeyValues[i+1])
}
body = strings.NewReader(urlValues.Encode())
}
req, err := http.NewRequest(method, "http://localhost", body)
if err != nil {
panic(err.Error())
}
if len(postKeyValues) > 0 {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
return req
}
// MockMailer helps simplify mailer testing by storing the last sent email
type MockMailer struct {
Last authboss.Email
SendErr string
}
// NewMockMailer constructs a mock mailer
func NewMockMailer() *MockMailer {
return &MockMailer{}
}
// Send an e-mail
func (m *MockMailer) Send(email authboss.Email) error {
if len(m.SendErr) > 0 {
return errors.New(m.SendErr)
}
m.Last = email
return nil
}
// MockAfterCallback is a callback that knows if it was called
type MockAfterCallback struct {
HasBeenCalled bool
Fn authboss.After
}
// NewMockAfterCallback constructs a new mockaftercallback.
func NewMockAfterCallback() *MockAfterCallback {
m := MockAfterCallback{}
m.Fn = func(_ *authboss.Context) error {
m.HasBeenCalled = true
return nil
}
return &m
}