File size: 6,033 Bytes
d992912
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import pytest
from backend.app.engine.query_parser import QueryParser, ParsedQuery


@pytest.fixture
def parser():
    return QueryParser()


class TestCategoryParsing:
    def test_dress(self, parser):
        result = parser.parse("black midi dress")
        assert result.category_filter == "Dresses"

    def test_jacket(self, parser):
        result = parser.parse("leather jacket")
        assert result.category_filter == "Coats & Jackets"

    def test_jeans(self, parser):
        result = parser.parse("blue jeans")
        assert result.category_filter == "Jeans"

    def test_hoodie(self, parser):
        result = parser.parse("oversized hoodie")
        assert result.category_filter == "Hoodies & Sweatshirts"

    def test_trainers(self, parser):
        result = parser.parse("white trainers")
        assert result.category_filter == "Shoes"

    def test_bag(self, parser):
        result = parser.parse("leather bag")
        assert result.category_filter == "Bags"

    def test_no_category(self, parser):
        result = parser.parse("something nice")
        assert result.category_filter is None

    def test_multi_word_category(self, parser):
        result = parser.parse("puffer jacket warm")
        assert result.category_filter == "Coats & Jackets"


class TestColorParsing:
    def test_basic_color(self, parser):
        result = parser.parse("black dress")
        assert result.color_filter == "black"

    def test_synonym_color(self, parser):
        result = parser.parse("scarlet top")
        assert result.color_filter == "red"

    def test_navy(self, parser):
        result = parser.parse("navy blazer")
        assert result.color_filter == "navy"

    def test_multi_word_color(self, parser):
        result = parser.parse("sky blue dress")
        assert result.color_filter == "blue"

    def test_no_color(self, parser):
        result = parser.parse("casual hoodie")
        assert result.color_filter is None


class TestPriceParsing:
    def test_under(self, parser):
        result = parser.parse("dress under £40")
        assert result.price_max == 40.0
        assert result.price_min is None

    def test_over(self, parser):
        result = parser.parse("jacket over £100")
        assert result.price_min == 100.0

    def test_range(self, parser):
        result = parser.parse("shoes £20-£50")
        assert result.price_min == 20.0
        assert result.price_max == 50.0

    def test_budget(self, parser):
        result = parser.parse("budget dress")
        assert result.price_max == 30.0

    def test_luxury(self, parser):
        result = parser.parse("luxury jacket")
        assert result.price_min == 100.0

    def test_no_price(self, parser):
        result = parser.parse("blue dress")
        assert result.price_min is None
        assert result.price_max is None


class TestGenderParsing:
    def test_mens(self, parser):
        result = parser.parse("mens hoodie")
        assert result.gender_filter == "Men"

    def test_womens(self, parser):
        result = parser.parse("for women dress")
        assert result.gender_filter == "Women"

    def test_ladies(self, parser):
        result = parser.parse("ladies dress elegant")
        assert result.gender_filter == "Women"

    def test_no_gender(self, parser):
        result = parser.parse("casual hoodie")
        assert result.gender_filter is None


class TestMaterialParsing:
    def test_silk(self, parser):
        result = parser.parse("silk midi dress")
        assert result.material_filter == "silk"

    def test_leather(self, parser):
        result = parser.parse("leather jacket")
        assert result.material_filter == "leather"

    def test_denim(self, parser):
        result = parser.parse("denim jacket")
        assert result.material_filter == "denim"

    def test_no_material(self, parser):
        result = parser.parse("black dress")
        assert result.material_filter is None


class TestSizeParsing:
    def test_named_size(self, parser):
        result = parser.parse("size small hoodie")
        assert result.size_filter == "S"

    def test_numeric_size(self, parser):
        result = parser.parse("size 10 dress")
        assert result.size_filter == "10"

    def test_xl(self, parser):
        result = parser.parse("XL casual shirt")
        assert result.size_filter == "XL"

    def test_no_size(self, parser):
        result = parser.parse("black dress")
        assert result.size_filter is None


class TestExclusions:
    def test_not(self, parser):
        result = parser.parse("black dress not floral")
        assert "floral" in result.exclusions

    def test_without(self, parser):
        result = parser.parse("jacket without leather")
        assert "leather" in result.exclusions

    def test_no_keyword(self, parser):
        result = parser.parse("summer top no black")
        assert "black" in result.exclusions

    def test_material_exclusion_conflict(self, parser):
        result = parser.parse("jacket not cotton")
        assert result.material_filter is None
        assert "cotton" in result.exclusions

    def test_no_exclusions(self, parser):
        result = parser.parse("black dress")
        assert result.exclusions == []


class TestStyleTags:
    def test_single_tag(self, parser):
        result = parser.parse("casual hoodie")
        assert "casual" in result.style_tags

    def test_multiple_tags(self, parser):
        result = parser.parse("vintage boho dress")
        assert "vintage" in result.style_tags
        assert "boho" in result.style_tags

    def test_no_tags(self, parser):
        result = parser.parse("blue jeans")
        assert "casual" not in result.style_tags


class TestVibeText:
    def test_preserves_raw_query(self, parser):
        result = parser.parse("black dress under £40")
        assert result.raw_query == "black dress under £40"

    def test_vibe_not_empty(self, parser):
        result = parser.parse("black dress")
        assert len(result.vibe_text) > 0