Clear pre-existing ruff lint + format debt (make check now green)
This commit is contained in:
@@ -17,7 +17,6 @@ widget into a ``DateCriterion`` unchanged. All behaviour is wired by
|
|||||||
``games/static/js/date_range_picker.js``.
|
``games/static/js/date_range_picker.js``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from common.components.core import Element, HTMLAttribute, Media, Node, Safe
|
from common.components.core import Element, HTMLAttribute, Media, Node, Safe
|
||||||
from common.components.primitives import Div, Input, Span
|
from common.components.primitives import Div, Input, Span
|
||||||
from common.time import DatePartSpec, date_parts
|
from common.time import DatePartSpec, date_parts
|
||||||
@@ -101,9 +100,7 @@ def _iso_part_values(iso_value: str, parts: list[DatePartSpec]) -> dict[str, str
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
def _segment_input(
|
def _segment_input(*, part: DatePartSpec, side: str, label: str, value: str) -> Node:
|
||||||
*, part: DatePartSpec, side: str, label: str, value: str
|
|
||||||
) -> Node:
|
|
||||||
side_label = "from" if side == "min" else "to"
|
side_label = "from" if side == "min" else "to"
|
||||||
return Input(
|
return Input(
|
||||||
attributes=[
|
attributes=[
|
||||||
|
|||||||
@@ -173,9 +173,7 @@ def _split_modifier(modifier: str, has_m2m: bool = False) -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def _enum_filter(
|
def _enum_filter(field_name: str, options, choice: FilterChoice, *, nullable) -> Node:
|
||||||
field_name: str, options, choice: FilterChoice, *, nullable
|
|
||||||
) -> Node:
|
|
||||||
"""A FilterSelect over a small, fully pre-rendered option set (enum field).
|
"""A FilterSelect over a small, fully pre-rendered option set (enum field).
|
||||||
|
|
||||||
Enum fields are single-valued, so no M2M modifiers (all/only are
|
Enum fields are single-valued, so no M2M modifiers (all/only are
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import pytest
|
|||||||
# synchronous operations inside the async context safely.
|
# synchronous operations inside the async context safely.
|
||||||
os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
|
os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def browser_type_launch_args(browser_type_launch_args):
|
def browser_type_launch_args(browser_type_launch_args):
|
||||||
# Try to find a system-installed Google Chrome or Chromium to bypass Nix/NixOS shared library issues
|
# Try to find a system-installed Google Chrome or Chromium to bypass Nix/NixOS shared library issues
|
||||||
|
|||||||
@@ -121,9 +121,7 @@ def test_max_only_serializes_as_less_than(live_server, page):
|
|||||||
".dispatchEvent(new Event('submit', {cancelable: true}))"
|
".dispatchEvent(new Event('submit', {cancelable: true}))"
|
||||||
)
|
)
|
||||||
parsed = _filter_from_url(page.url)
|
parsed = _filter_from_url(page.url)
|
||||||
assert parsed == {
|
assert parsed == {"date_refunded": {"value": "2025-06-30", "modifier": "LESS_THAN"}}
|
||||||
"date_refunded": {"value": "2025-06-30", "modifier": "LESS_THAN"}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
"""End-to-end Playwright test for the RangeSlider JS synchronization, cross-over, and clamping behavior.
|
"""End-to-end Playwright test for the RangeSlider JS synchronization, cross-over, and clamping behavior."""
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import urllib.parse
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
@@ -101,7 +97,9 @@ def test_range_slider_empty_max_thumb_does_not_jump_to_beginning(live_server, pa
|
|||||||
page.goto(live_server.url + "/test-range-slider/")
|
page.goto(live_server.url + "/test-range-slider/")
|
||||||
|
|
||||||
# Locate handles
|
# Locate handles
|
||||||
max_handle = page.locator('.range-handle-max[data-target="filter-session-count-max"]')
|
max_handle = page.locator(
|
||||||
|
'.range-handle-max[data-target="filter-session-count-max"]'
|
||||||
|
)
|
||||||
|
|
||||||
# Initially, max_input is empty, so handle should sit at 100% (far right)
|
# Initially, max_input is empty, so handle should sit at 100% (far right)
|
||||||
style = max_handle.get_attribute("style")
|
style = max_handle.get_attribute("style")
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ def prefilled_bar_view(request):
|
|||||||
"value": "Switch",
|
"value": "Switch",
|
||||||
"modifier": "INCLUDES",
|
"modifier": "INCLUDES",
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {"modifier": "IS_NULL"},
|
||||||
"modifier": "IS_NULL"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return HttpResponse(_bar_page(filter_json=filter_json))
|
return HttpResponse(_bar_page(filter_json=filter_json))
|
||||||
@@ -73,7 +71,9 @@ def test_string_filter_defaults_and_toggles(live_server, page):
|
|||||||
|
|
||||||
# 2. Enter values, click "includes" (INCLUDES), and submit
|
# 2. Enter values, click "includes" (INCLUDES), and submit
|
||||||
name_input.fill("PlayStation")
|
name_input.fill("PlayStation")
|
||||||
includes_radio = page.locator('input[name="filter-name-modifier"][value="INCLUDES"]')
|
includes_radio = page.locator(
|
||||||
|
'input[name="filter-name-modifier"][value="INCLUDES"]'
|
||||||
|
)
|
||||||
includes_radio.click()
|
includes_radio.click()
|
||||||
|
|
||||||
with page.expect_navigation():
|
with page.expect_navigation():
|
||||||
@@ -121,12 +121,16 @@ def test_string_filter_prefilled_states(live_server, page):
|
|||||||
# Verifies name matches "Switch" and "includes" is checked
|
# Verifies name matches "Switch" and "includes" is checked
|
||||||
assert name_input.input_value() == "Switch"
|
assert name_input.input_value() == "Switch"
|
||||||
assert name_input.is_enabled()
|
assert name_input.is_enabled()
|
||||||
assert page.locator('input[name="filter-name-modifier"][value="INCLUDES"]').is_checked()
|
assert page.locator(
|
||||||
|
'input[name="filter-name-modifier"][value="INCLUDES"]'
|
||||||
|
).is_checked()
|
||||||
|
|
||||||
# Verifies group is empty, disabled, and "is null" is checked
|
# Verifies group is empty, disabled, and "is null" is checked
|
||||||
assert group_input.input_value() == ""
|
assert group_input.input_value() == ""
|
||||||
assert not group_input.is_enabled()
|
assert not group_input.is_enabled()
|
||||||
assert page.locator('input[name="filter-group-modifier"][value="IS_NULL"]').is_checked()
|
assert page.locator(
|
||||||
|
'input[name="filter-group-modifier"][value="IS_NULL"]'
|
||||||
|
).is_checked()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
+3
-1
@@ -412,7 +412,9 @@ class GameFilter(OperatorFilter):
|
|||||||
from games.models import PlayEvent
|
from games.models import PlayEvent
|
||||||
|
|
||||||
event_q = criterion.to_q("note")
|
event_q = criterion.to_q("note")
|
||||||
matching_ids = PlayEvent.objects.filter(event_q).values_list("game_id", flat=True)
|
matching_ids = PlayEvent.objects.filter(event_q).values_list(
|
||||||
|
"game_id", flat=True
|
||||||
|
)
|
||||||
return Q(id__in=matching_ids)
|
return Q(id__in=matching_ids)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('games', '0017_add_filter_preset'),
|
("games", "0017_add_filter_preset"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='session',
|
model_name="session",
|
||||||
name='timestamp_start',
|
name="timestamp_start",
|
||||||
field=models.DateTimeField(db_index=True, verbose_name='Start'),
|
field=models.DateTimeField(db_index=True, verbose_name="Start"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -362,4 +362,3 @@ class FilterBarRenderingTest(TestCase):
|
|||||||
self.assertIn('name="filter-refunded"', purchase_html)
|
self.assertIn('name="filter-refunded"', purchase_html)
|
||||||
self.assertIn('value="true"', purchase_html)
|
self.assertIn('value="true"', purchase_html)
|
||||||
self.assertIn('value="false"', purchase_html)
|
self.assertIn('value="false"', purchase_html)
|
||||||
|
|
||||||
|
|||||||
@@ -85,4 +85,3 @@ class ParseBoolNullableTest(SimpleTestCase):
|
|||||||
self.assertTrue(_parse_bool_nullable({"field": {"value": "1"}}, "field"))
|
self.assertTrue(_parse_bool_nullable({"field": {"value": "1"}}, "field"))
|
||||||
self.assertFalse(_parse_bool_nullable({"field": {"value": "false"}}, "field"))
|
self.assertFalse(_parse_bool_nullable({"field": {"value": "false"}}, "field"))
|
||||||
self.assertFalse(_parse_bool_nullable({"field": {"value": "0"}}, "field"))
|
self.assertFalse(_parse_bool_nullable({"field": {"value": "0"}}, "field"))
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -560,8 +560,14 @@ class TestFilterBarRendering:
|
|||||||
|
|
||||||
def test_mastered_not_checked_by_default(self):
|
def test_mastered_not_checked_by_default(self):
|
||||||
html = str(FilterBar(filter_json=""))
|
html = str(FilterBar(filter_json=""))
|
||||||
assert 'name="filter-mastered" value="true" class="rounded-full border-default-medium bg-neutral-secondary-medium text-brand focus:ring-brand" checked="true"' not in html
|
assert (
|
||||||
assert 'name="filter-mastered" value="false" class="rounded-full border-default-medium bg-neutral-secondary-medium text-brand focus:ring-brand" checked="true"' not in html
|
'name="filter-mastered" value="true" class="rounded-full border-default-medium bg-neutral-secondary-medium text-brand focus:ring-brand" checked="true"'
|
||||||
|
not in html
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'name="filter-mastered" value="false" class="rounded-full border-default-medium bg-neutral-secondary-medium text-brand focus:ring-brand" checked="true"'
|
||||||
|
not in html
|
||||||
|
)
|
||||||
|
|
||||||
def test_mastered_checked_when_filtered(self):
|
def test_mastered_checked_when_filtered(self):
|
||||||
html = str(
|
html = str(
|
||||||
@@ -784,7 +790,7 @@ class TestExpandedFiltersAgainstDB:
|
|||||||
from games.filters import SessionFilter
|
from games.filters import SessionFilter
|
||||||
from games.models import Session
|
from games.models import Session
|
||||||
|
|
||||||
data = self._setup_entities()
|
self._setup_entities()
|
||||||
|
|
||||||
# Test duration_total_hours equals 4
|
# Test duration_total_hours equals 4
|
||||||
sf_tot = SessionFilter.from_json(
|
sf_tot = SessionFilter.from_json(
|
||||||
@@ -808,7 +814,7 @@ class TestExpandedFiltersAgainstDB:
|
|||||||
from games.filters import PurchaseFilter
|
from games.filters import PurchaseFilter
|
||||||
from games.models import Purchase
|
from games.models import Purchase
|
||||||
|
|
||||||
data = self._setup_entities()
|
self._setup_entities()
|
||||||
|
|
||||||
pf = PurchaseFilter.from_json(
|
pf = PurchaseFilter.from_json(
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user