mirror of
https://github.com/Floriansylvain/RenewCMS.git
synced 2026-08-19 11:43:22 +02:00
feat: unit testing mocked repos / domain
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"RenewCMS/internal/domain/article"
|
||||||
|
"RenewCMS/internal/infrastructure/useCases"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockArticleRepo struct {
|
||||||
|
articles map[uint32]article.Article
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockArticleRepo) FindByFilters(f article.Filters) ([]article.Article, error) {
|
||||||
|
var results []article.Article
|
||||||
|
for _, a := range m.articles {
|
||||||
|
if f.IsOnline != nil && a.IsOnline == *f.IsOnline {
|
||||||
|
results = append(results, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockArticleRepo) Get(id uint32) (article.Article, error) {
|
||||||
|
a, ok := m.articles[id]
|
||||||
|
if !ok {
|
||||||
|
return article.Article{}, article.ErrArticleNotFound
|
||||||
|
}
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockArticleRepo) Create(a article.Article) (article.Article, error) {
|
||||||
|
a.ID = uint32(len(m.articles) + 1)
|
||||||
|
m.articles[a.ID] = a
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockArticleRepo) Delete(id uint32) error {
|
||||||
|
delete(m.articles, id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockArticleRepo) GetByName(n string) (article.Article, error) { return article.Article{}, nil }
|
||||||
|
func (m *mockArticleRepo) GetAll() []article.Article { return nil }
|
||||||
|
func (m *mockArticleRepo) UpdateBody(id uint32, b string) (article.Article, error) {
|
||||||
|
return article.Article{}, nil
|
||||||
|
}
|
||||||
|
func (m *mockArticleRepo) UpdateIsOnline(id uint32, o bool) (article.Article, error) {
|
||||||
|
return article.Article{}, nil
|
||||||
|
}
|
||||||
|
func (m *mockArticleRepo) AddImage(p, i uint32) error { return nil }
|
||||||
|
|
||||||
|
var _ article.Repository = &mockArticleRepo{}
|
||||||
|
|
||||||
|
func TestCreateArticle(t *testing.T) {
|
||||||
|
repo := &mockArticleRepo{articles: make(map[uint32]article.Article)}
|
||||||
|
uc := useCases.NewCreateArticleUseCase(repo)
|
||||||
|
|
||||||
|
t.Run("Valid Title", func(t *testing.T) {
|
||||||
|
cmd := useCases.CreateArticleCommand{Title: "Valid Title", Body: "Content"}
|
||||||
|
res, err := uc.CreateArticle(cmd)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if res.Title != cmd.Title {
|
||||||
|
t.Errorf("Expected %s, got %s", cmd.Title, res.Title)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Short Title", func(t *testing.T) {
|
||||||
|
cmd := useCases.CreateArticleCommand{Title: "Ab", Body: "Content"}
|
||||||
|
_, err := uc.CreateArticle(cmd)
|
||||||
|
if !errors.Is(err, article.ErrInvalidTitle) {
|
||||||
|
t.Errorf("Expected ErrInvalidTitle")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetOnlineArticle(t *testing.T) {
|
||||||
|
repo := &mockArticleRepo{articles: map[uint32]article.Article{
|
||||||
|
1: {ID: 1, IsOnline: true},
|
||||||
|
2: {ID: 2, IsOnline: false},
|
||||||
|
}}
|
||||||
|
uc := useCases.NewGetArticleUseCase(repo)
|
||||||
|
|
||||||
|
t.Run("Article Online", func(t *testing.T) {
|
||||||
|
_, err := uc.GetOnlineArticle(1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected article to be found")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Article Offline", func(t *testing.T) {
|
||||||
|
_, err := uc.GetOnlineArticle(2)
|
||||||
|
if !errors.Is(err, article.ErrArticleNotFound) {
|
||||||
|
t.Errorf("Offline article should return not found")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"RenewCMS/internal/domain/image"
|
||||||
|
"RenewCMS/internal/infrastructure/useCases"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockImageRepo struct {
|
||||||
|
images map[uint32]image.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockImageRepo) Create(input image.ImageInput) (image.Image, error) {
|
||||||
|
newId := uint32(len(m.images) + 1)
|
||||||
|
img := image.Image{
|
||||||
|
ID: newId,
|
||||||
|
Path: "/static/" + input.Filename,
|
||||||
|
}
|
||||||
|
m.images[newId] = img
|
||||||
|
return img, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockImageRepo) Delete(id uint32) error {
|
||||||
|
delete(m.images, id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ image.Repository = &mockImageRepo{}
|
||||||
|
|
||||||
|
func TestImageUseCases(t *testing.T) {
|
||||||
|
repo := &mockImageRepo{images: make(map[uint32]image.Image)}
|
||||||
|
createUc := useCases.NewCreateImageUseCase(repo)
|
||||||
|
deleteUc := useCases.NewDeleteImageUseCase(repo)
|
||||||
|
|
||||||
|
t.Run("Create Image", func(t *testing.T) {
|
||||||
|
input := image.ImageInput{
|
||||||
|
Content: strings.NewReader("fake-image-data"),
|
||||||
|
Filename: "test.png",
|
||||||
|
ContentType: "image/png",
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := createUc.CreateImage(input)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreateImage failed: %v", err)
|
||||||
|
}
|
||||||
|
if res.ID == 0 {
|
||||||
|
t.Errorf("Expected valid ID, got 0")
|
||||||
|
}
|
||||||
|
if !strings.Contains(res.Path, "test.png") {
|
||||||
|
t.Errorf("Path mismatch: %s", res.Path)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Delete Image", func(t *testing.T) {
|
||||||
|
repo.images[99] = image.Image{ID: 99, Path: "/static/delete-me.png"}
|
||||||
|
|
||||||
|
err := deleteUc.DeleteImage(99)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("DeleteImage failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := repo.images[99]; exists {
|
||||||
|
t.Errorf("Image 99 should have been deleted")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"RenewCMS/internal/domain/mail"
|
||||||
|
"RenewCMS/internal/infrastructure/useCases"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockMailRepo struct {
|
||||||
|
SentEmails []struct {
|
||||||
|
Address string
|
||||||
|
Template string
|
||||||
|
Data any
|
||||||
|
}
|
||||||
|
ShouldFail bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockMailRepo) Send(receiverAddress string, templateName string, data any) error {
|
||||||
|
if m.ShouldFail {
|
||||||
|
return errors.New("smtp error")
|
||||||
|
}
|
||||||
|
m.SentEmails = append(m.SentEmails, struct {
|
||||||
|
Address string
|
||||||
|
Template string
|
||||||
|
Data any
|
||||||
|
}{receiverAddress, templateName, data})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ mail.Repository = &mockMailRepo{}
|
||||||
|
|
||||||
|
func TestSendMail(t *testing.T) {
|
||||||
|
repo := &mockMailRepo{}
|
||||||
|
uc := useCases.NewSendMailUseCase(repo)
|
||||||
|
|
||||||
|
t.Run("Successful Email Send", func(t *testing.T) {
|
||||||
|
repo.ShouldFail = false
|
||||||
|
err := uc.SendMail("user@example.com", "welcome", "User123")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
if len(repo.SentEmails) != 1 {
|
||||||
|
t.Errorf("Expected 1 email to be sent, got %d", len(repo.SentEmails))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Failed Email Send", func(t *testing.T) {
|
||||||
|
repo.ShouldFail = true
|
||||||
|
err := uc.SendMail("fail@example.com", "reset", nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected an error but got nil")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"RenewCMS/internal/domain/user"
|
||||||
|
"RenewCMS/internal/infrastructure/useCases"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockUserRepo struct {
|
||||||
|
users map[uint32]user.User
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUserRepo) Create(u user.User) (user.User, error) {
|
||||||
|
u.ID = uint32(len(m.users) + 1)
|
||||||
|
m.users[u.ID] = u
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUserRepo) Get(id uint32) (user.User, error) {
|
||||||
|
u, ok := m.users[id]
|
||||||
|
if !ok {
|
||||||
|
return user.User{}, nil
|
||||||
|
}
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUserRepo) GetAll() []user.User {
|
||||||
|
var list []user.User
|
||||||
|
for _, u := range m.users {
|
||||||
|
list = append(list, u)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUserRepo) UpdateVerificationStatus(id uint32, v bool) (user.User, error) {
|
||||||
|
u := m.users[id]
|
||||||
|
u.IsVerified = v
|
||||||
|
m.users[id] = u
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockUserRepo) GetByUsername(n string) (user.User, error) { return user.User{}, nil }
|
||||||
|
func (m *mockUserRepo) GetByEmail(e string) (user.User, error) { return user.User{}, nil }
|
||||||
|
func (m *mockUserRepo) Delete(id uint32) error { return nil }
|
||||||
|
func (m *mockUserRepo) UpdatePassword(id uint32, p string) (user.User, error) {
|
||||||
|
return user.User{}, nil
|
||||||
|
}
|
||||||
|
func (m *mockUserRepo) UpdatePasswordResetCode(id uint32, c string) (user.User, error) {
|
||||||
|
return user.User{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ user.Repository = &mockUserRepo{}
|
||||||
|
|
||||||
|
func TestCreateUser(t *testing.T) {
|
||||||
|
repo := &mockUserRepo{users: make(map[uint32]user.User)}
|
||||||
|
uc := useCases.NewCreateUserUseCase(repo)
|
||||||
|
|
||||||
|
cmd := useCases.CreateUserCommand{
|
||||||
|
Username: "testuser",
|
||||||
|
Password: "password123",
|
||||||
|
Email: "test@example.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := uc.CreateUser(cmd)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("User creation failed: %v", err)
|
||||||
|
}
|
||||||
|
if res.Username != cmd.Username {
|
||||||
|
t.Errorf("Username mismatch")
|
||||||
|
}
|
||||||
|
if res.VerificationCode == "" {
|
||||||
|
t.Errorf("Verification code was not generated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateUserVerification(t *testing.T) {
|
||||||
|
repo := &mockUserRepo{users: map[uint32]user.User{
|
||||||
|
1: {ID: 1, IsVerified: false},
|
||||||
|
}}
|
||||||
|
uc := useCases.NewUpdateUserUseCase(repo)
|
||||||
|
|
||||||
|
res, err := uc.UpdateVerificationStatus(1, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Update failed: %v", err)
|
||||||
|
}
|
||||||
|
if !res.IsVerified {
|
||||||
|
t.Errorf("User should be verified")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user