package find import ( "bytes" "os" "testing" "git.smesh.lol/nostr/pkg/event" "git.smesh.lol/nostr/pkg/signer/p8k" "git.smesh.lol/morly/pkg/store" ) // openTmp opens a store in a fresh directory. The caller owns both: defer // os.RemoveAll(dir) and defer eng.Close(). func openTmp(t *testing.T) (p *store.Engine, dir string) { t.Helper() dir, derr := os.MkdirTemp("", "moxie-test") if derr != nil { t.Fatal(derr) } eng, err := store.Open(dir) if err != nil { t.Fatal(err) } return eng, dir } func makeEvent(t *testing.T, s *p8k.Signer, content string, ts int64) (p *event.E) { t.Helper() ev := &event.E{ CreatedAt: ts, Kind: 1, Content: []byte(content), } if err := ev.Sign(s); err != nil { t.Fatal(err) } return ev } func TestSplitWords(t *testing.T) { tests := []struct { input string want []string }{ {"hello world", []string{"hello", "world"}}, {"Hi There", []string{"there"}}, // "hi" too short {"a bb ccc", []string{"ccc"}}, // min 3 chars {"foo123 bar", []string{"foo123", "bar"}}, // alphanumeric {"", nil}, } for _, tt := range tests { got := SplitWords([]byte(tt.input)) if len(got) != len(tt.want) { t.Errorf("SplitWords(%q): got %d words, want %d", tt.input, len(got), len(tt.want)) continue } for i := range got { if string(got[i]) != tt.want[i] { t.Errorf("SplitWords(%q)[%d] = %q, want %q", tt.input, i, got[i], tt.want[i]) } } } } func TestSearchFindsEvent(t *testing.T) { eng, dir := openTmp(t) defer os.RemoveAll(dir) defer eng.Close() s := p8k.MustNew() if err := s.Generate(); err != nil { t.Fatal(err) } ev := makeEvent(t, s, "the quick brown fox jumps", 1700000000) if err := eng.SaveEvent(ev); err != nil { t.Fatal(err) } f := New(eng) results := f.Search([]byte("quick brown"), 10) if len(results) != 1 { t.Fatalf("expected 1 result, got %d", len(results)) } if !bytes.Equal(results[0].ID, ev.ID) { t.Error("result ID mismatch") } } func TestSearchNoMatch(t *testing.T) { eng, dir := openTmp(t) defer os.RemoveAll(dir) defer eng.Close() s := p8k.MustNew() if err := s.Generate(); err != nil { t.Fatal(err) } if err := eng.SaveEvent(makeEvent(t, s, "hello world foo", 1700000000)); err != nil { t.Fatal(err) } f := New(eng) results := f.Search([]byte("nonexistent"), 10) if len(results) != 0 { t.Fatalf("expected 0 results, got %d", len(results)) } } func TestSearchLimit(t *testing.T) { eng, dir := openTmp(t) defer os.RemoveAll(dir) defer eng.Close() s := p8k.MustNew() if err := s.Generate(); err != nil { t.Fatal(err) } for i := 0; i < 5; i++ { if err := eng.SaveEvent(makeEvent(t, s, "testing search limit feature", int64(1700000000+i))); err != nil { t.Fatal(err) } } f := New(eng) results := f.Search([]byte("testing search"), 2) if len(results) != 2 { t.Fatalf("expected 2 results, got %d", len(results)) } }