init
This commit is contained in:
commit
d295c7f139
1527 files changed
+270726
No files matched your search
@@ -0,0 +1,174 @@
|
||||
package screens
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
||||
"github.com/santifer/career-ops/dashboard/internal/model"
|
||||
"github.com/santifer/career-ops/dashboard/internal/theme"
|
||||
)
|
||||
|
||||
func keyMsg(s string) tea.KeyMsg {
|
||||
return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune(s)}
|
||||
}
|
||||
|
||||
func newPDFTestModel(t *testing.T, careerOpsPath string, apps []model.CareerApplication) PipelineModel {
|
||||
t.Helper()
|
||||
pm := NewPipelineModel(
|
||||
theme.NewTheme("catppuccin-mocha"),
|
||||
apps,
|
||||
model.PipelineMetrics{Total: len(apps)},
|
||||
careerOpsPath,
|
||||
120,
|
||||
40,
|
||||
)
|
||||
pm.viewMode = "flat"
|
||||
pm.applyFilterAndSort()
|
||||
return pm
|
||||
}
|
||||
|
||||
func writePDFFixture(t *testing.T, root, rel string) {
|
||||
t.Helper()
|
||||
full := filepath.Join(root, filepath.FromSlash(rel))
|
||||
if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
|
||||
t.Fatalf("mkdir: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(full, []byte("pdf"), 0o644); err != nil {
|
||||
t.Fatalf("write: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPDFKeyFlashesWhenNoPDFExists(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
apps := []model.CareerApplication{
|
||||
{Company: "Globex", Role: "Engineer", Status: "Evaluated", Score: 4.0},
|
||||
}
|
||||
|
||||
pm := newPDFTestModel(t, root, apps)
|
||||
updated, cmd := pm.Update(keyMsg("d"))
|
||||
|
||||
if cmd != nil {
|
||||
t.Fatal("expected no command when no PDF matches")
|
||||
}
|
||||
if updated.flash == "" {
|
||||
t.Fatal("expected a flash notice when no PDF matches")
|
||||
}
|
||||
if updated.pdfPicker {
|
||||
t.Fatal("expected no picker when no PDF matches")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPDFKeyOpensSingleMatchDirectly(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writePDFFixture(t, root, "output/cv-jane-doe-globex-2026-06-05.pdf")
|
||||
apps := []model.CareerApplication{
|
||||
{Company: "Globex", Role: "Engineer", Status: "Evaluated", Score: 4.0},
|
||||
}
|
||||
|
||||
pm := newPDFTestModel(t, root, apps)
|
||||
updated, cmd := pm.Update(keyMsg("d"))
|
||||
|
||||
if updated.pdfPicker {
|
||||
t.Fatal("expected no picker for a single match")
|
||||
}
|
||||
if cmd == nil {
|
||||
t.Fatal("expected an open command for a single match")
|
||||
}
|
||||
msg, ok := cmd().(PipelineOpenPDFMsg)
|
||||
if !ok {
|
||||
t.Fatalf("expected PipelineOpenPDFMsg, got %T", cmd())
|
||||
}
|
||||
if !strings.HasSuffix(msg.Path, "cv-jane-doe-globex-2026-06-05.pdf") {
|
||||
t.Fatalf("unexpected PDF path %q", msg.Path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPDFKeyOpensNewestForMultipleMatches(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
// Write two PDFs for the same company with distinct dates so ordering is predictable.
|
||||
writePDFFixture(t, root, "output/cv-jane-doe-anthropic-2026-06-05.pdf")
|
||||
writePDFFixture(t, root, "output/cv-jane-doe-anthropic-2026-06-10.pdf")
|
||||
apps := []model.CareerApplication{
|
||||
{Company: "Anthropic", Role: "Staff UI Engineer", Status: "Evaluated", Score: 4.6},
|
||||
}
|
||||
|
||||
pm := newPDFTestModel(t, root, apps)
|
||||
updated, cmd := pm.Update(keyMsg("d"))
|
||||
|
||||
// Multiple candidates → open the newest one immediately, no picker.
|
||||
if updated.pdfPicker {
|
||||
t.Fatal("expected no picker — newest match should be opened directly")
|
||||
}
|
||||
if cmd == nil {
|
||||
t.Fatal("expected an open command for the newest match")
|
||||
}
|
||||
msg, ok := cmd().(PipelineOpenPDFMsg)
|
||||
if !ok {
|
||||
t.Fatalf("expected PipelineOpenPDFMsg, got %T", cmd())
|
||||
}
|
||||
if !strings.HasSuffix(msg.Path, "cv-jane-doe-anthropic-2026-06-10.pdf") {
|
||||
t.Fatalf("expected newest PDF to be opened, got %q", msg.Path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegenerateKeyFlashesWithoutManifestEntry(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
apps := []model.CareerApplication{
|
||||
{Company: "Globex", Role: "Engineer", Status: "Evaluated", Score: 4.0, ReportNumber: "001"},
|
||||
}
|
||||
|
||||
pm := newPDFTestModel(t, root, apps)
|
||||
updated, cmd := pm.Update(keyMsg("D"))
|
||||
|
||||
if cmd != nil {
|
||||
t.Fatal("expected no command without a manifest entry")
|
||||
}
|
||||
if updated.flash == "" {
|
||||
t.Fatal("expected a flash notice without a manifest entry")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegenerateKeyEmitsGenerateMsgFromManifest(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writePDFFixture(t, root, "output/cv-jane-doe-globex.html")
|
||||
writePDFFixture(t, root, "data/pdf-index.tsv") // placeholder, overwritten below
|
||||
manifest := "001\toutput/cv-jane-doe-globex-2026-06-05.pdf\toutput/cv-jane-doe-globex.html\tletter\t2026-06-05\n"
|
||||
if err := os.WriteFile(filepath.Join(root, "data", "pdf-index.tsv"), []byte(manifest), 0o644); err != nil {
|
||||
t.Fatalf("write manifest: %v", err)
|
||||
}
|
||||
apps := []model.CareerApplication{
|
||||
{Company: "Globex", Role: "Engineer", Status: "Evaluated", Score: 4.0, ReportNumber: "001"},
|
||||
}
|
||||
|
||||
pm := newPDFTestModel(t, root, apps)
|
||||
updated, cmd := pm.Update(keyMsg("D"))
|
||||
|
||||
if cmd == nil {
|
||||
t.Fatal("expected a generate command")
|
||||
}
|
||||
if updated.flash == "" {
|
||||
t.Fatal("expected an in-progress flash while regenerating")
|
||||
}
|
||||
msg, ok := cmd().(PipelineGeneratePDFMsg)
|
||||
if !ok {
|
||||
t.Fatalf("expected PipelineGeneratePDFMsg, got %T", cmd())
|
||||
}
|
||||
if msg.ReportNumber != "001" || msg.HTMLPath != "output/cv-jane-doe-globex.html" || msg.Format != "letter" {
|
||||
t.Fatalf("unexpected generate request: %+v", msg)
|
||||
}
|
||||
|
||||
// Outcome message updates the flash.
|
||||
done, _ := updated.Update(PipelinePDFGeneratedMsg{Path: "/abs/cv.pdf"})
|
||||
if !strings.Contains(done.flash, "cv.pdf") {
|
||||
t.Fatalf("expected success flash to name the PDF, got %q", done.flash)
|
||||
}
|
||||
failed, _ := updated.Update(PipelinePDFGeneratedMsg{Err: "node not found"})
|
||||
if !strings.Contains(failed.flash, "node not found") {
|
||||
t.Fatalf("expected failure flash to carry the error, got %q", failed.flash)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user