Files
bamort/backend/pdfrender/fill_capacity_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

111 lines
2.7 KiB
Go

package pdfrender
import (
"strings"
"testing"
)
func TestFillToCapacity_Skills(t *testing.T) {
// Test filling skills list to capacity
skills := []SkillViewModel{
{Name: "Skill 1", Value: 10},
{Name: "Skill 2", Value: 12},
}
filled := FillToCapacity(skills, 5)
if len(filled) != 5 {
t.Errorf("Expected 5 items after filling, got %d", len(filled))
}
// First 2 should be original skills
if filled[0].Name != "Skill 1" {
t.Error("First item should be original")
}
// Last 3 should be empty
if filled[2].Name != "" {
t.Error("Filled items should have empty Name")
}
if filled[4].Value != 0 {
t.Error("Filled items should have zero Value")
}
}
func TestFillToCapacity_LessThanCapacity(t *testing.T) {
// If already at or over capacity, should not add more
skills := []SkillViewModel{
{Name: "Skill 1"},
{Name: "Skill 2"},
{Name: "Skill 3"},
}
filled := FillToCapacity(skills, 2)
// Should keep original 3, not truncate
if len(filled) != 3 {
t.Errorf("Expected 3 items (original), got %d", len(filled))
}
}
func TestTemplateWithEmptyRows(t *testing.T) {
// Integration test: render template with filled rows
loader := NewTemplateLoader("../templates/Default_A4_Quer")
err := loader.LoadTemplates()
if err != nil {
t.Fatalf("Failed to load templates: %v", err)
}
// Create data with few skills
skills := []SkillViewModel{
{Name: "Schwimmen", Value: 10},
{Name: "Klettern", Value: 8},
}
// Fill to column capacity (29)
filledCol1 := FillToCapacity(skills, 29)
pageData := &PageData{
Character: CharacterInfo{
Name: "Test Character",
},
SkillsColumn1: filledCol1,
SkillsColumn2: FillToCapacity([]SkillViewModel{}, 29),
Meta: PageMeta{
Date: "19.12.2025",
},
}
html, err := loader.RenderTemplate("page_1.html", pageData)
if err != nil {
t.Fatalf("Failed to render template: %v", err)
}
// Get expected skill capacity from template
templateSet := DefaultA4QuerTemplateSet()
var page1Template *TemplateWithMeta
for i := range templateSet.Templates {
if templateSet.Templates[i].Metadata.Name == "page_1.html" {
page1Template = &templateSet.Templates[i]
break
}
}
if page1Template == nil {
t.Fatal("page_1.html template not found")
}
var col1Capacity int
for i := range page1Template.Metadata.Blocks {
if page1Template.Metadata.Blocks[i].Name == "skills_column1" {
col1Capacity = page1Template.Metadata.Blocks[i].MaxItems
break
}
}
// Count the number of <tr> tags in skills table
// Should have col1Capacity rows (2 filled + remaining empty)
trCount := strings.Count(html, "<tr><td>")
if trCount < col1Capacity {
t.Errorf("Expected at least %d skill rows in HTML (from template), got %d", col1Capacity, trCount)
}
}