PrintToVeraeTimeStamp/internal/job/job_test.go
Grok Bot (for George) 13ebc351f5 0.3.2: Save As filename prompt per print (Windows + macOS)
- promptForFilename setting (default true; env VERAE_PROMPT_FOR_FILENAME),
  'verae-print config --prompt-for-filename', last Save As folder in
  ~/.verae/state.json
- Windows helper: common file dialog (PDF filter, overwrite prompt, topmost
  owner) before stamping; macOS printer path: choose file name (NSSavePanel)
  via 'stamp -prompt-name -title'; cancel discards the job (no stamp/credit)
- job.Options.OutPath: original saved at the chosen path, certificate and
  .verae.json next to it with the chosen base name (never overwritten)
- held jobs keep the chosen path (pendingMeta.OutPath)
- installer: 'Ask for a file name for each print' checkbox; removed the
  'Open the user guide' finish-page checkbox; mac-key-setup asks too
- auth test no longer touches the real macOS keychain (VERAE_SKIP_KEYCHAIN)
- version 0.3.2
2026-10-03 20:00:56 -04:00

181 lines
6.8 KiB
Go

package job
import (
"encoding/base64"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"testing"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/auth"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/veraeapi"
)
func TestSanitizeAndStem(t *testing.T) {
if SanitizeReceiptID("bafy/xyz!") != "bafy-xyz" {
t.Fatal(SanitizeReceiptID("bafy/xyz!"))
}
if StemFromPath("/tmp/My Contract (1).pdf", "") != "My-Contract-1" {
t.Fatal(StemFromPath("/tmp/My Contract (1).pdf", ""))
}
}
func TestRunZapierWritesNamedFiles(t *testing.T) {
dir := t.TempDir()
src := filepath.Join(dir, "src.pdf")
if err := os.WriteFile(src, []byte("%PDF-1.4 hello"), 0o600); err != nil {
t.Fatal(err)
}
out := filepath.Join(dir, "out")
pdf := []byte("%PDF-1.4 certificate-bytes")
b64 := base64.StdEncoding.EncodeToString(pdf)
client := &veraeapi.Client{
Channel: auth.ChannelZapier,
ZapierBase: "https://zap.test",
XVeraeToken: "xVerae-x",
HTTPDo: func(req *http.Request) (*http.Response, error) {
body := `{"receipt_id":"bafyReceipt99","pdfBase64":"` + b64 + `"}`
return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(body)), Header: make(http.Header)}, nil
},
}
res, err := Run(Options{
SourcePDF: src,
OutDir: out,
DocumentName: "Contract.pdf",
Channel: auth.ChannelZapier,
Client: client,
})
if err != nil {
t.Fatal(err)
}
wantCert := filepath.Join(out, "Contract-verae-timestamp-bafyReceipt99.pdf")
if res.CertificatePDF != wantCert {
t.Fatalf("cert path %s want %s", res.CertificatePDF, wantCert)
}
if _, err := os.Stat(res.OriginalPDF); err != nil {
t.Fatal(err)
}
got, _ := os.ReadFile(res.CertificatePDF)
if !strings.HasPrefix(string(got), "%PDF") {
t.Fatal("certificate is not a PDF")
}
if !strings.Contains(string(got), "Verae Timestamp Registration Document") {
t.Fatal("missing branded title")
}
if strings.Contains(string(got), "mcp.verae.ai") || strings.Contains(string(got), "via MCP") {
t.Fatal("certificate must not mention mcp.verae.ai / via MCP")
}
if _, err := os.Stat(res.ReceiptJSON); err != nil {
t.Fatal(err)
}
}
func TestRunVeraeRendersLocalCert(t *testing.T) {
dir := t.TempDir()
src := filepath.Join(dir, "memo.pdf")
_ = os.WriteFile(src, []byte("%PDF-1.4 memo"), 0o600)
out := filepath.Join(dir, "out")
client := &veraeapi.Client{
Channel: auth.ChannelVerae,
VeraeBase: "https://api.test",
VeraeToken: "jwt",
HTTPDo: func(req *http.Request) (*http.Response, error) {
body := `{"existing":true,"certificate":"cidLocal1","receipts":[{"certificate":"cidLocal1","completedAt":"2026-10-03T12:00:00Z","blockIndex":"99"}]}`
if strings.HasPrefix(req.URL.Path, "/api/hash/") {
body = `{"receipts":[{"certificate":"cidLocal1","completedAt":"2026-10-03T12:00:00Z","blockIndex":"99"}]}`
}
return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(body)), Header: make(http.Header)}, nil
},
}
res, err := Run(Options{SourcePDF: src, OutDir: out, Channel: auth.ChannelVerae, Client: client})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(res.CertificatePDF, "memo-verae-timestamp-cidLocal1.pdf") {
t.Fatal(res.CertificatePDF)
}
b, _ := os.ReadFile(res.CertificatePDF)
if !strings.HasPrefix(string(b), "%PDF") {
t.Fatal("not a pdf")
}
}
func TestRunNeverOverwritesSameName(t *testing.T) {
dir := t.TempDir()
out := filepath.Join(dir, "out")
n := 0
client := &veraeapi.Client{
Channel: auth.ChannelZapier,
ZapierBase: "https://zap.test",
XVeraeToken: "xVerae-x",
HTTPDo: func(req *http.Request) (*http.Response, error) {
n++
// same receipt id every time, to also exercise cert-name collisions
body := `{"receipt_id":"bafySame"}`
return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(body)), Header: make(http.Header)}, nil
},
}
var results []Result
for i, content := range []string{"%PDF-1.4 first", "%PDF-1.4 second", "%PDF-1.4 third"} {
src := filepath.Join(dir, "src"+string(rune('a'+i))+".pdf")
_ = os.WriteFile(src, []byte(content), 0o600)
res, err := Run(Options{SourcePDF: src, OutDir: out, DocumentName: "Printed 2026-10-03 192901.pdf", Channel: auth.ChannelZapier, Client: client})
if err != nil {
t.Fatal(err)
}
results = append(results, res)
}
wantOrig := []string{"Printed 2026-10-03 192901.pdf", "Printed 2026-10-03 192901-2.pdf", "Printed 2026-10-03 192901-3.pdf"}
wantJSON := []string{"Printed-2026-10-03-192901.verae.json", "Printed-2026-10-03-192901-2.verae.json", "Printed-2026-10-03-192901-3.verae.json"}
wantCert := []string{"Printed-2026-10-03-192901-verae-timestamp-bafySame.pdf", "Printed-2026-10-03-192901-2-verae-timestamp-bafySame.pdf", "Printed-2026-10-03-192901-3-verae-timestamp-bafySame.pdf"}
for i, r := range results {
if filepath.Base(r.OriginalPDF) != wantOrig[i] || filepath.Base(r.ReceiptJSON) != wantJSON[i] || filepath.Base(r.CertificatePDF) != wantCert[i] {
t.Fatalf("job %d: %s | %s | %s", i, filepath.Base(r.OriginalPDF), filepath.Base(r.ReceiptJSON), filepath.Base(r.CertificatePDF))
}
}
if b, _ := os.ReadFile(results[0].OriginalPDF); string(b) != "%PDF-1.4 first" {
t.Fatalf("first original overwritten: %q", b)
}
// a pre-existing cert with the target name is never overwritten
p, err := writeExclusive(out, "Printed-2026-10-03-192901-verae-timestamp-bafySame", ".pdf", []byte("x"))
if err != nil || filepath.Base(p) != "Printed-2026-10-03-192901-verae-timestamp-bafySame-2.pdf" {
t.Fatal(p, err)
}
}
func TestRunWithChosenPath(t *testing.T) {
dir := t.TempDir()
src := filepath.Join(dir, "spool.pdf")
_ = os.WriteFile(src, []byte("%PDF-1.4 new"), 0o600)
pick := filepath.Join(dir, "My Contract v2.pdf")
_ = os.WriteFile(pick, []byte("old"), 0o600) // user confirmed "Replace"
client := &veraeapi.Client{Channel: auth.ChannelZapier, ZapierBase: "https://zap.test", XVeraeToken: "xVerae-x",
HTTPDo: func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(`{"receipt_id":"bafyR1"}`)), Header: make(http.Header)}, nil
}}
for i := 0; i < 2; i++ {
res, err := Run(Options{SourcePDF: src, OutPath: pick, Channel: auth.ChannelZapier, Client: client})
if err != nil {
t.Fatal(err)
}
if res.OriginalPDF != pick {
t.Fatal(res.OriginalPDF)
}
wantCert := "My Contract v2-verae-timestamp-bafyR1.pdf"
wantJSON := "My Contract v2.verae.json"
if i == 1 {
wantCert = "My Contract v2-verae-timestamp-bafyR1-2.pdf"
wantJSON = "My Contract v2-2.verae.json"
}
if filepath.Base(res.CertificatePDF) != wantCert || filepath.Base(res.ReceiptJSON) != wantJSON {
t.Fatalf("run %d: %s %s", i, filepath.Base(res.CertificatePDF), filepath.Base(res.ReceiptJSON))
}
}
if b, _ := os.ReadFile(pick); string(b) != "%PDF-1.4 new" {
t.Fatal("original not written to chosen path")
}
}