1
0
mirror of https://github.com/volatiletech/authboss.git synced 2024-11-24 08:42:17 +02:00
authboss/mocks_test.go
Aaron L 24fc6196c7 Introduce new type of client storage
- This addresses the problem of having to update multiple times during
  one request. It's hard to have a nice interface especially with JWT
  because you always end up having to decode the request, encode new
  response, write header, then a second write to it comes, and where do
  you grab the value from? Often you don't have access to the response
  as a "read" structure. So we store it as events instead, and play
  those events against the original data right before the response is
  written to set the headers.
2017-02-24 16:45:47 -08:00

204 lines
4.0 KiB
Go

package authboss
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/url"
"strings"
"github.com/pkg/errors"
)
type mockUser struct {
Email string
Password string
}
type mockStoredUser struct {
mockUser
mockStoreLoader
}
type mockStoreLoader map[string]mockUser
func (m mockStoreLoader) Load(ctx context.Context, key string) (Storer, error) {
u, ok := m[key]
if !ok {
return nil, ErrUserNotFound
}
return mockStoredUser{
mockUser: u,
mockStoreLoader: m,
}, nil
}
func (m mockStoredUser) Load(ctx context.Context) error {
u, ok := m.mockStoreLoader[m.Email]
if !ok {
return ErrUserNotFound
}
m.Email = u.Email
m.Password = u.Password
return nil
}
func (m mockStoredUser) Save(ctx context.Context) error {
m.mockStoreLoader[m.Email] = m.mockUser
return nil
}
func (m mockStoredUser) PutEmail(ctx context.Context, email string) error {
m.Email = email
return nil
}
func (m mockStoredUser) PutUsername(ctx context.Context, username string) error {
return errors.New("not impl")
}
func (m mockStoredUser) PutPassword(ctx context.Context, password string) error {
m.Password = password
return nil
}
func (m mockStoredUser) GetEmail(ctx context.Context) (email string, err error) {
return m.Email, nil
}
func (m mockStoredUser) GetUsername(ctx context.Context) (username string, err error) {
return "", errors.New("not impl")
}
func (m mockStoredUser) GetPassword(ctx context.Context) (password string, err error) {
return m.Password, nil
}
type mockClientStateReadWriter struct {
state mockClientState
}
type mockClientState map[string]string
func newMockClientStateRW(keyValue ...string) mockClientStateReadWriter {
state := mockClientState{}
for i := 0; i < len(keyValue); i += 2 {
key, value := keyValue[i], keyValue[i+1]
state[key] = value
}
return mockClientStateReadWriter{state}
}
func (m mockClientStateReadWriter) ReadState(w http.ResponseWriter, r *http.Request) (ClientState, error) {
return m.state, nil
}
func (m mockClientStateReadWriter) WriteState(w http.ResponseWriter, cs ClientState, evs []ClientStateEvent) error {
var state mockClientState
if cs != nil {
state = cs.(mockClientState)
} else {
state = mockClientState{}
}
for _, ev := range evs {
switch ev.Kind {
case ClientStateEventPut:
state[ev.Key] = ev.Value
case ClientStateEventDel:
delete(state, ev.Key)
}
}
b, err := json.Marshal(state)
if err != nil {
return err
}
w.Header().Set("test_session", string(b))
return nil
}
func (m mockClientState) Get(key string) (string, bool) {
val, ok := m[key]
return val, ok
}
func newMockRequest(postKeyValues ...string) *http.Request {
urlValues := make(url.Values)
for i := 0; i < len(postKeyValues); i += 2 {
urlValues.Set(postKeyValues[i], postKeyValues[i+1])
}
req, err := http.NewRequest("POST", "http://localhost", strings.NewReader(urlValues.Encode()))
if err != nil {
panic(err.Error())
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req
}
func newMockAPIRequest(postKeyValues ...string) *http.Request {
kv := map[string]string{}
for i := 0; i < len(postKeyValues); i += 2 {
key, value := postKeyValues[i], postKeyValues[i+1]
kv[key] = value
}
b, err := json.Marshal(kv)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", "http://localhost", bytes.NewReader(b))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
return req
}
type mockValidator struct {
FieldName string
Errs ErrorList
Ruleset []string
}
func (m mockValidator) Field() string {
return m.FieldName
}
func (m mockValidator) Errors(in string) ErrorList {
return m.Errs
}
func (m mockValidator) Rules() []string {
return m.Ruleset
}
type mockRenderLoader struct{}
func (m mockRenderLoader) Init(names []string) (Renderer, error) {
return mockRenderer{}, nil
}
type mockRenderer struct{}
func (m mockRenderer) Render(ctx context.Context, name string, data HTMLData) ([]byte, string, error) {
b, err := json.Marshal(data)
if err != nil {
return nil, "", err
}
return b, "application/json", nil
}