Skip to main content

tests/javascript/test_chives_sorting.py

1"""
2Tests for ChivesSorting and the <chives-sort-options> web component.
3"""
5import json
6from typing import Any
8from playwright.sync_api import expect, Page
9import pytest
11from chives.browser_fixtures import file_uri
14def apply_sorting(
15 page: Page,
16 *,
17 sorting_config_json: str,
18 url_query: str,
19 default_sort_order: str,
20 items: Any,
21) -> None:
22 """
23 Sort a list of items and the sorting controls on the page.
24 """
25 page.goto("about:blank")
27 with open("javascript/chives-sorting.js") as f:
28 component_js = f.read()
30 page.evaluate(
31 """
32 %s
33 const sortOptions = %s;
34 const searchParams = new URLSearchParams(%s);
35 const sorting = new ChivesSorting(sortOptions, searchParams);
37 const defaultSortOrder = %s;
38 if (defaultSortOrder) {
39 sorting.defaultSortOrder = defaultSortOrder;
40 }
42 const items = %s;
43 const sortedItems = sorting.apply(items);
45 const listOfItems = document.createElement("p");
46 listOfItems.innerText = JSON.stringify(sortedItems);
47 document.body.appendChild(listOfItems);
49 renderSortingControls({
50 "querySelector": "body",
51 sorting,
52 searchParams,
53 });
54 """
55 % (
56 component_js,
57 sorting_config_json.strip(),
58 json.dumps(url_query),
59 json.dumps(default_sort_order),
60 json.dumps(items),
61 )
62 )
65@pytest.mark.parametrize(
66 "url_query, expected_items, default_sort_order, expected_sort_order_key",
67 [
68 ("", '["apple","banana","coconut","date","elderberry"]', "", "AtoZ"),
69 (
70 "sortOrder=AtoZ",
71 '["apple","banana","coconut","date","elderberry"]',
72 "",
73 "AtoZ",
74 ),
75 (
76 "sortOrder=ZtoA",
77 '["elderberry","date","coconut","banana","apple"]',
78 "",
79 "ZtoA",
80 ),
81 # Default sort order is used if URL params don't specify
82 ("", '["elderberry","date","coconut","banana","apple"]', "ZtoA", "ZtoA"),
83 (
84 "sortOrder=length",
85 '["date","apple","banana","coconut","elderberry"]',
86 "ZtoA",
87 "length",
88 ),
89 # Unrecognised sort order => falls back to the first in the list
90 (
91 "sortOrder=unknown",
92 '["apple","banana","coconut","date","elderberry"]',
93 "",
94 "AtoZ",
95 ),
96 ],
98def test_render_basic_sorting(
99 page: Page,
100 url_query: str,
101 expected_items: str,
102 default_sort_order: str,
103 expected_sort_order_key: str,
104) -> None:
105 """
106 Test basic sorting order and controls.
107 """
108 apply_sorting(
109 page,
110 sorting_config_json="""
111 [
112 {
113 key: "AtoZ",
114 label: "title (A to Z)",
115 compareFn: (a, b) => a > b ? 1 : -1,
116 },
117 {
118 key: "ZtoA",
119 label: "title (Z to A)",
120 compareFn: (a, b) => a > b ? -1 : 1,
121 },
122 {
123 key: "length",
124 label: "length",
125 compareFn: (a, b) => a.length - b.length,
126 },
127 ]
128 """,
129 url_query=url_query,
130 default_sort_order=default_sort_order,
131 items=["apple", "banana", "coconut", "date", "elderberry"],
132 )
134 items_elem = page.locator("p")
135 assert items_elem.inner_text() == expected_items
137 sorting_elem = page.locator("chives-sort-options")
138 expect(sorting_elem).to_be_visible()
139 assert (
140 sorting_elem.locator("option[selected]").get_attribute("value")
141 == expected_sort_order_key
142 )
145def test_selecting_a_sort_order_resets_page_number(page: Page) -> None:
146 """
147 Selecting a sort order resets the page number.
148 """
149 uri = (
150 file_uri("tests/fixtures/html/greeting.html")
151 + "?sortOrder=ZtoA&page=2&tag=cats"
152 )
153 page.goto(uri)
155 with open("javascript/chives-sorting.js") as f:
156 component_js = f.read()
158 page.evaluate(
159 """
160 %s
161 const sortOptions = [
162 {key: "AtoZ", label: "title (A to Z)", compareFn: (a, b) => 1},
163 {key: "ZtoA", label: "title (Z to A)", compareFn: (a, b) => 1},
164 ];
165 const searchParams = new URLSearchParams(window.location.search);
166 const sorting = new ChivesSorting(sortOptions, searchParams);
168 const items = ["apple", "banana", "coconut", "date", "elderberry"];
169 const sortedItems = sorting.apply(items);
171 renderSortingControls({
172 "querySelector": "body",
173 sorting,
174 searchParams,
175 });
176 """
177 % component_js
178 )
180 assert page.locator("option").count() == 2
182 with page.expect_navigation():
183 page.get_by_label("sort by:").select_option("title (A to Z)")
185 assert "sortOrder=AtoZ" in page.url
186 assert "page=" not in page.url