add LIKE substring fallback to search and update plan statuses
FTS5 prefix matching misses mid-word substrings (e.g. "ebook" in "notebook"). When FTS5 returns zero results, fall back to LIKE query on title and category with proper wildcard escaping. 4 new tests, 757 total. Also marks completed plan files (search, admin-redesign, setup-wizard, products-context) with correct status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -169,18 +169,24 @@ defmodule SimpleshopTheme.SearchTest do
|
||||
|
||||
describe "index_product/1" do
|
||||
test "indexes a single product", %{ocean: ocean} do
|
||||
# Clear and rebuild without ocean
|
||||
# Clear FTS index
|
||||
SimpleshopTheme.Repo.query!("DELETE FROM products_search_map")
|
||||
SimpleshopTheme.Repo.query!("DELETE FROM products_search")
|
||||
|
||||
assert Search.search("ocean") == []
|
||||
# Verify FTS index is empty
|
||||
%{rows: rows} = SimpleshopTheme.Repo.query!("SELECT COUNT(*) FROM products_search_map")
|
||||
assert rows == [[0]]
|
||||
|
||||
# Index just ocean
|
||||
ocean = SimpleshopTheme.Repo.preload(ocean, [:variants])
|
||||
Search.index_product(ocean)
|
||||
|
||||
# Verify ocean is now in the FTS index
|
||||
%{rows: [[count]]} = SimpleshopTheme.Repo.query!("SELECT COUNT(*) FROM products_search_map")
|
||||
assert count == 1
|
||||
|
||||
results = Search.search("ocean")
|
||||
assert length(results) == 1
|
||||
assert length(results) >= 1
|
||||
assert hd(results).id == ocean.id
|
||||
end
|
||||
|
||||
@@ -197,13 +203,41 @@ defmodule SimpleshopTheme.SearchTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "LIKE fallback" do
|
||||
test "finds substring matches that FTS5 prefix misses", %{ocean: ocean} do
|
||||
# "ebook" is in the middle of "Notebook" — FTS5 prefix won't match
|
||||
results = Search.search("ebook")
|
||||
assert Enum.any?(results, &(&1.id == ocean.id))
|
||||
end
|
||||
|
||||
test "falls back to category substring match", %{forest: forest} do
|
||||
# "ppar" is a substring of "Apparel" — FTS5 prefix won't match
|
||||
results = Search.search("pparel")
|
||||
assert Enum.any?(results, &(&1.id == forest.id))
|
||||
end
|
||||
end
|
||||
|
||||
describe "remove_product/1" do
|
||||
test "removes a product from the index", %{ocean: ocean} do
|
||||
assert Search.search("ocean") != []
|
||||
# Verify ocean is in the FTS index
|
||||
%{rows: [[rowid]]} =
|
||||
SimpleshopTheme.Repo.query!(
|
||||
"SELECT rowid FROM products_search_map WHERE product_id = ?1",
|
||||
[ocean.id]
|
||||
)
|
||||
|
||||
assert rowid
|
||||
|
||||
Search.remove_product(ocean.id)
|
||||
|
||||
assert Search.search("ocean") == []
|
||||
# Verify it's gone from the FTS index
|
||||
%{rows: rows} =
|
||||
SimpleshopTheme.Repo.query!(
|
||||
"SELECT rowid FROM products_search_map WHERE product_id = ?1",
|
||||
[ocean.id]
|
||||
)
|
||||
|
||||
assert rows == []
|
||||
end
|
||||
|
||||
test "is a no-op for unindexed product" do
|
||||
|
||||
Reference in New Issue
Block a user