Files
bamort/backend/pdfrender/templates_test.go
T
Frank 59fe69d35d refactor: Unify PDF pagination system and rename templates
BREAKING CHANGE: Template names changed from page1_stats.html to page_1.html

## Phase 1: Unified Pagination Function
- Implemented PaginateMultiList() to replace PaginateSkills(), PaginateSpells(), and PaginatePage2PlayLists()
- Single metadata-driven function handles all list types (skills, weapons, spells, equipment)
- Properly handles filters (learned/unlearned/language) via template metadata
- Shares list trackers by ListType+Filter combination to avoid duplication
- Added comprehensive tests for all edge cases

## Phase 2: Template Naming Convention
- Renamed templates to be data-agnostic:
  - page1_stats.html -> page_1.html
  - page1.2_stats.html -> page_1.2.html
  - page2_play.html -> page_2.html
  - page2.2_play.html -> page_2.2.html
  - page3_spell.html -> page_3.html
  - page3.2_spell.html -> page_3.2.html
  - page4_equip.html -> page_4.html
- Updated GenerateContinuationTemplateName() for new naming (page_1.html -> page_1.2.html)
- Updated ExtractBaseTemplateName() to handle new format
- Updated all test files and source files with new template names

## Phase 3: Simplified RenderPageWithContinuations
- Removed hardcoded switch statements based on template names
- Replaced with generic dataMap and unified pagination call
- Extracted populatePageDataFromDistribution() to handle data mapping
- Template type detection now driven by metadata, not hardcoded names

## Benefits
-  Extensibility: Add new templates without code changes
-  Maintainability: One pagination algorithm instead of three
-  Clarity: Template names reflect page numbers, not content types
-  Flexibility: Templates can mix any data types
-  All 40+ tests passing

## Technical Details
- Added SkillsColumn3 and SkillsColumn4 fields to PageData for continuation pages
- Template metadata loaded from HTML comments drives pagination behavior
- Backward compatibility maintained for old template references in comments
2025-12-21 22:07:46 +01:00

181 lines
4.2 KiB
Go

package pdfrender
import (
"strings"
"testing"
)
func TestLoadTemplate_Success(t *testing.T) {
// Arrange
loader := NewTemplateLoader("../templates/Default_A4_Quer")
// Act
err := loader.LoadTemplates()
// Assert
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}
// Check that templates were loaded
if loader.templates == nil {
t.Error("Expected templates to be loaded, got nil")
}
}
func TestRenderTemplate_BasicData(t *testing.T) {
// Arrange
loader := NewTemplateLoader("../templates/Default_A4_Quer")
err := loader.LoadTemplates()
if err != nil {
t.Fatalf("Failed to load templates: %v", err)
}
data := &PageData{
Character: CharacterInfo{
Name: "Test Character",
Grade: 5,
},
Attributes: AttributeValues{
St: 80,
Gs: 70,
},
Meta: PageMeta{
Date: "18.12.2025",
},
}
// Act
html, err := loader.RenderTemplate("page_1.html", data)
// Assert
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}
if html == "" {
t.Error("Expected non-empty HTML, got empty string")
}
// Check that template variables were replaced
if !strings.Contains(html, "Test Character") {
t.Error("Expected HTML to contain 'Test Character'")
}
if !strings.Contains(html, "18.12.2025") {
t.Error("Expected HTML to contain date '18.12.2025'")
}
}
func TestGetTemplateMetadata(t *testing.T) {
// Arrange
loader := NewTemplateLoader("../templates/Default_A4_Quer")
err := loader.LoadTemplates()
if err != nil {
t.Fatalf("Failed to load templates: %v", err)
}
// Act
metadata := loader.GetTemplateMetadata("page_3.html")
// Assert
if len(metadata) == 0 {
t.Fatal("Expected metadata blocks, got none")
}
// Read actual template to get expected MAX values
templateSet := DefaultA4QuerTemplateSet()
var page3Template *TemplateWithMeta
for i := range templateSet.Templates {
if templateSet.Templates[i].Metadata.Name == "page_3.html" {
page3Template = &templateSet.Templates[i]
break
}
}
if page3Template == nil {
t.Fatal("page_3.html template not found")
}
// Get expected values from template
var expectedLeftMax, expectedRightMax int
for i := range page3Template.Metadata.Blocks {
if page3Template.Metadata.Blocks[i].Name == "spells_left" {
expectedLeftMax = page3Template.Metadata.Blocks[i].MaxItems
} else if page3Template.Metadata.Blocks[i].Name == "spells_right" {
expectedRightMax = page3Template.Metadata.Blocks[i].MaxItems
}
}
// Check for spells_left block
leftBlock := GetBlockByName(metadata, "spells_left")
if leftBlock == nil {
t.Error("Expected to find 'spells_left' block")
} else {
if leftBlock.MaxItems != expectedLeftMax {
t.Errorf("Expected spells_left max %d (from template), got %d", expectedLeftMax, leftBlock.MaxItems)
}
}
// Check for spells_right block
rightBlock := GetBlockByName(metadata, "spells_right")
if rightBlock == nil {
t.Error("Expected to find 'spells_right' block")
} else {
if rightBlock.MaxItems != expectedRightMax {
t.Errorf("Expected spells_right max %d (from template), got %d", expectedRightMax, rightBlock.MaxItems)
}
}
}
func TestRenderTemplate_WithSkills(t *testing.T) {
// Arrange
loader := NewTemplateLoader("../templates/Default_A4_Quer")
err := loader.LoadTemplates()
if err != nil {
t.Fatalf("Failed to load templates: %v", err)
}
data := &PageData{
Character: CharacterInfo{
Name: "Test",
},
SkillsColumn1: []SkillViewModel{
{Name: "Schwimmen", Value: 10, PracticePoints: 2},
},
SkillsColumn2: []SkillViewModel{
{Name: "Klettern", Value: 8, PracticePoints: 3},
},
Meta: PageMeta{
Date: "18.12.2025",
},
}
// Act
html, err := loader.RenderTemplate("page_1.html", data)
// Assert
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}
// Check that skills were rendered
if !strings.Contains(html, "Schwimmen") {
t.Error("Expected HTML to contain 'Schwimmen'")
}
if !strings.Contains(html, "Klettern") {
t.Error("Expected HTML to contain 'Klettern'")
}
}
func TestLoadTemplate_InvalidPath(t *testing.T) {
// Arrange
loader := NewTemplateLoader("/invalid/path")
// Act
err := loader.LoadTemplates()
// Assert
if err == nil {
t.Error("Expected error for invalid path, got nil")
}
}