package services import ( "context" "errors" "testing" "gogs.fxtmmsk.ru/foxtime/photoplaces/backend/internal/models" ) // mockPlaceRepo реализует интерфейс репозитория мест для тестов type mockPlaceRepo struct { places []*models.Place } func (m *mockPlaceRepo) Create(ctx context.Context, place *models.Place) error { m.places = append(m.places, place) return nil } func (m *mockPlaceRepo) GetByID(ctx context.Context, id string) (*models.Place, error) { for _, p := range m.places { if p.ID == id { return p, nil } } return nil, nil } func (m *mockPlaceRepo) List(ctx context.Context, filter models.PlaceFilter) ([]*models.Place, error) { return m.places, nil } func (m *mockPlaceRepo) Update(ctx context.Context, place *models.Place) error { for i, p := range m.places { if p.ID == place.ID { m.places[i] = place return nil } } return nil } func (m *mockPlaceRepo) UpdateStatus(ctx context.Context, id, status, comment string) error { for _, p := range m.places { if p.ID == id { p.Status = status return nil } } return nil } func (m *mockPlaceRepo) SoftDelete(ctx context.Context, id string) error { return nil } func (m *mockPlaceRepo) GetTags(ctx context.Context, placeID string) ([]models.Tag, error) { return nil, nil } func (m *mockPlaceRepo) GetFeatures(ctx context.Context, placeID string) ([]models.Feature, error) { return nil, nil } func (m *mockPlaceRepo) SetTags(ctx context.Context, placeID string, tags []models.Tag) error { return nil } func (m *mockPlaceRepo) SetFeatures(ctx context.Context, placeID string, features []models.Feature) error { return nil } func (m *mockPlaceRepo) GetTagsBatch(ctx context.Context, placeIDs []string) (map[string][]models.Tag, error) { return nil, nil } func (m *mockPlaceRepo) GetFeaturesBatch(ctx context.Context, placeIDs []string) (map[string][]models.Feature, error) { return nil, nil } func TestPlaceService_Create(t *testing.T) { repo := &mockPlaceRepo{} svc := NewPlaceService(repo) input := CreatePlaceInput{ OwnerID: "owner-1", Type: "studio", Title: "Test Studio", } place, err := svc.Create(context.Background(), input) if err != nil { t.Fatalf("unexpected error: %v", err) } if place.Title != "Test Studio" { t.Errorf("expected title 'Test Studio', got '%s'", place.Title) } if place.Status != "pending_moderation" { t.Errorf("new place should be pending_moderation, got '%s'", place.Status) } } func TestPlaceService_Update_NotOwner(t *testing.T) { repo := &mockPlaceRepo{} svc := NewPlaceService(repo) repo.places = append(repo.places, &models.Place{ ID: "place-1", OwnerID: "owner-1", Title: "Original", }) input := UpdatePlaceInput{ ID: "place-1", OwnerID: "owner-2", Title: strPtr("Hacked"), } _, err := svc.Update(context.Background(), input, false) if err == nil { t.Fatal("expected error for non-owner update, got nil") } if !errors.Is(err, ErrNotYourPlace) { t.Errorf("expected ErrNotYourPlace, got %v", err) } } func TestPlaceService_Moderate_UnknownAction(t *testing.T) { repo := &mockPlaceRepo{} svc := NewPlaceService(repo) err := svc.Moderate(context.Background(), "place-1", "burn", "", "mod-1") if err == nil { t.Fatal("expected error for unknown action, got nil") } } func strPtr(s string) *string { if s == "" { return nil } return &s }