Updated transaction routers, removed receipts router

This commit is contained in:
2026-05-09 12:04:20 +03:00
parent 2dc8ff01b7
commit a57f918d23
22 changed files with 1376 additions and 752 deletions
@@ -0,0 +1,161 @@
package services
import (
"FamilyHub/src/domain"
"context"
"errors"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type transactionServiceCreateMock struct {
createFn func(ctx context.Context, req domain.CreateTransactionRequest) (*domain.Transaction, error)
getByIDFn func(ctx context.Context, id int64) (*domain.Transaction, error)
}
func (m *transactionServiceCreateMock) Create(ctx context.Context, req domain.CreateTransactionRequest) (*domain.Transaction, error) {
if m.createFn != nil {
return m.createFn(ctx, req)
}
return nil, errors.New("mock is not configured")
}
func (m *transactionServiceCreateMock) GetByID(ctx context.Context, id int64) (*domain.Transaction, error) {
if m.getByIDFn != nil {
return m.getByIDFn(ctx, id)
}
return nil, errors.New("mock is not configured")
}
func (m *transactionServiceCreateMock) List(ctx context.Context, filter domain.TransactionListFilter) ([]*domain.Transaction, error) {
return nil, errors.New("not implemented")
}
func (m *transactionServiceCreateMock) Analytics(ctx context.Context, filter domain.TransactionAnalyticsFilter) (domain.TransactionAnalytics, error) {
return domain.TransactionAnalytics{}, errors.New("not implemented")
}
func (m *transactionServiceCreateMock) Update(ctx context.Context, id int64, req domain.UpdateTransactionRequest) (*domain.Transaction, error) {
return nil, errors.New("not implemented")
}
func (m *transactionServiceCreateMock) Delete(ctx context.Context, id int64) error {
return errors.New("not implemented")
}
type receiptServiceCreateMock struct {
addReceiptFn func(ctx context.Context, req domain.AddReceiptRequest) (*domain.Receipt, error)
}
func (m *receiptServiceCreateMock) AddReceipt(ctx context.Context, req domain.AddReceiptRequest) (*domain.Receipt, error) {
if m.addReceiptFn != nil {
return m.addReceiptFn(ctx, req)
}
return nil, errors.New("mock is not configured")
}
type ocrCreateMock struct {
recognizeFn func(ctx context.Context, image []byte) (string, error)
}
func (m *ocrCreateMock) Recognize(ctx context.Context, image []byte) (string, error) {
if m.recognizeFn != nil {
return m.recognizeFn(ctx, image)
}
return "", errors.New("mock is not configured")
}
func (m *ocrCreateMock) Close() error {
return nil
}
func TestTransactionCreationService_Create_Manual(t *testing.T) {
now := time.Date(2026, time.January, 21, 10, 11, 12, 0, time.UTC)
svc := NewTransactionCreationService(
&transactionServiceCreateMock{createFn: func(ctx context.Context, req domain.CreateTransactionRequest) (*domain.Transaction, error) {
assert.Equal(t, int64(1), req.FamilyID)
return &domain.Transaction{ID: 1, FamilyID: req.FamilyID, DateTime: now}, nil
}},
nil,
nil,
)
transaction, err := svc.Create(context.Background(), CreateTransactionInput{
Manual: &domain.CreateTransactionRequest{FamilyID: 1},
})
require.NoError(t, err)
assert.Equal(t, int64(1), transaction.ID)
}
func TestTransactionCreationService_Create_Receipt(t *testing.T) {
now := time.Date(2026, time.January, 21, 10, 11, 12, 0, time.UTC)
svc := NewTransactionCreationService(
&transactionServiceCreateMock{getByIDFn: func(ctx context.Context, id int64) (*domain.Transaction, error) {
assert.Equal(t, int64(15), id)
return &domain.Transaction{ID: id, DateTime: now}, nil
}},
&receiptServiceCreateMock{addReceiptFn: func(ctx context.Context, req domain.AddReceiptRequest) (*domain.Receipt, error) {
assert.Equal(t, "123", req.Number)
return &domain.Receipt{TransactionID: ptrInt64Service(15)}, nil
}},
nil,
)
transaction, err := svc.Create(context.Background(), CreateTransactionInput{
Receipt: &domain.AddReceiptRequest{Number: "123"},
})
require.NoError(t, err)
assert.Equal(t, int64(15), transaction.ID)
}
func TestTransactionCreationService_Create_Photo(t *testing.T) {
now := time.Date(2026, time.January, 21, 10, 11, 12, 0, time.UTC)
svc := NewTransactionCreationService(
&transactionServiceCreateMock{getByIDFn: func(ctx context.Context, id int64) (*domain.Transaction, error) {
assert.Equal(t, int64(17), id)
return &domain.Transaction{ID: id, DateTime: now}, nil
}},
&receiptServiceCreateMock{addReceiptFn: func(ctx context.Context, req domain.AddReceiptRequest) (*domain.Receipt, error) {
assert.Equal(t, strings.Repeat("1", 24), req.Number)
assert.Equal(t, "21.01.2026", req.Date)
return &domain.Receipt{TransactionID: ptrInt64Service(17)}, nil
}},
&ocrCreateMock{recognizeFn: func(ctx context.Context, image []byte) (string, error) {
assert.Equal(t, []byte("image"), image)
return "21.01.2026 " + strings.Repeat("1", 24), nil
}},
)
familyID := int64(1)
createdBy := int64(2)
transaction, err := svc.Create(context.Background(), CreateTransactionInput{
Photo: &CreateTransactionPhotoInput{
Image: []byte("image"),
FamilyID: &familyID,
CreatedBy: &createdBy,
},
})
require.NoError(t, err)
assert.Equal(t, int64(17), transaction.ID)
}
func TestTransactionCreationService_Create_PhotoRequiresActors(t *testing.T) {
svc := NewTransactionCreationService(
&transactionServiceCreateMock{},
&receiptServiceCreateMock{},
&ocrCreateMock{},
)
_, err := svc.Create(context.Background(), CreateTransactionInput{
Photo: &CreateTransactionPhotoInput{Image: []byte("image")},
})
require.ErrorIs(t, err, ErrReceiptTransactionActorsMissing)
}
func ptrInt64Service(v int64) *int64 {
return &v
}