✨ Enhance NATS configuration and error handling. Introduce stream limits and consumer rules in configuration files. Refactor message processing to handle permanent errors. Update README and development configuration to reflect changes. Add tests for new error handling mechanisms.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"caatsm/internal/adapter"
|
||||
"caatsm/internal/adapter/parser"
|
||||
"caatsm/internal/domain"
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type stubParser struct {
|
||||
value *domain.ParsedMessage
|
||||
}
|
||||
|
||||
func (s *stubParser) Parse(rawText string) *domain.ParsedMessage {
|
||||
return s.value
|
||||
}
|
||||
|
||||
type stubRepository struct {
|
||||
inserted []*domain.ParsedMessage
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *stubRepository) InsertOne(ctx context.Context, msg *domain.ParsedMessage) error {
|
||||
if s.err != nil {
|
||||
return s.err
|
||||
}
|
||||
s.inserted = append(s.inserted, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stubRepository) InsertBatch(ctx context.Context, msgs []*domain.ParsedMessage) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
type stubPublisher struct {
|
||||
last interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *stubPublisher) Publish(message interface{}) error {
|
||||
s.last = message
|
||||
return s.err
|
||||
}
|
||||
|
||||
func newTestProcessor(p parser.Parser, repo adapter.Repository, pub adapter.Publisher) *MessageProcessor {
|
||||
return NewMessageProcessor(p, repo, pub, zap.NewNop())
|
||||
}
|
||||
|
||||
func TestHandleEmptyMessageIsPermanent(t *testing.T) {
|
||||
proc := newTestProcessor(&stubParser{}, &stubRepository{}, &stubPublisher{})
|
||||
err := proc.Handle(context.Background(), nil, "id-1")
|
||||
if err == nil || !IsPermanent(err) {
|
||||
t.Fatalf("expected permanent error for empty message, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleNilParserResultIsPermanent(t *testing.T) {
|
||||
proc := newTestProcessor(&stubParser{value: nil}, &stubRepository{}, &stubPublisher{})
|
||||
err := proc.Handle(context.Background(), []byte("payload"), "id-2")
|
||||
if err == nil || !IsPermanent(err) {
|
||||
t.Fatalf("expected permanent error for nil parser result, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleSuccessSetsUuidAndPublishes(t *testing.T) {
|
||||
parsed := domain.NewParsedMessage()
|
||||
parsed.Parsed = true
|
||||
|
||||
repo := &stubRepository{}
|
||||
pub := &stubPublisher{}
|
||||
proc := newTestProcessor(&stubParser{value: parsed}, repo, pub)
|
||||
|
||||
const msgID = "uuid-123"
|
||||
err := proc.Handle(context.Background(), []byte("payload"), msgID)
|
||||
if err != nil {
|
||||
t.Fatalf("expected success, got %v", err)
|
||||
}
|
||||
|
||||
if len(repo.inserted) != 1 {
|
||||
t.Fatalf("expected one inserted message, got %d", len(repo.inserted))
|
||||
}
|
||||
if repo.inserted[0].Uuid != msgID {
|
||||
t.Fatalf("expected message uuid to be %s, got %s", msgID, repo.inserted[0].Uuid)
|
||||
}
|
||||
if pub.last == nil {
|
||||
t.Fatalf("expected publisher to receive message")
|
||||
}
|
||||
if pub.last != repo.inserted[0] {
|
||||
t.Fatalf("publisher received unexpected message pointer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlePublisherErrorIsRetriable(t *testing.T) {
|
||||
parsed := domain.NewParsedMessage()
|
||||
parsed.Parsed = true
|
||||
|
||||
repo := &stubRepository{}
|
||||
pub := &stubPublisher{err: errors.New("publish failed")}
|
||||
proc := newTestProcessor(&stubParser{value: parsed}, repo, pub)
|
||||
|
||||
err := proc.Handle(context.Background(), []byte("payload"), "id-3")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error when publisher fails")
|
||||
}
|
||||
if IsPermanent(err) {
|
||||
t.Fatalf("publisher failure should not be permanent")
|
||||
}
|
||||
if len(repo.inserted) != 1 {
|
||||
t.Fatalf("expected message to insert before publish failure")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user