Files
accounting/pkg/invoice/invoice_test.go
schreifuchs 774d5acbd2
All checks were successful
Go / build (pull_request) Successful in 14s
feat: better debug logs
2025-12-03 21:26:54 +01:00

164 lines
4.8 KiB
Go

package invoice
import (
"bytes"
"errors"
"io"
"log/slog"
"strings"
"testing"
"time"
"code.gitea.io/sdk/gitea"
"git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice/model"
)
// MockGiteaClient is a mock implementation of the GiteaClient interface.
type MockGiteaClient struct {
ListRepoIssuesFunc func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error)
}
func (m *MockGiteaClient) ListRepoIssues(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
if m.ListRepoIssuesFunc != nil {
return m.ListRepoIssuesFunc(owner, repo, opt)
}
return nil, nil, errors.New("ListRepoIssuesFunc not implemented")
}
// MockPdfGenerator is a mock implementation of the PdfGenerator interface.
type MockPdfGenerator struct {
HtmlToPdfFunc func(html string) (io.ReadCloser, error)
}
func (m *MockPdfGenerator) HtmlToPdf(html string) (io.ReadCloser, error) {
if m.HtmlToPdfFunc != nil {
return m.HtmlToPdfFunc(html)
}
return nil, errors.New("HtmlToPdfFunc not implemented")
}
func TestGenerate(t *testing.T) {
creditor := model.Entity{
Name: "creditor",
}
debtor := model.Entity{
Name: "deptor",
}
rate := 100.0
repos := []Repo{
{Owner: "owner", Repo: "repo"},
}
testCases := []struct {
name string
setupMocks func(*MockGiteaClient, *MockPdfGenerator)
config *Options
expectedError string
}{
{
name: "successful generation",
setupMocks: func(g *MockGiteaClient, p *MockPdfGenerator) {
g.ListRepoIssuesFunc = func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
return []*gitea.Issue{
{ID: 1, Title: "Test Issue", Body: "```info\nduration: 1h\n```"},
}, &gitea.Response{}, nil
}
p.HtmlToPdfFunc = func(html string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader([]byte("pdf"))), nil
}
},
config: &DefaultOptions,
expectedError: "",
},
{
name: "gitea error",
setupMocks: func(g *MockGiteaClient, p *MockPdfGenerator) {
g.ListRepoIssuesFunc = func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
return nil, nil, errors.New("gitea error")
}
},
config: &DefaultOptions,
expectedError: "gitea error",
},
{
name: "pdf error",
setupMocks: func(g *MockGiteaClient, p *MockPdfGenerator) {
g.ListRepoIssuesFunc = func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
return []*gitea.Issue{
{ID: 1, Title: "Test Issue", Body: "```info\nduration: 1h\n```"},
}, &gitea.Response{}, nil
}
p.HtmlToPdfFunc = func(html string) (io.ReadCloser, error) {
return nil, errors.New("pdf error")
}
},
config: &DefaultOptions,
expectedError: "pdf error",
},
{
name: "no issues",
setupMocks: func(g *MockGiteaClient, p *MockPdfGenerator) {
g.ListRepoIssuesFunc = func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
return []*gitea.Issue{}, &gitea.Response{}, nil
}
p.HtmlToPdfFunc = func(html string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader([]byte("pdf"))), nil
}
},
config: &DefaultOptions,
expectedError: "",
},
{
name: "custom template",
setupMocks: func(g *MockGiteaClient, p *MockPdfGenerator) {
g.ListRepoIssuesFunc = func(owner, repo string, opt gitea.ListIssueOption) ([]*gitea.Issue, *gitea.Response, error) {
return []*gitea.Issue{
{ID: 1, Title: "Test Issue", Body: "```info\nduration: 1h\n```"},
}, &gitea.Response{}, nil
}
p.HtmlToPdfFunc = func(html string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader([]byte("pdf"))), nil
}
},
config: &Options{
Mindur: time.Minute * 15,
Since: time.Now().AddDate(0, -1, 0),
Before: time.Now(),
IssueState: gitea.StateClosed,
IssueFilter: func(i *gitea.Issue) bool { return true },
CustomTemplate: "custom template",
},
expectedError: "",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
giteaClient := new(MockGiteaClient)
pdfGenerator := new(MockPdfGenerator)
tc.setupMocks(giteaClient, pdfGenerator)
service := New(slog.Default(), giteaClient, pdfGenerator)
doc, _, err := service.Generate(creditor, &debtor, rate, repos, tc.config)
if tc.expectedError != "" {
if err == nil {
t.Fatalf("expected an error, but got none")
}
if !strings.Contains(err.Error(), tc.expectedError) {
t.Errorf("expected error to contain '%s', but got '%s'", tc.expectedError, err.Error())
}
} else {
if err != nil {
t.Fatalf("expected no error, but got: %v", err)
}
if doc == nil {
t.Fatal("expected a document, but got nil")
}
}
})
}
}