arnaucube
arnaucube/gitviewPublic Self-hosted repository
gitview/internal/routes/index_test.go
internal/routes/index_test.goRaw
  1package routes
  2
  3import (
  4	"encoding/json"
  5	"fmt"
  6	"net/http"
  7	"net/http/httptest"
  8	"os"
  9	"path/filepath"
 10	"regexp"
 11	"slices"
 12	"strings"
 13	"testing"
 14	"time"
 15
 16	gogit "github.com/go-git/go-git/v5"
 17	"github.com/go-git/go-git/v5/plumbing/object"
 18	"gitview/internal/config"
 19)
 20
 21// Exercise configured ordering through YAML loading and rendered repository cards.
 22func TestIndexPinnedOrder(t *testing.T) {
 23	c, _ := testWorkspace(t)
 24	source := filepath.Join(c.Repo.ScanPath, "sample")
 25	for name, day := range map[string]int{"first": 1, "second.git": 5, "recent": 10, "hidden": 20, "ignored": 25} {
 26		path := filepath.Join(c.Repo.ScanPath, name)
 27		repo, err := gogit.PlainClone(path, false, &gogit.CloneOptions{URL: source})
 28		if err != nil {
 29			t.Fatal(err)
 30		}
 31		wt, err := repo.Worktree()
 32		if err != nil {
 33			t.Fatal(err)
 34		}
 35		if err := os.WriteFile(filepath.Join(path, "README.md"), []byte(name), 0644); err != nil {
 36			t.Fatal(err)
 37		}
 38		if _, err := wt.Add("README.md"); err != nil {
 39			t.Fatal(err)
 40		}
 41		author := &object.Signature{Name: "Test Author", Email: "author@example.com", When: time.Date(2026, 1, day, 12, 0, 0, 0, time.UTC)}
 42		if _, err := wt.Commit("Update "+name, &gogit.CommitOptions{Author: author}); err != nil {
 43			t.Fatal(err)
 44		}
 45	}
 46	cards := regexp.MustCompile(`data-repo="([^"]+)"`)
 47	for _, tt := range []struct {
 48		name         string
 49		pinned, want []string
 50	}{
 51		{"default", nil, []string{"recent", "second", "sample", "first"}},
 52		{"configured order", []string{"first", "second"}, []string{"first", "second", "recent", "sample"}},
 53		{"suffixes duplicates missing and hidden", []string{"hidden", "ignored", "missing", "second.git", "first", "second"}, []string{"second", "first", "recent", "sample"}},
 54	} {
 55		t.Run(tt.name, func(t *testing.T) {
 56			pinned, err := json.Marshal(tt.pinned)
 57			if err != nil {
 58				t.Fatal(err)
 59			}
 60			path := filepath.Join(t.TempDir(), "config.yaml")
 61			yaml := fmt.Sprintf("repo:\n  scanPath: %q\n  pinned: %s\n  unlisted: [hidden]\n  ignore: [ignored]\ndirs:\n  templates: %q\n  static: %q\n", c.Repo.ScanPath, pinned, c.Dirs.Templates, c.Dirs.Static)
 62			if err := os.WriteFile(path, []byte(yaml), 0644); err != nil {
 63				t.Fatal(err)
 64			}
 65			loaded, err := config.Read(path)
 66			if err != nil {
 67				t.Fatal(err)
 68			}
 69			w := httptest.NewRecorder()
 70			Handlers(loaded).ServeHTTP(w, httptest.NewRequest("GET", "/", nil))
 71			if w.Code != http.StatusOK {
 72				t.Fatalf("index status: %d", w.Code)
 73			}
 74			var got []string
 75			for _, match := range cards.FindAllStringSubmatch(w.Body.String(), -1) {
 76				got = append(got, match[1])
 77			}
 78			if !slices.Equal(got, tt.want) {
 79				t.Fatalf("repository order: %v; want %v", got, tt.want)
 80			}
 81		})
 82	}
 83}
 84
 85func TestRepositoryOwnerFromConfig(t *testing.T) {
 86	c, _ := testWorkspace(t)
 87	path := filepath.Join(t.TempDir(), "config.yaml")
 88	yaml := fmt.Sprintf("repo:\n  scanPath: %q\n  mainBranch: [main]\ndirs:\n  templates: %q\n  static: %q\nmeta:\n  title: git.example.com\n  username: arnaucube\n", c.Repo.ScanPath, c.Dirs.Templates, c.Dirs.Static)
 89	if err := os.WriteFile(path, []byte(yaml), 0644); err != nil {
 90		t.Fatal(err)
 91	}
 92	loaded, err := config.Read(path)
 93	if err != nil {
 94		t.Fatal(err)
 95	}
 96	for _, path := range []string{"/sample", "/sample/tree/main/", "/sample/blob/main/src/main.go", "/sample/log/main", "/sample/refs/"} {
 97		w := httptest.NewRecorder()
 98		Handlers(loaded).ServeHTTP(w, httptest.NewRequest("GET", path, nil))
 99		if w.Code != http.StatusOK || !strings.Contains(w.Body.String(), `<a href="/">arnaucube</a>`) {
100			t.Errorf("%s: missing configured owner (status %d)", path, w.Code)
101		}
102	}
103}