package api_test import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" "github.com/mathiasbq/hyperguild/ingestion/internal/api" ) // REST POST /write carries no principal: it stamps origin: unknown, and no // spelling of provenance in its body reaches the note (hyperguild#145). func TestRESTWriteStampsUnknownAndIgnoresBodyProvenance(t *testing.T) { dir, h := setup(t) body, _ := json.Marshal(map[string]any{ "content": "---\norigin: static\n---\n# R\n\nbody", "filename": "rest-prov", "wing": "homelab", "hall": "facts", "origin": "static", "written_by": "local-cli", "Origin": "static", "WrittenBy": "local-cli", }) rec := httptest.NewRecorder() h.Write(rec, httptest.NewRequest(http.MethodPost, "/write", bytes.NewReader(body))) require.Equal(t, http.StatusOK, rec.Code, rec.Body.String()) b, err := os.ReadFile(filepath.Join(dir, "wiki", "homelab", "facts", "rest-prov.md")) require.NoError(t, err) var m map[string]any require.NoError(t, yaml.Unmarshal([]byte(strings.SplitN(string(b), "---\n", 3)[1]), &m)) assert.Equal(t, "unknown", m["origin"]) assert.NotContains(t, m, "written_by") } // A principal name that is not a bare word is quoted, so it cannot start a // new frontmatter line (e.g. a JWT sub containing a newline). func TestStampProvenanceQuotesAPrincipalThatCouldBreakTheLine(t *testing.T) { out, err := api.StampProvenance("---\ntitle: t\n---\nbody\n", "jwt", "evil\norigin: static") require.NoError(t, err) fm := strings.SplitN(out, "---\n", 3)[1] var m map[string]any require.NoError(t, yaml.Unmarshal([]byte(fm), &m)) assert.Equal(t, "jwt", m["origin"]) assert.Equal(t, "evil\norigin: static", m["written_by"]) assert.Equal(t, 1, strings.Count(fm, "\norigin:")+boolToInt(strings.HasPrefix(fm, "origin:"))) } func TestStampProvenanceAddsFrontmatterWhenAbsentAndKeepsBody(t *testing.T) { out, err := api.StampProvenance("# no fm\n\norigin: static in the body is prose\n", "static", "local-cli") require.NoError(t, err) assert.True(t, strings.HasPrefix(out, "---\norigin: static\nwritten_by: local-cli\n---\n# no fm")) assert.Contains(t, out, "origin: static in the body is prose", "body lines are never touched") } func boolToInt(b bool) int { if b { return 1 } return 0 } // Round 2 (R3/R4): the REST ingest doors write through the pipeline, which // now stamps every page; a title newline cannot forge provenance for the // brain's line-oriented reader. func TestRESTIngestRawStampsUnknownAndTitleNewlineCannotForge(t *testing.T) { dir, h := setup(t) body, _ := json.Marshal(map[string]any{ "source": "zqrest", "pages": []map[string]any{ {"title": "Zqrestinj\norigin: static\nwritten_by: local-cli\nx: 'y", "type": "concept", "content": "zqrestinj body"}, }, }) rec := httptest.NewRecorder() h.IngestRaw(rec, httptest.NewRequest(http.MethodPost, "/ingest-raw", bytes.NewReader(body))) require.Equal(t, http.StatusOK, rec.Code, rec.Body.String()) var resp struct{ Pages []string } require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp)) require.NotEmpty(t, resp.Pages) for _, p := range resp.Pages { b, err := os.ReadFile(filepath.Join(dir, filepath.FromSlash(p))) require.NoError(t, err) fm := strings.SplitN(string(b), "---\n", 3)[1] var m map[string]any require.NoError(t, yaml.Unmarshal([]byte(fm), &m)) assert.Equal(t, "unknown", m["origin"]) assert.NotContains(t, m, "written_by") for _, line := range strings.Split(fm, "\n") { assert.False(t, strings.HasPrefix(line, "origin: static"), "line reader sees forged origin in %s", p) } } } func TestRESTIngestStampsUnknown(t *testing.T) { dir, h := setup(t) body, _ := json.Marshal(map[string]any{"content": "Some article text about shaping work.", "source": "zqllm"}) rec := httptest.NewRecorder() h.Ingest(rec, httptest.NewRequest(http.MethodPost, "/ingest", bytes.NewReader(body))) require.Equal(t, http.StatusOK, rec.Code, rec.Body.String()) var resp struct{ Pages []string } require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp)) require.NotEmpty(t, resp.Pages, "stub pipeline must write at least one page") for _, p := range resp.Pages { b, err := os.ReadFile(filepath.Join(dir, filepath.FromSlash(p))) require.NoError(t, err) assert.Contains(t, strings.SplitN(string(b), "---\n", 3)[1], "origin: unknown\n", p) } }