61 lines
2.7 KiB
Go
61 lines
2.7 KiB
Go
package settlement
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"gl/domain/ledger"
|
|
)
|
|
|
|
type memoryRepository struct{ record ledger.Settlement }
|
|
|
|
func (m *memoryRepository) ClaimDue(context.Context, string, int, time.Time) ([]ledger.Settlement, error) {
|
|
return []ledger.Settlement{m.record}, nil
|
|
}
|
|
func (m *memoryRepository) Save(_ context.Context, record ledger.Settlement, _ string) error {
|
|
m.record = record
|
|
return nil
|
|
}
|
|
|
|
type submitter struct {
|
|
hash string
|
|
err error
|
|
}
|
|
|
|
func (s submitter) Submit(context.Context, ledger.Settlement) (string, error) { return s.hash, s.err }
|
|
|
|
func TestWorkerPersistsSubmission(t *testing.T) {
|
|
repository := &memoryRepository{record: ledger.Settlement{ID: "s1", SourceService: "wallet", SourceTxID: "42", IdempotencyKey: "kuknos:42", Status: ledger.SettlementPending, AvailableAt: time.Unix(1, 0)}}
|
|
worker := Worker{Repository: repository, Submitter: submitter{hash: "hash-42"}, WorkerID: "worker-1", Now: func() time.Time { return time.Unix(2, 0) }}
|
|
if err := worker.RunOnce(context.Background(), 1); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if repository.record.Status != ledger.SettlementConfirmed || repository.record.TransactionHash != "hash-42" || repository.record.Attempts != 1 {
|
|
t.Fatalf("unexpected settlement: %+v", repository.record)
|
|
}
|
|
}
|
|
|
|
func TestWorkerSchedulesRetryAfterFirstFailedAttempt(t *testing.T) {
|
|
repository := &memoryRepository{record: ledger.Settlement{ID: "s1", SourceService: "wallet", SourceTxID: "42", IdempotencyKey: "kuknos:42", Status: ledger.SettlementPending, AvailableAt: time.Unix(1, 0)}}
|
|
worker := Worker{Repository: repository, Submitter: submitter{err: errors.New("timeout")}, WorkerID: "worker-1", MaxAttempts: 3, Now: func() time.Time { return time.Unix(2, 0) }}
|
|
if err := worker.RunOnce(context.Background(), 1); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if repository.record.Status != ledger.SettlementRetryable || repository.record.Attempts != 1 || !repository.record.AvailableAt.Equal(time.Unix(3, 0)) {
|
|
t.Fatalf("unexpected settlement: %+v", repository.record)
|
|
}
|
|
}
|
|
|
|
func TestWorkerMovesExhaustedSubmissionToManualReview(t *testing.T) {
|
|
repository := &memoryRepository{record: ledger.Settlement{ID: "s1", SourceService: "wallet", SourceTxID: "42", IdempotencyKey: "kuknos:42", Status: ledger.SettlementRetryable, Attempts: 2, AvailableAt: time.Unix(1, 0)}}
|
|
worker := Worker{Repository: repository, Submitter: submitter{err: errors.New("timeout")}, WorkerID: "worker-1", MaxAttempts: 3, Now: func() time.Time { return time.Unix(2, 0) }}
|
|
if err := worker.RunOnce(context.Background(), 1); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if repository.record.Status != ledger.SettlementManualReview {
|
|
t.Fatalf("status=%s", repository.record.Status)
|
|
}
|
|
}
|