GameOver1337 / GitClone Public
К репозиторию
4.4 KB
internal/handlers/templates_test.go
4.4 KB
1package handlers
2
3import (
4 "bytes"
5 "net/http/httptest"
6 "testing"
7 "time"
8
9 "github.com/clancore/repo/internal/models"
10 "github.com/clancore/repo/internal/services"
11)
12
13func TestTemplatesRender(t *testing.T) {
14 tmpl := NewTemplates()
15 if err := tmpl.LoadDir("../../templates"); err != nil {
16 t.Fatalf("load templates: %v", err)
17 }
18
19 now := time.Date(2026, 1, 2, 15, 4, 5, 0, time.UTC)
20 user := &models.User{
21 ID: 1,
22 Username: "testuser",
23 Email: "test@example.com",
24 CreatedAt: now,
25 }
26 repo := &models.Repo{
27 ID: 1,
28 Name: "demo",
29 OwnerID: user.ID,
30 Owner: user,
31 CloneURL: "testuser/demo",
32 Description: "Демонстрационный репозиторий",
33 CreatedAt: now,
34 UpdatedAt: now,
35 }
36 finished := now.Add(time.Minute)
37 build := &models.Build{
38 ID: 1,
39 RepoID: repo.ID,
40 Branch: "main",
41 BuildType: "go",
42 Status: "success",
43 StartedAt: now,
44 FinishedAt: &finished,
45 CreatedAt: now,
46 }
47 release := &models.Release{
48 ID: 1,
49 RepoID: repo.ID,
50 Tag: "v1.0.0",
51 Title: "Первый релиз",
52 Body: "Что нового\n- первая версия",
53 IsPrerelease: false,
54 CreatedAt: now,
55 }
56 releases := []*models.Release{release}
57 commits := []services.CommitInfo{{
58 Hash: "5030ca0a",
59 Author: "testuser",
60 Time: now,
61 Subject: "Initial commit",
62 }}
63 tree := []services.FileEntry{
64 {Name: "main.go", Path: "main.go", Type: "blob", Size: 1024,
65 Commit: &services.CommitInfo{Hash: "5030ca0a", Author: "testuser", Time: now, Subject: "Initial commit"}},
66 {Name: "src", Path: "src", Type: "tree"},
67 }
68 repos := []*models.Repo{repo}
69 rows := []struct {
70 B *models.Build
71 Repo *models.Repo
72 }{{B: build, Repo: repo}}
73
74 base := map[string]interface{}{
75 "UserID": user.ID,
76 "User": user,
77 "CSRF": "test-token",
78 "Query": "",
79 "BaseURL": "http://localhost:5758",
80 }
81 page := func(extra map[string]interface{}) map[string]interface{} {
82 d := make(map[string]interface{}, len(base)+len(extra))
83 for k, v := range base {
84 d[k] = v
85 }
86 for k, v := range extra {
87 d[k] = v
88 }
89 return d
90 }
91
92 pages := map[string]map[string]interface{}{
93 "home": page(map[string]interface{}{
94 "PublicRepos": repos,
95 }),
96 "repo": page(map[string]interface{}{
97 "Repo": repo,
98 "IsOwner": true,
99 "Branches": []string{"main", "dev"},
100 "ActiveBranch": "main",
101 "Commits": commits,
102 "Tree": tree,
103 "Path": "",
104 "Crumbs": []Crumb(nil),
105 "TreeError": false,
106 "BranchCount": 2,
107 "TagCount": 1,
108 "CommitCount": 7,
109 "Releases": releases,
110 "ReleaseCount": 1,
111 }),
112 "file": page(map[string]interface{}{
113 "Repo": repo,
114 "Path": "main.go",
115 "Crumbs": []Crumb{{Name: "main.go", Path: "main.go"}},
116 "Branch": "main",
117 "Content": "package main\n\nfunc main() {}\n",
118 "FileSize": "27 B",
119 "LangClass": langClass("main.go"),
120 }),
121 "dashboard": page(map[string]interface{}{
122 "Repos": repos,
123 }),
124 "builds": page(map[string]interface{}{
125 "Rows": rows,
126 "FilterRepo": repo,
127 }),
128 "build": page(map[string]interface{}{
129 "Repo": repo,
130 "Build": build,
131 "BuildID": build.ID,
132 "BuildLog": "=== build started ===\ntype: go\n=== build SUCCESS ===\n",
133 }),
134 "login": page(map[string]interface{}{
135 "Error": "",
136 }),
137 "register": page(map[string]interface{}{
138 "Error": "",
139 }),
140 "repo-create": page(map[string]interface{}{
141 "Error": "",
142 }),
143 "profile": page(map[string]interface{}{
144 "ProfileUser": user,
145 "Repos": repos,
146 }),
147 "releases": page(map[string]interface{}{
148 "Repo": repo,
149 "IsOwner": true,
150 "Releases": releases,
151 }),
152 "release-new": page(map[string]interface{}{
153 "Repo": repo,
154 "Error": "",
155 "Tag": "v1.0.0",
156 "Title": "Первый релиз",
157 "Body": "Что нового",
158 "IsPrerelease": false,
159 }),
160 }
161
162 for name, data := range pages {
163 t.Run(name, func(t *testing.T) {
164 rec := httptest.NewRecorder()
165 tmpl.Render(rec, name, data)
166 if rec.Code != 200 {
167 t.Fatalf("status = %d, body = %s", rec.Code, rec.Body.String())
168 }
169 body := rec.Body.Bytes()
170 if !bytes.Contains(body, []byte("</html>")) {
171 t.Fatalf("page %s was not fully rendered", name)
172 }
173 if bytes.Contains(body, []byte("<no value>")) {
174 t.Fatalf("page %s contains missing template values", name)
175 }
176 })
177 }
178}