diff options
| author | mihna123 <mihailonvojinovic@gmail.com> | 2026-08-23 17:47:16 +0200 |
|---|---|---|
| committer | mihna123 <mihailonvojinovic@gmail.com> | 2026-08-23 17:47:16 +0200 |
| commit | 1e43f2a59bba0462494066767fac140601791718 (patch) | |
| tree | 45a4d0c4f3159f4acd7949eebbbfe138e4c1bc3f /internal | |
| parent | 516ed55e09a253255e7056d31eb59acfd68db3a8 (diff) | |
| download | openstore-1e43f2a59bba0462494066767fac140601791718.tar.gz openstore-1e43f2a59bba0462494066767fac140601791718.zip | |
listing: implement a service layer stub along with tests
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/listing/mock_test.go | 89 | ||||
| -rw-r--r-- | internal/listing/service.go | 36 | ||||
| -rw-r--r-- | internal/listing/service_test.go | 89 |
3 files changed, 214 insertions, 0 deletions
diff --git a/internal/listing/mock_test.go b/internal/listing/mock_test.go new file mode 100644 index 0000000..5aa6d68 --- /dev/null +++ b/internal/listing/mock_test.go @@ -0,0 +1,89 @@ +package listing + +import "time" + +type RepositoryMock struct { + listings []Listing + err error +} + +func (r *RepositoryMock) GetAll() ([]Listing, error) { + if r.err != nil { + return nil, r.err + } + + return r.listings, nil +} + +func (r *RepositoryMock) GetByCategory(c string) ([]Listing, error) { + if r.err != nil { + return nil, r.err + } + + var res []Listing + for _, l := range r.listings { + for _, cat := range l.category { + if cat == c { + res = append(res, l) + break + } + } + } + + return res, nil +} + +func NewRepositoryMock() *RepositoryMock { + mockListings := []Listing{ + { + id: 0, + title: "Audi a5 2.0 2015 godiste", + slug: "audi-a5-2-0-2015-godiste", + location: Location{city: "Novi Sad", street: "Bulevar Cara Lazara", premise: "3"}, + status: PublishedStatus, + category: []string{"automobile", "audi", "a5"}, + price: 5000, + currency: "EUR", + description: "Pali odma ide lepo", + images: []string{}, + views: 10, + createdAt: time.Now(), + author: nil, + isExternal: false, + }, + { + id: 1, + title: "Led lampa za glavu TJ-1608", + slug: "led-lampa-za-glavu-tj-1608", + location: Location{city: "Belgrade"}, + status: PublishedStatus, + category: []string{"hunting", "hunting-lamps"}, + price: 1200, + currency: "RSD", + description: "Odlična lampa, svetli super", + images: []string{}, + views: 21, + createdAt: time.Now(), + author: nil, + isExternal: false, + }, + { + id: 2, + title: "Školski anatomski ranac Minnie Mouse metalik", + slug: "skolski-anatomski-ranac-minnie-mouse-metalik", + location: Location{city: "Mladenovac"}, + status: PublishedStatus, + category: []string{"school", "backpacks"}, + price: 3400, + currency: "RSD", + description: "Minnie ranac mnogo lep za devojčice", + images: []string{}, + views: 131, + createdAt: time.Now(), + author: nil, + isExternal: false, + }, + } + + return &RepositoryMock{listings: mockListings} +} diff --git a/internal/listing/service.go b/internal/listing/service.go new file mode 100644 index 0000000..302628b --- /dev/null +++ b/internal/listing/service.go @@ -0,0 +1,36 @@ +package listing + +import "log/slog" + +type Repository interface { + GetAll() ([]Listing, error) + GetByCategory(category string) ([]Listing, error) +} + +type Service struct { + repository Repository +} + +func New(r Repository) *Service { + return &Service{repository: r} +} + +func (s *Service) GetAll() ([]Listing, error) { + listings, err := s.repository.GetAll() + if err != nil { + slog.Error("listing service", "error", err) + return nil, err + } + + return listings, nil +} + +func (s *Service) GetByCategory(c string) ([]Listing, error) { + listings, err := s.repository.GetByCategory(c) + if err != nil { + slog.Error("listing service", "error", err) + return nil, err + } + + return listings, nil +} diff --git a/internal/listing/service_test.go b/internal/listing/service_test.go new file mode 100644 index 0000000..1d555c9 --- /dev/null +++ b/internal/listing/service_test.go @@ -0,0 +1,89 @@ +package listing + +import ( + "errors" + "log/slog" + "os" + "slices" + "testing" +) + +func TestMain(m *testing.M) { + slog.SetDefault(slog.New(slog.DiscardHandler)) + os.Exit(m.Run()) +} + +func TestGetAll(t *testing.T) { + mock := NewRepositoryMock() + s := New(mock) + listings, err := s.GetAll() + if err != nil { + t.Error(err.Error()) + } + + if len(listings) != 3 { + t.Errorf("Listings lengths don't match. Have %d, want 3", + len(listings)) + } +} + +func TestGetAllWithError(t *testing.T) { + mock := &RepositoryMock{err: errors.New("db exploded")} + s := New(mock) + listings, err := s.GetAll() + + if err == nil { + t.Error("No error returned from faulty GetAll call") + } + + if listings != nil { + t.Error("Listings not nil when returned from faulty GetAll call") + } +} + +func TestGetByCategory(t *testing.T) { + mock := NewRepositoryMock() + s := New(mock) + + listings, err := s.GetByCategory("audi") + if err != nil { + t.Error(err.Error()) + } + + if len(listings) != 1 { + t.Errorf("Listings by category have wrong length. Have %d, want %d", + len(listings), 1) + } + if !slices.Contains(listings[0].category, "audi") { + t.Errorf("Returned listing has wrong category. Have %s, want audi", + listings[0].category) + } +} + +func TestGetByCategoryNoMatches(t *testing.T) { + mock := &RepositoryMock{} + s := New(mock) + + listings, err := s.GetByCategory("nonexistantcategory") + if err != nil { + t.Error(err.Error()) + } + + if listings != nil { + t.Error("Listings should be nil if no category matches") + } +} + +func TestGetByCategoryWithError(t *testing.T) { + mock := &RepositoryMock{err: errors.New("datacenter hit by asteroid")} + s := New(mock) + + listings, err := s.GetByCategory("mercedes") + if err == nil { + t.Error("Error nil when GetByCategory failed") + } + + if listings != nil { + t.Error("Listings not nil when GetByCategory failed") + } +} |
