tests: implemented go user api tests
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// GenerateID generates a new UUID string.
|
||||
func GenerateID() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/domain/repository"
|
||||
"context"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
)
|
||||
|
||||
// MockAuthRepository is a mock implementation of AuthRepository.
|
||||
type MockAuthRepository struct{}
|
||||
|
||||
// NewMockAuthRepository creates a new instance of MockAuthRepository.
|
||||
func NewMockAuthRepository() repository.AuthRepository {
|
||||
return &MockAuthRepository{}
|
||||
}
|
||||
|
||||
// GenerateToken always returns a successful token generation.
|
||||
func (m *MockAuthRepository) GenerateToken(ctx context.Context) func(userID string) E.Either[error, string] {
|
||||
return func(userID string) E.Either[error, string] {
|
||||
return E.Right[error]("mocked-token")
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateToken always validates a token successfully.
|
||||
func (m *MockAuthRepository) ValidateToken(ctx context.Context) func(token string) E.Either[error, string] {
|
||||
return func(token string) E.Either[error, string] {
|
||||
return E.Right[error]("mocked-user-id")
|
||||
}
|
||||
}
|
||||
|
||||
// RevokeToken always revokes a token successfully.
|
||||
func (m *MockAuthRepository) RevokeToken(ctx context.Context) func(token string) E.Either[error, string] {
|
||||
return func(token string) E.Either[error, string] {
|
||||
return E.Right[error]("mocked-user-id")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/domain/data"
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
impl "actatempus_backend/internal/infrastructure/data"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
type MockProjectDataSource struct {
|
||||
Store map[string]*entities.Project
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMockProjectDataSource() data.ProjectDataSource {
|
||||
return &MockProjectDataSource{
|
||||
Store: make(map[string]*entities.Project),
|
||||
}
|
||||
}
|
||||
|
||||
// Create adds a new project to the store
|
||||
func (ds *MockProjectDataSource) Create(ctx context.Context, project entities.ProjectCreate) E.Either[error, entities.Project] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
id := GenerateID()
|
||||
newProject := entities.Project{
|
||||
ID: id,
|
||||
Name: project.Name,
|
||||
UserID: project.UserID,
|
||||
Description: project.Description,
|
||||
ClientID: project.ClientID,
|
||||
}
|
||||
|
||||
ds.Store[id] = &newProject
|
||||
|
||||
return E.Right[error](newProject)
|
||||
}
|
||||
|
||||
// FindByID retrieves a project by its ID
|
||||
func (ds *MockProjectDataSource) FindByID(ctx context.Context, id string) E.Either[error, entities.Project] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
return F.Pipe2(
|
||||
O.FromNillable(ds.Store[id]),
|
||||
E.FromOption[*entities.Project](F.Constant(fmt.Errorf("project with ID %s not found", id))),
|
||||
E.Chain(impl.TryDereference[entities.Project]),
|
||||
)
|
||||
}
|
||||
|
||||
// Update modifies an existing project
|
||||
func (ds *MockProjectDataSource) Update(ctx context.Context, project entities.ProjectUpdate) E.Either[error, entities.Project] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[project.ID]
|
||||
if !found {
|
||||
return E.Left[entities.Project](fmt.Errorf("project with ID %s not found", project.ID))
|
||||
}
|
||||
|
||||
if project.Name != nil {
|
||||
existing.Name = *project.Name
|
||||
}
|
||||
if project.Description != nil {
|
||||
existing.Description = project.Description
|
||||
}
|
||||
if project.ClientID != nil {
|
||||
existing.ClientID = project.ClientID
|
||||
}
|
||||
if project.UserID != nil {
|
||||
existing.UserID = *project.UserID
|
||||
}
|
||||
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// Delete removes a project from the store
|
||||
func (ds *MockProjectDataSource) Delete(ctx context.Context, id string) E.Either[error, entities.Project] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[id]
|
||||
if !found {
|
||||
return E.Left[entities.Project](fmt.Errorf("project with ID %s not found", id))
|
||||
}
|
||||
|
||||
delete(ds.Store, id)
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// FindAll retrieves all projects
|
||||
func (ds *MockProjectDataSource) FindAll(ctx context.Context) E.Either[error, []entities.Project] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
projects := make([]entities.Project, 0, len(ds.Store))
|
||||
for _, project := range ds.Store {
|
||||
projects = append(projects, *project)
|
||||
}
|
||||
|
||||
return E.Right[error](projects)
|
||||
}
|
||||
|
||||
// FindByUserID retrieves all projects for a specific user
|
||||
func (ds *MockProjectDataSource) FindByUserID(ctx context.Context, userID string) E.Either[error, []entities.Project] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
projects := make([]entities.Project, 0)
|
||||
for _, project := range ds.Store {
|
||||
if project.UserID == userID {
|
||||
projects = append(projects, *project)
|
||||
}
|
||||
}
|
||||
|
||||
return E.Right[error](projects)
|
||||
}
|
||||
|
||||
func (ds *MockProjectDataSource) Clear() {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
ds.Store = make(map[string]*entities.Project)
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/domain/data"
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
impl "actatempus_backend/internal/infrastructure/data"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
type MockProjectTaskDataSource struct {
|
||||
Store map[string]*entities.ProjectTask
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMockProjectTaskDataSource() data.ProjectTaskDataSource {
|
||||
return &MockProjectTaskDataSource{
|
||||
Store: make(map[string]*entities.ProjectTask),
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new ProjectTask
|
||||
func (ds *MockProjectTaskDataSource) Create(ctx context.Context, task entities.ProjectTaskCreate) E.Either[error, entities.ProjectTask] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
id := GenerateID()
|
||||
newTask := entities.ProjectTask{
|
||||
ID: id,
|
||||
Name: task.Name,
|
||||
ProjectID: task.ProjectID,
|
||||
Description: task.Description,
|
||||
}
|
||||
|
||||
ds.Store[id] = &newTask
|
||||
|
||||
return E.Right[error](newTask)
|
||||
}
|
||||
|
||||
// Find ProjectTask by ID
|
||||
func (ds *MockProjectTaskDataSource) FindByID(ctx context.Context, id string) E.Either[error, entities.ProjectTask] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
return F.Pipe2(
|
||||
O.FromNillable(ds.Store[id]),
|
||||
E.FromOption[*entities.ProjectTask](F.Constant(fmt.Errorf("project task with ID %s not found", id))),
|
||||
E.Chain(impl.TryDereference[entities.ProjectTask]),
|
||||
)
|
||||
}
|
||||
|
||||
// Update an existing ProjectTask
|
||||
func (ds *MockProjectTaskDataSource) Update(ctx context.Context, task entities.ProjectTaskUpdate) E.Either[error, entities.ProjectTask] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[task.ID]
|
||||
if !found {
|
||||
return E.Left[entities.ProjectTask](fmt.Errorf("project task with ID %s not found", task.ID))
|
||||
}
|
||||
|
||||
if task.Name != nil {
|
||||
existing.Name = *task.Name
|
||||
}
|
||||
if task.Description != nil {
|
||||
existing.Description = task.Description
|
||||
}
|
||||
if task.ProjectID != nil {
|
||||
existing.ProjectID = *task.ProjectID
|
||||
}
|
||||
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// Delete a ProjectTask
|
||||
func (ds *MockProjectTaskDataSource) Delete(ctx context.Context, id string) E.Either[error, entities.ProjectTask] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[id]
|
||||
if !found {
|
||||
return E.Left[entities.ProjectTask](fmt.Errorf("project task with ID %s not found", id))
|
||||
}
|
||||
|
||||
delete(ds.Store, id)
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// FindAll retrieves all ProjectTasks
|
||||
func (ds *MockProjectTaskDataSource) FindAll(ctx context.Context) E.Either[error, []entities.ProjectTask] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
tasks := make([]entities.ProjectTask, 0, len(ds.Store))
|
||||
for _, task := range ds.Store {
|
||||
tasks = append(tasks, *task)
|
||||
}
|
||||
|
||||
return E.Right[error](tasks)
|
||||
}
|
||||
|
||||
// FindByProjectID retrieves all ProjectTasks for a given Project
|
||||
func (ds *MockProjectTaskDataSource) FindByProjectID(ctx context.Context, projectID string) E.Either[error, []entities.ProjectTask] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
tasks := make([]entities.ProjectTask, 0)
|
||||
for _, task := range ds.Store {
|
||||
if task.ProjectID == projectID {
|
||||
tasks = append(tasks, *task)
|
||||
}
|
||||
}
|
||||
|
||||
return E.Right[error](tasks)
|
||||
}
|
||||
|
||||
func (ds *MockProjectTaskDataSource) Clear() {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
ds.Store = make(map[string]*entities.ProjectTask)
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
impl "actatempus_backend/internal/infrastructure/data"
|
||||
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
type MockTimeEntryDataSource struct {
|
||||
Store map[string]*entities.TimeEntry
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMockTimeEntryDataSource() *MockTimeEntryDataSource {
|
||||
return &MockTimeEntryDataSource{
|
||||
Store: make(map[string]*entities.TimeEntry),
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new TimeEntry
|
||||
func (ds *MockTimeEntryDataSource) Create(ctx context.Context, entry entities.TimeEntryCreate) E.Either[error, entities.TimeEntry] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
id := GenerateID()
|
||||
newEntry := entities.TimeEntry{
|
||||
ID: id,
|
||||
StartTime: entry.StartTime,
|
||||
EndTime: entry.EndTime,
|
||||
Description: entry.Description,
|
||||
UserID: entry.UserID,
|
||||
ProjectID: entry.ProjectID,
|
||||
}
|
||||
|
||||
ds.Store[id] = &newEntry
|
||||
|
||||
return E.Right[error](newEntry)
|
||||
}
|
||||
|
||||
// Find TimeEntry by ID
|
||||
func (ds *MockTimeEntryDataSource) FindByID(ctx context.Context, id string) E.Either[error, entities.TimeEntry] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
return F.Pipe2(
|
||||
O.FromNillable(ds.Store[id]),
|
||||
E.FromOption[*entities.TimeEntry](F.Constant(fmt.Errorf("time entry with ID %s not found", id))),
|
||||
E.Chain(impl.TryDereference[entities.TimeEntry]),
|
||||
)
|
||||
}
|
||||
|
||||
// Update an existing TimeEntry
|
||||
func (ds *MockTimeEntryDataSource) Update(ctx context.Context, entry entities.TimeEntryUpdate) E.Either[error, entities.TimeEntry] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[entry.ID]
|
||||
if !found {
|
||||
return E.Left[entities.TimeEntry](fmt.Errorf("time entry with ID %s not found", entry.ID))
|
||||
}
|
||||
|
||||
if entry.StartTime != nil {
|
||||
existing.StartTime = *entry.StartTime
|
||||
}
|
||||
if entry.EndTime != nil {
|
||||
existing.EndTime = entry.EndTime
|
||||
}
|
||||
if entry.Description != nil {
|
||||
existing.Description = entry.Description
|
||||
}
|
||||
if entry.UserID != nil {
|
||||
existing.UserID = *entry.UserID
|
||||
}
|
||||
if entry.ProjectID != nil {
|
||||
existing.ProjectID = *entry.ProjectID
|
||||
}
|
||||
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// Delete a TimeEntry
|
||||
func (ds *MockTimeEntryDataSource) Delete(ctx context.Context, id string) E.Either[error, entities.TimeEntry] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[id]
|
||||
if !found {
|
||||
return E.Left[entities.TimeEntry](fmt.Errorf("time entry with ID %s not found", id))
|
||||
}
|
||||
|
||||
delete(ds.Store, id)
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
// FindAll retrieves all TimeEntries
|
||||
func (ds *MockTimeEntryDataSource) FindAll(ctx context.Context) E.Either[error, []entities.TimeEntry] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
entries := make([]entities.TimeEntry, 0, len(ds.Store))
|
||||
for _, entry := range ds.Store {
|
||||
entries = append(entries, *entry)
|
||||
}
|
||||
|
||||
return E.Right[error](entries)
|
||||
}
|
||||
|
||||
// FindByUserID retrieves all TimeEntries by UserID
|
||||
func (ds *MockTimeEntryDataSource) FindByUserID(ctx context.Context, userID string) E.Either[error, []entities.TimeEntry] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
entries := make([]entities.TimeEntry, 0)
|
||||
for _, entry := range ds.Store {
|
||||
if entry.UserID == userID {
|
||||
entries = append(entries, *entry)
|
||||
}
|
||||
}
|
||||
|
||||
return E.Right[error](entries)
|
||||
}
|
||||
|
||||
// FindByProjectID retrieves all TimeEntries by ProjectID
|
||||
func (ds *MockTimeEntryDataSource) FindByProjectID(ctx context.Context, projectID string) E.Either[error, []entities.TimeEntry] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
entries := make([]entities.TimeEntry, 0)
|
||||
for _, entry := range ds.Store {
|
||||
if entry.ProjectID == projectID {
|
||||
entries = append(entries, *entry)
|
||||
}
|
||||
}
|
||||
|
||||
return E.Right[error](entries)
|
||||
}
|
||||
|
||||
func (ds *MockTimeEntryDataSource) Clear() {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
ds.Store = make(map[string]*entities.TimeEntry)
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
impl "actatempus_backend/internal/infrastructure/data"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
O "github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
type MockUserDataSource struct {
|
||||
Store map[string]*entities.User
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMockUserDataSource() *MockUserDataSource {
|
||||
return &MockUserDataSource{
|
||||
Store: make(map[string]*entities.User),
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) Create(ctx context.Context, user entities.UserCreate) E.Either[error, entities.User] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
id := GenerateID()
|
||||
newUser := entities.User{
|
||||
ID: id,
|
||||
Name: user.Name,
|
||||
Email: user.Email,
|
||||
Password: impl.GenerateSecureHash(user.Password),
|
||||
}
|
||||
|
||||
ds.Store[id] = &newUser
|
||||
|
||||
return E.Right[error](newUser)
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) FindByID(ctx context.Context, id string) E.Either[error, entities.User] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
return F.Pipe2(
|
||||
O.FromNillable(ds.Store[id]),
|
||||
E.FromOption[*entities.User](F.Constant(fmt.Errorf("user with ID %s not found", id))),
|
||||
E.Chain(
|
||||
impl.TryDereference[entities.User],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) FindByEmail(ctx context.Context, email string) E.Either[error, entities.User] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
for _, user := range ds.Store {
|
||||
if user.Email == email {
|
||||
return E.Right[error](*user)
|
||||
}
|
||||
}
|
||||
return E.Left[entities.User](fmt.Errorf("user with email %s not found", email))
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) Update(ctx context.Context, user entities.UserUpdate) E.Either[error, entities.User] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[user.ID]
|
||||
if !found {
|
||||
return E.Left[entities.User](fmt.Errorf("user with ID %s not found", user.ID))
|
||||
}
|
||||
|
||||
if user.Name != nil {
|
||||
existing.Name = *user.Name
|
||||
}
|
||||
if user.Email != nil {
|
||||
existing.Email = *user.Email
|
||||
}
|
||||
if user.Password != nil {
|
||||
existing.Password = impl.GenerateSecureHash(*user.Password)
|
||||
}
|
||||
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) Delete(ctx context.Context, id string) E.Either[error, entities.User] {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
existing, found := ds.Store[id]
|
||||
if !found {
|
||||
return E.Left[entities.User](fmt.Errorf("user with ID %s not found", id))
|
||||
}
|
||||
|
||||
delete(ds.Store, id)
|
||||
return E.Right[error](*existing)
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) FindAll(ctx context.Context) E.Either[error, []entities.User] {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
users := make([]entities.User, 0, len(ds.Store))
|
||||
for _, user := range ds.Store {
|
||||
users = append(users, *user)
|
||||
}
|
||||
|
||||
return E.Right[error](users)
|
||||
}
|
||||
|
||||
func (ds *MockUserDataSource) Clear() {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
ds.Store = make(map[string]*entities.User)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package services_test
|
||||
|
||||
// StringPtr returns a pointer to the string value passed in
|
||||
func StringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package services_test
|
||||
|
||||
import (
|
||||
"actatempus_backend/internal/application/repository"
|
||||
"actatempus_backend/internal/application/services"
|
||||
"actatempus_backend/internal/application/services/dto"
|
||||
"actatempus_backend/internal/domain/entities"
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"actatempus_backend/tests/mocks"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUserService(t *testing.T) {
|
||||
// Setup
|
||||
gin.SetMode(gin.TestMode)
|
||||
//mockAuthRepo := repository.NewInMemoryAuthRepositoryImpl("secret")
|
||||
mockAuthRepo := mocks.NewMockAuthRepository()
|
||||
userDS := mocks.NewMockUserDataSource()
|
||||
userRepo := repository.NewUserRepository(userDS)
|
||||
userService := services.NewUserService(mockAuthRepo, userRepo)
|
||||
|
||||
router := gin.Default()
|
||||
router.RedirectTrailingSlash = false
|
||||
api := router.Group("/api/users")
|
||||
userService.RegisterRoutes(api)
|
||||
|
||||
t.Run("CreateUser - Success", func(t *testing.T) {
|
||||
userCreateDTO := dto.UserCreateDTO{
|
||||
Name: "John Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Password: "password123",
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(userCreateDTO)
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/users/", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rec.Code)
|
||||
var response dto.UserDTO
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, userCreateDTO.Name, response.Name)
|
||||
assert.Equal(t, userCreateDTO.Email, response.Email)
|
||||
})
|
||||
|
||||
t.Run("GetUserByID - Success", func(t *testing.T) {
|
||||
// Prepopulate mock data
|
||||
user := entities.UserCreate{
|
||||
Name: "John Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Password: "hashed_password",
|
||||
}
|
||||
|
||||
newUser, _ := E.Unwrap(F.Pipe1(
|
||||
user,
|
||||
userRepo.Create(context.Background()),
|
||||
))
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/api/users/%s", newUser.ID), nil)
|
||||
req.Header.Set("Cookie", "session_token=fake_test_token")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
router.ServeHTTP(rec, req)
|
||||
print(rec.Body.String())
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
var response dto.UserDTO
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, user.Name, response.Name)
|
||||
assert.Equal(t, user.Email, response.Email)
|
||||
})
|
||||
|
||||
t.Run("GetAllUsers - Success", func(t *testing.T) {
|
||||
userDS.Clear()
|
||||
// Prepopulate mock data
|
||||
userRepo.Create(context.Background())(entities.UserCreate{
|
||||
Name: "John Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Password: "hashed_password",
|
||||
})
|
||||
userRepo.Create(context.Background())(entities.UserCreate{
|
||||
Name: "Jane Smith",
|
||||
Email: "jane.smith@example.com",
|
||||
Password: "hashed_password",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/users/", nil)
|
||||
req.Header.Set("Cookie", "session_token=fake_test_token")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
var response []dto.UserDTO
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, response, 2)
|
||||
})
|
||||
|
||||
t.Run("UpdateUser - Success", func(t *testing.T) {
|
||||
// Prepopulate mock data
|
||||
|
||||
newUser, _ := E.Unwrap(F.Pipe1(
|
||||
entities.UserCreate{
|
||||
Name: "John Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Password: "hashed_password",
|
||||
},
|
||||
userRepo.Create(context.Background()),
|
||||
))
|
||||
|
||||
userUpdateDTO := dto.UserUpdateDTO{
|
||||
Name: StringPtr("John Updated"),
|
||||
Email: StringPtr("john.updated@example.com"),
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(userUpdateDTO)
|
||||
req := httptest.NewRequest(http.MethodPut, fmt.Sprintf("/api/users/%s", newUser.ID), bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Cookie", "session_token=fake_test_token")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
var response dto.UserDTO
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, *userUpdateDTO.Name, response.Name)
|
||||
assert.Equal(t, *userUpdateDTO.Email, response.Email)
|
||||
})
|
||||
|
||||
t.Run("DeleteUser - Success", func(t *testing.T) {
|
||||
// Prepopulate mock data
|
||||
newUser, _ := E.Unwrap(F.Pipe1(
|
||||
entities.UserCreate{
|
||||
Name: "John Doe",
|
||||
Email: "john.doe@example.com",
|
||||
Password: "hashed_password",
|
||||
},
|
||||
userRepo.Create(context.Background()),
|
||||
))
|
||||
|
||||
req := httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/api/users/%s", newUser.ID), nil)
|
||||
req.Header.Set("Cookie", "session_token=fake_test_token")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
var response dto.UserDTO
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "John Doe", response.Name)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user