lens @ 9ba05d26ee2382f3191e25ae7af5d462ba2a35e4

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