add mock package and use in invite tests (#603)

* add mock package and use in invite tests

* mock expired invite test
This commit is contained in:
Victor Vrantchan 2017-01-10 16:49:14 -05:00 коммит произвёл GitHub
Родитель 1ba5559ae3
Коммит 9789543f8f
9 изменённых файлов: 416 добавлений и 62 удалений

38
server/mock/datastore.go Normal file
Просмотреть файл

@ -0,0 +1,38 @@
package mock
//go:generate mockimpl -o datastore_users.go "s *UserStore" "kolide.UserStore"
//go:generate mockimpl -o datastore_invites.go "s *InviteStore" "kolide.InviteStore"
//go:generate mockimpl -o datastore_appconfig.go "s *AppConfigStore" "kolide.AppConfigStore"
import "github.com/kolide/kolide-ose/server/kolide"
var _ kolide.Datastore = (*Store)(nil)
type Store struct {
kolide.HostStore
kolide.LabelStore
kolide.PackStore
kolide.CampaignStore
kolide.SessionStore
kolide.PasswordResetStore
kolide.QueryStore
kolide.OptionStore
kolide.ScheduledQueryStore
InviteStore
UserStore
AppConfigStore
}
func (m *Store) Drop() error {
return nil
}
func (m *Store) MigrateTables() error {
return nil
}
func (m *Store) MigrateData() error {
return nil
}
func (m *Store) Name() string {
return "mock"
}

Просмотреть файл

@ -0,0 +1,39 @@
// Automatically generated by mockimpl. DO NOT EDIT!
package mock
import "github.com/kolide/kolide-ose/server/kolide"
var _ kolide.AppConfigStore = (*AppConfigStore)(nil)
type NewAppConfigFunc func(info *kolide.AppConfig) (*kolide.AppConfig, error)
type AppConfigFunc func() (*kolide.AppConfig, error)
type SaveAppConfigFunc func(info *kolide.AppConfig) error
type AppConfigStore struct {
NewAppConfigFunc NewAppConfigFunc
NewAppConfigFuncInvoked bool
AppConfigFunc AppConfigFunc
AppConfigFuncInvoked bool
SaveAppConfigFunc SaveAppConfigFunc
SaveAppConfigFuncInvoked bool
}
func (s *AppConfigStore) NewAppConfig(info *kolide.AppConfig) (*kolide.AppConfig, error) {
s.NewAppConfigFuncInvoked = true
return s.NewAppConfigFunc(info)
}
func (s *AppConfigStore) AppConfig() (*kolide.AppConfig, error) {
s.AppConfigFuncInvoked = true
return s.AppConfigFunc()
}
func (s *AppConfigStore) SaveAppConfig(info *kolide.AppConfig) error {
s.SaveAppConfigFuncInvoked = true
return s.SaveAppConfigFunc(info)
}

Просмотреть файл

@ -0,0 +1,9 @@
package mock
import "github.com/kolide/kolide-ose/server/kolide"
func ReturnFakeAppConfig(fake *kolide.AppConfig) AppConfigFunc {
return func() (*kolide.AppConfig, error) {
return fake, nil
}
}

Просмотреть файл

@ -0,0 +1,79 @@
// Automatically generated by mockimpl. DO NOT EDIT!
package mock
import "github.com/kolide/kolide-ose/server/kolide"
var _ kolide.InviteStore = (*InviteStore)(nil)
type NewInviteFunc func(i *kolide.Invite) (*kolide.Invite, error)
type ListInvitesFunc func(opt kolide.ListOptions) ([]*kolide.Invite, error)
type InviteFunc func(id uint) (*kolide.Invite, error)
type InviteByEmailFunc func(email string) (*kolide.Invite, error)
type InviteByTokenFunc func(token string) (*kolide.Invite, error)
type SaveInviteFunc func(i *kolide.Invite) error
type DeleteInviteFunc func(id uint) error
type InviteStore struct {
NewInviteFunc NewInviteFunc
NewInviteFuncInvoked bool
ListInvitesFunc ListInvitesFunc
ListInvitesFuncInvoked bool
InviteFunc InviteFunc
InviteFuncInvoked bool
InviteByEmailFunc InviteByEmailFunc
InviteByEmailFuncInvoked bool
InviteByTokenFunc InviteByTokenFunc
InviteByTokenFuncInvoked bool
SaveInviteFunc SaveInviteFunc
SaveInviteFuncInvoked bool
DeleteInviteFunc DeleteInviteFunc
DeleteInviteFuncInvoked bool
}
func (s *InviteStore) NewInvite(i *kolide.Invite) (*kolide.Invite, error) {
s.NewInviteFuncInvoked = true
return s.NewInviteFunc(i)
}
func (s *InviteStore) ListInvites(opt kolide.ListOptions) ([]*kolide.Invite, error) {
s.ListInvitesFuncInvoked = true
return s.ListInvitesFunc(opt)
}
func (s *InviteStore) Invite(id uint) (*kolide.Invite, error) {
s.InviteFuncInvoked = true
return s.InviteFunc(id)
}
func (s *InviteStore) InviteByEmail(email string) (*kolide.Invite, error) {
s.InviteByEmailFuncInvoked = true
return s.InviteByEmailFunc(email)
}
func (s *InviteStore) InviteByToken(token string) (*kolide.Invite, error) {
s.InviteByTokenFuncInvoked = true
return s.InviteByTokenFunc(token)
}
func (s *InviteStore) SaveInvite(i *kolide.Invite) error {
s.SaveInviteFuncInvoked = true
return s.SaveInviteFunc(i)
}
func (s *InviteStore) DeleteInvite(id uint) error {
s.DeleteInviteFuncInvoked = true
return s.DeleteInviteFunc(id)
}

Просмотреть файл

@ -0,0 +1,33 @@
package mock
import "github.com/kolide/kolide-ose/server/kolide"
func ReturnNewInivite(fake *kolide.Invite) NewInviteFunc {
return func(i *kolide.Invite) (*kolide.Invite, error) {
return fake, nil
}
}
func ReturnFakeInviteByEmail(fake *kolide.Invite) InviteByEmailFunc {
return func(string) (*kolide.Invite, error) {
return fake, nil
}
}
func ReturnFakeInviteByToken(fake *kolide.Invite) InviteByTokenFunc {
return func(string) (*kolide.Invite, error) {
return fake, nil
}
}
func ReturnInviteFuncNotFound() InviteFunc {
return func(id uint) (*kolide.Invite, error) {
return nil, &Error{"not found"}
}
}
func ReturnFakeInviteByID(fake *kolide.Invite) InviteFunc {
return func(id uint) (*kolide.Invite, error) {
return fake, nil
}
}

Просмотреть файл

@ -0,0 +1,69 @@
// Automatically generated by mockimpl. DO NOT EDIT!
package mock
import "github.com/kolide/kolide-ose/server/kolide"
var _ kolide.UserStore = (*UserStore)(nil)
type NewUserFunc func(user *kolide.User) (*kolide.User, error)
type UserFunc func(username string) (*kolide.User, error)
type ListUsersFunc func(opt kolide.ListOptions) ([]*kolide.User, error)
type UserByEmailFunc func(email string) (*kolide.User, error)
type UserByIDFunc func(id uint) (*kolide.User, error)
type SaveUserFunc func(user *kolide.User) error
type UserStore struct {
NewUserFunc NewUserFunc
NewUserFuncInvoked bool
UserFunc UserFunc
UserFuncInvoked bool
ListUsersFunc ListUsersFunc
ListUsersFuncInvoked bool
UserByEmailFunc UserByEmailFunc
UserByEmailFuncInvoked bool
UserByIDFunc UserByIDFunc
UserByIDFuncInvoked bool
SaveUserFunc SaveUserFunc
SaveUserFuncInvoked bool
}
func (s *UserStore) NewUser(user *kolide.User) (*kolide.User, error) {
s.NewUserFuncInvoked = true
return s.NewUserFunc(user)
}
func (s *UserStore) User(username string) (*kolide.User, error) {
s.UserFuncInvoked = true
return s.UserFunc(username)
}
func (s *UserStore) ListUsers(opt kolide.ListOptions) ([]*kolide.User, error) {
s.ListUsersFuncInvoked = true
return s.ListUsersFunc(opt)
}
func (s *UserStore) UserByEmail(email string) (*kolide.User, error) {
s.UserByEmailFuncInvoked = true
return s.UserByEmailFunc(email)
}
func (s *UserStore) UserByID(id uint) (*kolide.User, error) {
s.UserByIDFuncInvoked = true
return s.UserByIDFunc(id)
}
func (s *UserStore) SaveUser(user *kolide.User) error {
s.SaveUserFuncInvoked = true
return s.SaveUserFunc(user)
}

Просмотреть файл

@ -0,0 +1,21 @@
package mock
import "github.com/kolide/kolide-ose/server/kolide"
func UserByEmailWithUser(u *kolide.User) UserByEmailFunc {
return func(email string) (*kolide.User, error) {
return u, nil
}
}
func UserWithEmailNotFound() UserByEmailFunc {
return func(email string) (*kolide.User, error) {
return nil, &Error{"not found"}
}
}
func UserWithID(u *kolide.User) UserByIDFunc {
return func(id uint) (*kolide.User, error) {
return u, nil
}
}

19
server/mock/errors.go Normal file
Просмотреть файл

@ -0,0 +1,19 @@
package mock
type Error struct {
Message string
}
func (e *Error) Error() string {
return e.Message
}
// implement kolide.NotFoundError
func (e *Error) IsNotFound() bool {
return true
}
// implement kolide.AlreadyExistsError
func (e *Error) IsExists() bool {
return true
}

Просмотреть файл

@ -1,80 +1,127 @@
package service
import (
"errors"
"testing"
"golang.org/x/net/context"
"time"
"github.com/WatchBeam/clock"
"github.com/kolide/kolide-ose/server/config"
"github.com/kolide/kolide-ose/server/datastore/inmem"
"github.com/kolide/kolide-ose/server/kolide"
"github.com/kolide/kolide-ose/server/mock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestInviteNewUser(t *testing.T) {
ds, err := inmem.New(config.TestConfig())
createTestUsers(t, ds)
createTestAppConfig(t, ds)
assert.Nil(t, err)
nosuchAdminID := uint(999)
adminID := uint(1)
func TestInviteNewUserMock(t *testing.T) {
svc, mockStore, mailer := setupInviteTest(t)
ctx := context.Background()
payload := kolide.InvitePayload{
Email: stringPtr("user@acme.co"),
InvitedBy: &adminUser.ID,
Admin: boolPtr(false),
}
// happy path
invite, err := svc.InviteNewUser(ctx, payload)
require.Nil(t, err)
assert.Equal(t, invite.ID, validInvite.ID)
assert.True(t, mockStore.NewInviteFuncInvoked)
assert.True(t, mockStore.AppConfigFuncInvoked)
assert.True(t, mailer.Invoked)
mockStore.UserByEmailFunc = mock.UserByEmailWithUser(new(kolide.User))
_, err = svc.InviteNewUser(ctx, payload)
require.NotNil(t, err, "should err if the user we're inviting already exists")
}
func TestVerifyInvite(t *testing.T) {
ms := new(mock.Store)
svc := service{
ds: ms,
config: config.TestConfig(),
clock: clock.NewMockClock(),
}
ctx := context.Background()
ms.InviteByTokenFunc = mock.ReturnFakeInviteByToken(expiredInvite)
wantErr := &invalidArgumentError{{name: "invite_token", reason: "Invite token has expired."}}
_, err := svc.VerifyInvite(ctx, expiredInvite.Token)
assert.Equal(t, err, wantErr)
wantErr = &invalidArgumentError{{name: "invite_token",
reason: "Invite Token does not match Email Address."}}
_, err = svc.VerifyInvite(ctx, "bad_token")
assert.Equal(t, err, wantErr)
}
func TestDeleteInvite(t *testing.T) {
ms := new(mock.Store)
svc := service{ds: ms}
ms.DeleteInviteFunc = func(uint) error { return nil }
err := svc.DeleteInvite(context.Background(), 1)
require.Nil(t, err)
assert.True(t, ms.DeleteInviteFuncInvoked)
}
func TestListInvites(t *testing.T) {
ms := new(mock.Store)
svc := service{ds: ms}
ms.ListInvitesFunc = func(kolide.ListOptions) ([]*kolide.Invite, error) {
return nil, nil
}
_, err := svc.ListInvites(context.Background(), kolide.ListOptions{})
require.Nil(t, err)
assert.True(t, ms.ListInvitesFuncInvoked)
}
func setupInviteTest(t *testing.T) (kolide.Service, *mock.Store, *mockMailService) {
ms := new(mock.Store)
ms.UserByEmailFunc = mock.UserWithEmailNotFound()
ms.UserByIDFunc = mock.UserWithID(adminUser)
ms.NewInviteFunc = mock.ReturnNewInivite(validInvite)
ms.AppConfigFunc = mock.ReturnFakeAppConfig(&kolide.AppConfig{
KolideServerURL: "https://acme.co",
})
mailer := &mockMailService{SendEmailFn: func(e kolide.Email) error { return nil }}
svc := validationMiddleware{service{
ds: ds,
ds: ms,
config: config.TestConfig(),
mailService: mailer,
clock: clock.NewMockClock(),
}}
var inviteTests = []struct {
payload kolide.InvitePayload
wantErr error
}{
{
wantErr: &invalidArgumentError{
{name: "email", reason: "missing required argument"},
{name: "invited_by", reason: "missing required argument"},
{name: "admin", reason: "missing required argument"},
},
},
{
payload: kolide.InvitePayload{
Email: stringPtr("nosuchuser@example.com"),
InvitedBy: &nosuchAdminID,
Admin: boolPtr(false),
},
wantErr: errors.New("User 999 was not found in the datastore"),
},
{
payload: kolide.InvitePayload{
Email: stringPtr("admin1@example.com"),
InvitedBy: &adminID,
Admin: boolPtr(false),
},
wantErr: &invalidArgumentError{
{name: "email", reason: "a user with this account already exists"}},
},
{
payload: kolide.InvitePayload{
Email: stringPtr("nosuchuser@example.com"),
InvitedBy: &adminID,
Admin: boolPtr(false),
},
},
}
for _, tt := range inviteTests {
t.Run("", func(t *testing.T) {
invite, err := svc.InviteNewUser(context.Background(), tt.payload)
if tt.wantErr != nil {
assert.Equal(t, tt.wantErr.Error(), err.Error())
return
} else {
assert.Nil(t, err)
}
assert.Equal(t, *tt.payload.InvitedBy, invite.InvitedBy)
})
}
return svc, ms, mailer
}
var adminUser = &kolide.User{
ID: 1,
Email: "admin@acme.co",
Username: "admin",
Name: "Administrator",
}
var existingUser = &kolide.User{
ID: 2,
Email: "user@acme.co",
Username: "user",
}
var validInvite = &kolide.Invite{
ID: 1,
Token: "abcd",
}
var expiredInvite = &kolide.Invite{
ID: 1,
Token: "abcd",
UpdateCreateTimestamps: kolide.UpdateCreateTimestamps{
CreateTimestamp: kolide.CreateTimestamp{
CreatedAt: time.Now().AddDate(-1, 0, 0),
},
},
}