mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
126 lines
3.6 KiB
Go
126 lines
3.6 KiB
Go
package booking
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rjNemo/rentease/internal/config"
|
|
)
|
|
|
|
func TestCreateInvoice_StoresInvoicePDFAndPersistsShareURL(t *testing.T) {
|
|
store := newStubStore()
|
|
pdfClient := stubInvoicePDF{
|
|
file: &GeneratedFile{
|
|
Name: "VFNI0240.pdf",
|
|
ContentType: "application/pdf",
|
|
Data: []byte("%PDF-1.4 test invoice"),
|
|
},
|
|
}
|
|
storage := &stubInvoiceStorage{
|
|
stored: &StoredInvoiceFile{
|
|
ShareURL: "https://minio.local/invoices/1/VFNI0240.pdf?X-Amz-Signature=test",
|
|
ShareURLExpiresAt: time.Date(2026, time.March, 21, 10, 0, 0, 0, time.UTC),
|
|
},
|
|
}
|
|
|
|
svc, err := NewService(slog.Default(), store, nil, pdfClient, storage, 2*time.Hour)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error creating service: %v", err)
|
|
}
|
|
|
|
booking := NewBooking(
|
|
time.Date(2026, time.March, 20, 0, 0, 0, 0, time.UTC),
|
|
time.Date(2026, time.March, 24, 0, 0, 0, 0, time.UTC),
|
|
"Jane Doe",
|
|
"+590690441530",
|
|
"jane@example.com",
|
|
"Booking",
|
|
2,
|
|
15,
|
|
nil,
|
|
).WithID(1)
|
|
|
|
doc, err := svc.CreateInvoice(context.Background(), booking, config.NewHost())
|
|
if err != nil {
|
|
t.Fatalf("unexpected error creating invoice: %v", err)
|
|
}
|
|
|
|
if storage.objectKey != "invoices/1/VFNI0240.pdf" {
|
|
t.Fatalf("expected invoice object key to include booking folder, got %q", storage.objectKey)
|
|
}
|
|
if storage.shareURLTTL != 2*time.Hour {
|
|
t.Fatalf("expected configured share URL TTL to be forwarded, got %s", storage.shareURLTTL)
|
|
}
|
|
if string(storage.file.Data) != "%PDF-1.4 test invoice" {
|
|
t.Fatalf("expected generated PDF bytes to be uploaded, got %q", string(storage.file.Data))
|
|
}
|
|
if doc.ShareURL != storage.stored.ShareURL {
|
|
t.Fatalf("expected returned document share URL %q, got %q", storage.stored.ShareURL, doc.ShareURL)
|
|
}
|
|
if store.invoiceDocument == nil {
|
|
t.Fatal("expected invoice document to be persisted")
|
|
}
|
|
if store.invoiceDocument.ObjectKey != "invoices/1/VFNI0240.pdf" {
|
|
t.Fatalf("expected persisted object key, got %q", store.invoiceDocument.ObjectKey)
|
|
}
|
|
if store.invoiceDocument.ShareURL != storage.stored.ShareURL {
|
|
t.Fatalf("expected persisted share URL %q, got %q", storage.stored.ShareURL, store.invoiceDocument.ShareURL)
|
|
}
|
|
}
|
|
|
|
func TestCreateInvoice_ReturnsConfigurationErrorWhenStorageIsMissing(t *testing.T) {
|
|
svc, err := NewService(slog.Default(), newStubStore(), nil, noopPDF{}, nil, time.Hour)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error creating service: %v", err)
|
|
}
|
|
|
|
booking := NewBooking(time.Now(), time.Now().Add(24*time.Hour), "Jane Doe", "", "", "Booking", 1, 0, nil).WithID(1)
|
|
|
|
_, err = svc.CreateInvoice(context.Background(), booking, config.NewHost())
|
|
if !errors.Is(err, ErrInvoiceStorageNotConfigured) {
|
|
t.Fatalf("expected ErrInvoiceStorageNotConfigured, got %v", err)
|
|
}
|
|
}
|
|
|
|
type stubInvoicePDF struct {
|
|
file *GeneratedFile
|
|
err error
|
|
}
|
|
|
|
func (s stubInvoicePDF) BuildInvoice(invoice Invoice) (*GeneratedFile, error) {
|
|
if s.err != nil {
|
|
return nil, s.err
|
|
}
|
|
return s.file, nil
|
|
}
|
|
|
|
func (stubInvoicePDF) BuildReport(report ReportData, period string, month, year int) (string, error) {
|
|
return "", nil
|
|
}
|
|
|
|
type stubInvoiceStorage struct {
|
|
file GeneratedFile
|
|
objectKey string
|
|
shareURLTTL time.Duration
|
|
stored *StoredInvoiceFile
|
|
err error
|
|
}
|
|
|
|
func (s *stubInvoiceStorage) StoreInvoice(ctx context.Context, objectKey string, file GeneratedFile, shareURLTTL time.Duration) (*StoredInvoiceFile, error) {
|
|
if s.err != nil {
|
|
return nil, s.err
|
|
}
|
|
|
|
s.objectKey = objectKey
|
|
s.file = file
|
|
s.shareURLTTL = shareURLTTL
|
|
|
|
stored := *s.stored
|
|
if stored.ObjectKey == "" {
|
|
stored.ObjectKey = objectKey
|
|
}
|
|
return &stored, nil
|
|
}
|