summaryrefslogtreecommitdiff
path: root/internal/reports/pdf_test.go
blob: 1f2e968650b42c9e7c9529afd92cc2a3829cebf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package reports

import (
	"os"
	"os/exec"
	"path/filepath"
	"testing"
	"time"

	"git.tjp.lol/punchcard/templates"
)

// Helper function for tests
func mustParseDate(dateStr string) time.Time {
	t, err := time.Parse("2006-01-02", dateStr)
	if err != nil {
		panic(err)
	}
	return t
}

func TestTypstTemplateCompilation(t *testing.T) {
	// Check if Typst is installed
	if err := checkTypstInstalled(); err != nil {
		t.Skip("Typst is not installed, skipping template compilation test")
	}

	// Create temporary directory
	tempDir, err := os.MkdirTemp("", "punchcard-test")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}
	defer func() { _ = os.RemoveAll(tempDir) }()

	// Copy test data to temp directory
	testDataPath := filepath.Join("testdata", "invoice_test_data.json")
	testData, err := os.ReadFile(testDataPath)
	if err != nil {
		t.Fatalf("Failed to read test data: %v", err)
	}

	dataFile := filepath.Join(tempDir, "data.json")
	if err := os.WriteFile(dataFile, testData, 0o644); err != nil {
		t.Fatalf("Failed to write test data file: %v", err)
	}

	// Write Typst template to temp directory
	typstFile := filepath.Join(tempDir, "invoice.typ")
	if err := os.WriteFile(typstFile, []byte(templates.InvoiceTemplate), 0o644); err != nil {
		t.Fatalf("Failed to write Typst template: %v", err)
	}

	// Compile with Typst
	outputPDF := filepath.Join(tempDir, "test-invoice.pdf")
	cmd := exec.Command("typst", "compile", typstFile, outputPDF)
	cmd.Dir = tempDir

	if output, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("Typst compilation failed: %v\nOutput: %s", err, string(output))
	}

	// Verify PDF was created
	if _, err := os.Stat(outputPDF); os.IsNotExist(err) {
		t.Fatalf("PDF file was not created")
	}

	t.Logf("Successfully compiled Typst template to PDF")
}

func TestGenerateInvoicePDF(t *testing.T) {
	// Check if Typst is installed
	if err := checkTypstInstalled(); err != nil {
		t.Skip("Typst is not installed, skipping PDF generation test")
	}

	// Create test invoice data
	invoiceData := &InvoiceData{
		ClientName:  "Test Client Co.",
		ProjectName: "Test Project",
		DateRange: DateRange{
			Start: mustParseDate("2025-07-01"),
			End:   mustParseDate("2025-07-31"),
		},
		LineItems: []LineItem{
			{
				Description: "Software development",
				Hours:       8.5,
				Rate:        150.0,
				Amount:      1275.0,
			},
			{
				Description: "Code review",
				Hours:       1.5,
				Rate:        150.0,
				Amount:      225.0,
			},
		},
		TotalHours:    10.0,
		TotalAmount:   1500.0,
		GeneratedDate: mustParseDate("2025-08-04"),
	}

	// Create temporary output file
	tempDir, err := os.MkdirTemp("", "punchcard-pdf-test")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}
	defer func() { _ = os.RemoveAll(tempDir) }()

	outputPath := filepath.Join(tempDir, "test-invoice.pdf")

	// Generate PDF
	if err := GenerateInvoicePDF(invoiceData, outputPath); err != nil {
		t.Fatalf("Failed to generate invoice PDF: %v", err)
	}

	// Verify PDF was created
	if _, err := os.Stat(outputPath); os.IsNotExist(err) {
		t.Fatalf("PDF file was not created at %s", outputPath)
	}

	t.Logf("Successfully generated invoice PDF at %s", outputPath)
}