104 lines
3.4 KiB
Go
104 lines
3.4 KiB
Go
package publish_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"supply-intelligence/internal/domain"
|
|
"supply-intelligence/internal/publish"
|
|
)
|
|
|
|
type txCaptureRepo struct {
|
|
candidate domain.DiscoveryCandidate
|
|
pkg domain.SupplyPackage
|
|
event domain.PackageChangeEvent
|
|
|
|
publishCalled bool
|
|
}
|
|
|
|
func (r *txCaptureRepo) AppendPackageEventContext(ctx context.Context, evt domain.PackageChangeEvent) (domain.PackageChangeEvent, error) {
|
|
panic("AppendPackageEventContext should not be called directly when publish transaction is supported")
|
|
}
|
|
|
|
func (r *txCaptureRepo) GetLatestDiscoveryCandidateContext(ctx context.Context, platform, model string) (domain.DiscoveryCandidate, bool) {
|
|
return r.candidate, r.candidate.Platform == platform && r.candidate.Model == model
|
|
}
|
|
|
|
func (r *txCaptureRepo) UpdateCandidateStatus(ctx context.Context, candidateID string, status domain.DiscoveryCandidateStatus, failureCode, failureSummary string) error {
|
|
panic("UpdateCandidateStatus should not be called directly when publish transaction is supported")
|
|
}
|
|
|
|
func (r *txCaptureRepo) GetSupplyPackage(ctx context.Context, platform, model string) (domain.SupplyPackage, bool) {
|
|
return r.pkg, r.pkg.Platform == platform && r.pkg.Model == model
|
|
}
|
|
|
|
func (r *txCaptureRepo) UpsertSupplyPackage(ctx context.Context, pkg domain.SupplyPackage) error {
|
|
panic("UpsertSupplyPackage should not be called directly when publish transaction is supported")
|
|
}
|
|
|
|
func (r *txCaptureRepo) PublishPackageAtomically(ctx context.Context, input publish.PublishPackageAtomicInput) (publish.PublishPackageAtomicResult, error) {
|
|
r.publishCalled = true
|
|
r.event = input.Event
|
|
r.candidate = input.Candidate
|
|
r.pkg = input.Package
|
|
return publish.PublishPackageAtomicResult{
|
|
Candidate: input.Candidate,
|
|
Package: input.Package,
|
|
Event: input.Event,
|
|
}, nil
|
|
}
|
|
|
|
func TestServicePublishDraftUsesAtomicPublisherWhenAvailable(t *testing.T) {
|
|
repo := &txCaptureRepo{
|
|
candidate: domain.DiscoveryCandidate{
|
|
CandidateID: "cand-atomic",
|
|
AccountID: 9001,
|
|
Platform: "openai",
|
|
Model: "gpt-4.1-mini",
|
|
Source: "admission",
|
|
Status: domain.DiscoveryCandidateStatusTestPassed,
|
|
DiscoveredAt: time.Unix(100, 0).UTC(),
|
|
UpdatedAt: time.Unix(110, 0).UTC(),
|
|
Version: 2,
|
|
},
|
|
pkg: domain.SupplyPackage{
|
|
PackageID: 88,
|
|
Platform: "openai",
|
|
Model: "gpt-4.1-mini",
|
|
Status: "draft",
|
|
Source: "admission",
|
|
CreatedAt: time.Unix(90, 0).UTC(),
|
|
UpdatedAt: time.Unix(110, 0).UTC(),
|
|
Version: 5,
|
|
},
|
|
}
|
|
service := publish.NewService(repo)
|
|
now := time.Unix(200, 0).UTC()
|
|
|
|
out, err := service.PublishDraft(context.Background(), publish.PublishDraftInput{
|
|
EventID: "evt-atomic-1",
|
|
Platform: "openai",
|
|
Model: "gpt-4.1-mini",
|
|
OccurredAt: now,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if !repo.publishCalled {
|
|
t.Fatal("expected atomic publish path to be used")
|
|
}
|
|
if out.Candidate.Status != domain.DiscoveryCandidateStatusPublished {
|
|
t.Fatalf("expected published candidate, got %+v", out.Candidate)
|
|
}
|
|
if out.Package.Status != "active" {
|
|
t.Fatalf("expected active package, got %+v", out.Package)
|
|
}
|
|
if out.Event.EventID != "evt-atomic-1" || out.Event.GatewaySyncStatus != domain.GatewaySyncStatusPending {
|
|
t.Fatalf("unexpected event: %+v", out.Event)
|
|
}
|
|
if out.Package.Version != 6 {
|
|
t.Fatalf("expected package version incremented, got %+v", out.Package)
|
|
}
|
|
}
|