places_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package services
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/models"
  7. )
  8. // mockPlaceRepo реализует интерфейс репозитория мест для тестов
  9. type mockPlaceRepo struct {
  10. places []*models.Place
  11. }
  12. func (m *mockPlaceRepo) Create(ctx context.Context, place *models.Place) error {
  13. m.places = append(m.places, place)
  14. return nil
  15. }
  16. func (m *mockPlaceRepo) GetByID(ctx context.Context, id string) (*models.Place, error) {
  17. for _, p := range m.places {
  18. if p.ID == id {
  19. return p, nil
  20. }
  21. }
  22. return nil, nil
  23. }
  24. func (m *mockPlaceRepo) List(ctx context.Context, filter models.PlaceFilter) ([]*models.Place, error) {
  25. return m.places, nil
  26. }
  27. func (m *mockPlaceRepo) Update(ctx context.Context, place *models.Place) error {
  28. for i, p := range m.places {
  29. if p.ID == place.ID {
  30. m.places[i] = place
  31. return nil
  32. }
  33. }
  34. return nil
  35. }
  36. func (m *mockPlaceRepo) UpdateStatus(ctx context.Context, id, status, comment string) error {
  37. for _, p := range m.places {
  38. if p.ID == id {
  39. p.Status = status
  40. return nil
  41. }
  42. }
  43. return nil
  44. }
  45. func (m *mockPlaceRepo) SoftDelete(ctx context.Context, id string) error {
  46. return nil
  47. }
  48. func (m *mockPlaceRepo) GetTags(ctx context.Context, placeID string) ([]models.Tag, error) {
  49. return nil, nil
  50. }
  51. func (m *mockPlaceRepo) GetFeatures(ctx context.Context, placeID string) ([]models.Feature, error) {
  52. return nil, nil
  53. }
  54. func (m *mockPlaceRepo) SetTags(ctx context.Context, placeID string, tagIDs []string) error {
  55. return nil
  56. }
  57. func (m *mockPlaceRepo) SetFeatures(ctx context.Context, placeID string, featureIDs []string) error {
  58. return nil
  59. }
  60. func TestPlaceService_Create(t *testing.T) {
  61. repo := &mockPlaceRepo{}
  62. svc := NewPlaceService(repo)
  63. input := CreatePlaceInput{
  64. OwnerID: "owner-1",
  65. Type: "studio",
  66. Title: "Test Studio",
  67. }
  68. place, err := svc.Create(context.Background(), input)
  69. if err != nil {
  70. t.Fatalf("unexpected error: %v", err)
  71. }
  72. if place.Title != "Test Studio" {
  73. t.Errorf("expected title 'Test Studio', got '%s'", place.Title)
  74. }
  75. if place.Status != "pending_moderation" {
  76. t.Errorf("new place should be pending_moderation, got '%s'", place.Status)
  77. }
  78. }
  79. func TestPlaceService_Update_NotOwner(t *testing.T) {
  80. repo := &mockPlaceRepo{}
  81. svc := NewPlaceService(repo)
  82. repo.places = append(repo.places, &models.Place{
  83. ID: "place-1",
  84. OwnerID: "owner-1",
  85. Title: "Original",
  86. })
  87. input := UpdatePlaceInput{
  88. ID: "place-1",
  89. OwnerID: "owner-2",
  90. Title: strPtr("Hacked"),
  91. }
  92. _, err := svc.Update(context.Background(), input, false)
  93. if err == nil {
  94. t.Fatal("expected error for non-owner update, got nil")
  95. }
  96. if !errors.Is(err, ErrNotYourPlace) {
  97. t.Errorf("expected ErrNotYourPlace, got %v", err)
  98. }
  99. }
  100. func TestPlaceService_Moderate_UnknownAction(t *testing.T) {
  101. repo := &mockPlaceRepo{}
  102. svc := NewPlaceService(repo)
  103. err := svc.Moderate(context.Background(), "place-1", "burn", "", "mod-1")
  104. if err == nil {
  105. t.Fatal("expected error for unknown action, got nil")
  106. }
  107. }
  108. func strPtr(s string) *string {
  109. if s == "" {
  110. return nil
  111. }
  112. return &s
  113. }