feat(inventory-go): wire spell filters into /search/items; harden empty-input guards
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
4edf94f416
commit
7096f30566
3 changed files with 23 additions and 3 deletions
|
|
@ -302,6 +302,9 @@ func (s *Server) runSearch(ctx context.Context, q url.Values) (map[string]any, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- spell filters: has_spell / spell_contains / legendary_cantrips ---
|
||||||
|
conds = append(conds, spellFilterConds(q, s.spells, ab)...)
|
||||||
|
|
||||||
where := ""
|
where := ""
|
||||||
if len(conds) > 0 {
|
if len(conds) > 0 {
|
||||||
where = " WHERE " + strings.Join(conds, " AND ")
|
where = " WHERE " + strings.Join(conds, " AND ")
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ func exactSpellID(spells map[int]map[string]any, q string) (int, bool) {
|
||||||
best := -1
|
best := -1
|
||||||
for id, sp := range spells {
|
for id, sp := range spells {
|
||||||
name, _ := sp["name"].(string)
|
name, _ := sp["name"].(string)
|
||||||
|
if name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if strings.ToLower(name) == q && (best == -1 || id < best) {
|
if strings.ToLower(name) == q && (best == -1 || id < best) {
|
||||||
best = id
|
best = id
|
||||||
}
|
}
|
||||||
|
|
@ -79,21 +82,21 @@ func spellFilterConds(q url.Values, spells map[int]map[string]any, ab *argBuilde
|
||||||
var conds []string
|
var conds []string
|
||||||
impossible := func() { conds = append(conds, "1 = 0") }
|
impossible := func() { conds = append(conds, "1 = 0") }
|
||||||
|
|
||||||
if v := q.Get("has_spell"); v != "" {
|
if v := strings.TrimSpace(q.Get("has_spell")); v != "" {
|
||||||
if id, ok := exactSpellID(spells, v); ok {
|
if id, ok := exactSpellID(spells, v); ok {
|
||||||
conds = append(conds, spellExists([]int{id}, ab))
|
conds = append(conds, spellExists([]int{id}, ab))
|
||||||
} else {
|
} else {
|
||||||
impossible()
|
impossible()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v := q.Get("spell_contains"); v != "" {
|
if v := strings.TrimSpace(q.Get("spell_contains")); v != "" {
|
||||||
if ids := spellIDsContaining(spells, v); len(ids) > 0 {
|
if ids := spellIDsContaining(spells, v); len(ids) > 0 {
|
||||||
conds = append(conds, spellExists(ids, ab))
|
conds = append(conds, spellExists(ids, ab))
|
||||||
} else {
|
} else {
|
||||||
impossible()
|
impossible()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v := q.Get("legendary_cantrips"); v != "" {
|
if v := strings.TrimSpace(q.Get("legendary_cantrips")); v != "" {
|
||||||
for _, name := range splitNonEmpty(v) {
|
for _, name := range splitNonEmpty(v) {
|
||||||
if ids := spellIDsForCantrip(spells, name); len(ids) > 0 {
|
if ids := spellIDsForCantrip(spells, name); len(ids) > 0 {
|
||||||
conds = append(conds, spellExists(ids, ab))
|
conds = append(conds, spellExists(ids, ab))
|
||||||
|
|
|
||||||
|
|
@ -112,3 +112,17 @@ func TestSpellFilterConds_Empty(t *testing.T) {
|
||||||
t.Errorf("no params => nil conds, got %v", conds)
|
t.Errorf("no params => nil conds, got %v", conds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSpellFilterConds_WhitespaceParamsIgnored(t *testing.T) {
|
||||||
|
ab := &argBuilder{}
|
||||||
|
q := map[string][]string{"spell_contains": {" "}, "has_spell": {" "}, "legendary_cantrips": {" , "}}
|
||||||
|
if conds := spellFilterConds(q, testSpells, ab); conds != nil {
|
||||||
|
t.Errorf("whitespace params => nil conds, got %v", conds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExactSpellID_EmptyNeverMatchesMalformed(t *testing.T) {
|
||||||
|
if _, ok := exactSpellID(testSpells, ""); ok {
|
||||||
|
t.Error("empty query must not match the malformed empty-name entry")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue