package reports import ( "os" "os/exec" "path/filepath" "punchcard/templates" "testing" "time" ) // 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 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, 0644); 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), 0644); 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 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) }