diff options
Diffstat (limited to 'app/db')
| -rw-r--r-- | app/db/in_memory_repository.go | 14 | ||||
| -rw-r--r-- | app/db/in_memory_repository_test.go | 25 | ||||
| -rw-r--r-- | app/db/publishing_repository.go | 36 | ||||
| -rw-r--r-- | app/db/publishing_repository_test.go | 35 |
4 files changed, 79 insertions, 31 deletions
diff --git a/app/db/in_memory_repository.go b/app/db/in_memory_repository.go index 1177662..2aa1fed 100644 --- a/app/db/in_memory_repository.go +++ b/app/db/in_memory_repository.go @@ -5,23 +5,20 @@ import ( "sort" "sync" - "github.com/xlgmokha/x/pkg/event" "github.com/xlgmokha/x/pkg/x" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/pls" ) type inMemoryRepository[T domain.Entity] struct { - aggregator *event.TypedAggregator[T] - items []T - mu sync.RWMutex + items []T + mu sync.RWMutex } -func NewRepository[T domain.Entity](aggregator *event.TypedAggregator[T]) domain.Repository[T] { +func NewRepository[T domain.Entity]() domain.Repository[T] { return &inMemoryRepository[T]{ - aggregator: aggregator, - items: []T{}, - mu: sync.RWMutex{}, + items: []T{}, + mu: sync.RWMutex{}, } } @@ -53,6 +50,5 @@ func (r *inMemoryRepository[T]) Save(ctx context.Context, item T) error { sort.Slice(r.items, func(i, j int) bool { return r.items[i].GetID() > r.items[j].GetID() }) - r.aggregator.Publish("after.create", item) return nil } diff --git a/app/db/in_memory_repository_test.go b/app/db/in_memory_repository_test.go index 5bb220e..b89f16a 100644 --- a/app/db/in_memory_repository_test.go +++ b/app/db/in_memory_repository_test.go @@ -7,14 +7,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/xlgmokha/x/pkg/event" "github.com/xlgmokha/x/pkg/x" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain" ) func TestInMemoryRepository(t *testing.T) { - aggregator := event.New[*domain.Sparkle]() - storage := NewRepository[*domain.Sparkle](aggregator) + storage := NewRepository[*domain.Sparkle]() t.Run("Save", func(t *testing.T) { t.Run("an invalid Sparkle", func(t *testing.T) { @@ -33,25 +31,8 @@ func TestInMemoryRepository(t *testing.T) { assert.Equal(t, "because", sparkles[0].Reason) }) - t.Run("publishes an event", func(t *testing.T) { - called := false - var payload *domain.Sparkle - - aggregator.SubscribeTo("after.create", func(item *domain.Sparkle) { - called = true - payload = item - }) - - sparkle := &domain.Sparkle{Sparklee: "@tanuki", Reason: "because"} - require.NoError(t, storage.Save(t.Context(), sparkle)) - - require.True(t, called) - require.NotNil(t, payload) - assert.Equal(t, sparkle, payload) - }) - t.Run("prevents race conditions", func(t *testing.T) { - repository := NewRepository[*domain.Sparkle](aggregator) + repository := NewRepository[*domain.Sparkle]() ctx := context.Background() numGoroutines := 100 @@ -112,7 +93,7 @@ func TestInMemoryRepository(t *testing.T) { }) t.Run("All", func(t *testing.T) { - repository := NewRepository[*domain.Sparkle](aggregator) + repository := NewRepository[*domain.Sparkle]() require.NoError(t, repository.Save(t.Context(), &domain.Sparkle{ Sparklee: "@tanuki", Reason: "because", diff --git a/app/db/publishing_repository.go b/app/db/publishing_repository.go new file mode 100644 index 0000000..6be8cf8 --- /dev/null +++ b/app/db/publishing_repository.go @@ -0,0 +1,36 @@ +package db + +import ( + "context" + + "github.com/xlgmokha/x/pkg/event" + "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain" +) + +type PublishingRepository[T domain.Entity] struct { + aggregator *event.TypedAggregator[T] + repository domain.Repository[T] +} + +func NewPublishingRepository[T domain.Entity](aggregator *event.TypedAggregator[T], repository domain.Repository[T]) domain.Repository[T] { + return &PublishingRepository[T]{ + aggregator: aggregator, + repository: repository, + } +} + +func (r *PublishingRepository[T]) All(ctx context.Context) []T { + return r.repository.All(ctx) +} + +func (r *PublishingRepository[T]) Find(ctx context.Context, id domain.ID) T { + return r.repository.Find(ctx, id) +} + +func (r *PublishingRepository[T]) Save(ctx context.Context, item T) error { + err := r.repository.Save(ctx, item) + if err == nil { + r.aggregator.Publish("after.create", item) + } + return err +} diff --git a/app/db/publishing_repository_test.go b/app/db/publishing_repository_test.go new file mode 100644 index 0000000..7bbc999 --- /dev/null +++ b/app/db/publishing_repository_test.go @@ -0,0 +1,35 @@ +package db + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/xlgmokha/x/pkg/event" + "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/domain" +) + +func TestPublishingRepository(t *testing.T) { + aggregator := event.New[*domain.Sparkle]() + repository := NewRepository[*domain.Sparkle]() + storage := NewPublishingRepository[*domain.Sparkle](aggregator, repository) + + t.Run("Save", func(t *testing.T) { + t.Run("publishes an event", func(t *testing.T) { + called := false + var payload *domain.Sparkle + + aggregator.SubscribeTo("after.create", func(item *domain.Sparkle) { + called = true + payload = item + }) + + sparkle := &domain.Sparkle{Sparklee: "@tanuki", Reason: "because"} + require.NoError(t, storage.Save(t.Context(), sparkle)) + + require.True(t, called) + require.NotNil(t, payload) + assert.Equal(t, sparkle, payload) + }) + }) +} |
