lens @ 4d930c0c8cb585979798fac2bb254f991faa62fb

  1//go:build unit
  2
  3package auth
  4
  5import (
  6	"context"
  7	"errors"
  8	"testing"
  9
 10	"github.com/samber/lo"
 11
 12	"git.sr.ht/~gabrielgio/img/pkg/components/user"
 13	"git.sr.ht/~gabrielgio/img/pkg/ext"
 14	"git.sr.ht/~gabrielgio/img/pkg/testkit"
 15)
 16
 17type (
 18	scene struct {
 19		ctx            context.Context
 20		mockRepository *MockUserRepository
 21		controller     Controller
 22	}
 23
 24	mockUser struct {
 25		id       uint
 26		username string
 27		password []byte
 28	}
 29
 30	MockUserRepository struct {
 31		index uint
 32		users []*mockUser
 33		err   error
 34	}
 35)
 36
 37var (
 38	_   Repository = &MockUserRepository{}
 39	key            = []byte("6368616e676520746869732070617373")
 40)
 41
 42func setUp() *scene {
 43	mockUserRepository := &MockUserRepository{}
 44	return &scene{
 45		ctx:            context.Background(),
 46		mockRepository: mockUserRepository,
 47		controller:     *NewController(mockUserRepository, nil, key),
 48	}
 49}
 50
 51func TestInitialRegisterAndLogin(t *testing.T) {
 52	testCases := []struct {
 53		name     string
 54		username string
 55		password []byte
 56	}{
 57		{
 58			name:     "Normal register",
 59			username: "username",
 60			password: []byte("password"),
 61		},
 62	}
 63
 64	for _, tc := range testCases {
 65		t.Run(tc.name, func(t *testing.T) {
 66			scene := setUp()
 67
 68			err := scene.controller.InitialRegister(scene.ctx, []byte(tc.username), tc.password, []byte("/"))
 69			testkit.TestFatalError(t, "Register", err)
 70
 71			userID := scene.mockRepository.GetLastId()
 72
 73			user, err := scene.mockRepository.Get(scene.ctx, userID)
 74			testkit.TestFatalError(t, "Get", err)
 75			testkit.TestValue(t, "Register", tc.username, user.Username)
 76
 77			auth, err := scene.controller.Login(scene.ctx, []byte(tc.username), tc.password)
 78			testkit.TestFatalError(t, "Login", err)
 79
 80			token, err := ext.ReadToken(auth, key)
 81			testkit.TestFatalError(t, "Login", err)
 82
 83			testkit.TestValue(t, "Login", tc.username, token.Username)
 84			testkit.TestValue(t, "Login", userID, token.UserID)
 85		})
 86	}
 87}
 88
 89func toUser(m *mockUser, _ int) *user.User {
 90	return &user.User{
 91		ID:       m.id,
 92		Username: m.username,
 93	}
 94}
 95
 96func (m *MockUserRepository) GetLastId() uint {
 97	return m.index
 98}
 99
100func (m *MockUserRepository) List(ctx context.Context) ([]*user.User, error) {
101	if m.err != nil {
102		return nil, m.err
103	}
104
105	return lo.Map(m.users, toUser), nil
106}
107
108func (m *MockUserRepository) Get(ctx context.Context, id uint) (*user.User, error) {
109	if m.err != nil {
110		return nil, m.err
111	}
112
113	for _, m := range m.users {
114		if m.id == id {
115			return toUser(m, 0), nil
116		}
117	}
118	return nil, errors.New("Item not found")
119}
120
121func (m *MockUserRepository) GetIDByUsername(ctx context.Context, username string) (uint, error) {
122	if m.err != nil {
123		return 0, m.err
124	}
125
126	for _, m := range m.users {
127		if m.username == username {
128			return m.id, nil
129		}
130	}
131	return 0, errors.New("Item not found")
132}
133
134func (m *MockUserRepository) GetPassword(ctx context.Context, id uint) ([]byte, error) {
135	if m.err != nil {
136		return nil, m.err
137	}
138
139	for _, m := range m.users {
140		if m.id == id {
141			return m.password, nil
142		}
143	}
144	return nil, errors.New("Item not found")
145}
146
147func (m *MockUserRepository) Create(ctx context.Context, createUser *user.CreateUser) (uint, error) {
148	if m.err != nil {
149		return 0, m.err
150	}
151
152	m.index++
153
154	m.users = append(m.users, &mockUser{
155		id:       m.index,
156		username: createUser.Username,
157		password: createUser.Password,
158	})
159
160	return m.index, nil
161}
162
163func (m *MockUserRepository) Update(ctx context.Context, id uint, update *user.UpdateUser) error {
164	if m.err != nil {
165		return m.err
166	}
167
168	for _, m := range m.users {
169		if m.id == id {
170			m.username = update.Username
171		}
172	}
173	return nil
174}
175
176func remove[T any](slice []T, s int) []T {
177	return append(slice[:s], slice[s+1:]...)
178}
179
180func (r *MockUserRepository) Delete(ctx context.Context, id uint) error {
181	if r.err != nil {
182		return r.err
183	}
184
185	for i, m := range r.users {
186		if m.id == id {
187			r.users = remove(r.users, i)
188		}
189	}
190	return nil
191}