feat: 配方查询支持按精油名搜索
All checks were successful
Test / unit-test (push) Successful in 6s
PR Preview / teardown-preview (pull_request) Has been skipped
Test / build-check (push) Successful in 9s
Test / e2e-test (push) Successful in 3m1s
PR Preview / test (pull_request) Successful in 6s
PR Preview / deploy-preview (pull_request) Successful in 20s
All checks were successful
Test / unit-test (push) Successful in 6s
PR Preview / teardown-preview (pull_request) Has been skipped
Test / build-check (push) Successful in 9s
Test / e2e-test (push) Successful in 3m1s
PR Preview / test (pull_request) Successful in 6s
PR Preview / deploy-preview (pull_request) Successful in 20s
输入精油中文名/英文名会返回含该精油的所有配方。 中文查询 ≥2 字才匹配精油,避免「草」这样的单字噪音。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
57
frontend/src/__tests__/recipeSearchByOil.test.js
Normal file
57
frontend/src/__tests__/recipeSearchByOil.test.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
|
||||
// Mirrors the exactResults matching rule in RecipeSearch.vue
|
||||
function matches(recipes, q, oilEn = (s) => '') {
|
||||
const query = (q || '').trim().toLowerCase()
|
||||
if (!query) return []
|
||||
const isEn = /^[a-zA-Z\s]+$/.test(query)
|
||||
return recipes.filter(r => {
|
||||
if (r.tags && r.tags.includes('已下架')) return false
|
||||
const nameMatch = r.name.toLowerCase().includes(query)
|
||||
const enNameMatch = isEn && (r.en_name || '').toLowerCase().includes(query)
|
||||
const oilEnMatch = isEn && (r.ingredients || []).some(ing => (oilEn(ing.oil) || '').toLowerCase().includes(query))
|
||||
const oilZhMatch = query.length >= 2 && (r.ingredients || []).some(ing => ing.oil.toLowerCase().includes(query))
|
||||
const tagMatch = (r.tags || []).some(t => t.toLowerCase().includes(query))
|
||||
return nameMatch || enNameMatch || oilEnMatch || oilZhMatch || tagMatch
|
||||
})
|
||||
}
|
||||
|
||||
const recipes = [
|
||||
{ name: '助眠晚安', tags: [], ingredients: [{ oil: '薰衣草', drops: 3 }, { oil: '乳香', drops: 2 }] },
|
||||
{ name: '提神醒脑', tags: [], ingredients: [{ oil: '椒样薄荷', drops: 2 }, { oil: '柠檬', drops: 3 }] },
|
||||
{ name: '肩颈舒缓', tags: ['舒缓'], ingredients: [{ oil: '西班牙牛至', drops: 1 }, { oil: '椰子油', drops: 10 }] },
|
||||
{ name: '感冒护理', tags: [], ingredients: [{ oil: '牛至呵护', drops: 2 }] },
|
||||
{ name: '下架配方', tags: ['已下架'], ingredients: [{ oil: '薰衣草', drops: 1 }] },
|
||||
]
|
||||
|
||||
describe('Recipe search by oil name', () => {
|
||||
it('finds recipes containing the oil (Chinese exact)', () => {
|
||||
const r = matches(recipes, '薰衣草')
|
||||
expect(r.map(x => x.name)).toEqual(['助眠晚安'])
|
||||
})
|
||||
|
||||
it('finds multiple recipes for a common oil', () => {
|
||||
expect(matches(recipes, '牛至').map(x => x.name).sort()).toEqual(['感冒护理', '肩颈舒缓'])
|
||||
})
|
||||
|
||||
it('excludes 已下架 recipes', () => {
|
||||
const r = matches(recipes, '薰衣草')
|
||||
expect(r.some(x => x.name === '下架配方')).toBe(false)
|
||||
})
|
||||
|
||||
it('single-char query does not match oil names (avoids noise)', () => {
|
||||
const r = matches(recipes, '草')
|
||||
expect(r).toEqual([])
|
||||
})
|
||||
|
||||
it('still matches recipe name for short queries', () => {
|
||||
const r = matches(recipes, '晚')
|
||||
expect(r.map(x => x.name)).toEqual(['助眠晚安'])
|
||||
})
|
||||
|
||||
it('matches english oil name when query is english', () => {
|
||||
const oilEn = (o) => ({ '薰衣草': 'Lavender', '乳香': 'Frankincense' }[o] || '')
|
||||
const r = matches(recipes, 'Lavender', oilEn)
|
||||
expect(r.map(x => x.name)).toEqual(['助眠晚安'])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user