Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions tests/test_app_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ def test_css_injects_before_sidebar_and_has_no_blocking_import():
assert ui_source.index("_inject_global_css(\"dark\")") < ui_source.index("render_sidebar(active_page)")


def test_home_tool_card_rows_wrap_at_responsive_breakpoints():
"""Home card rows must reflow rather than shrink five cards into an
unreadable strip on laptop, tablet, and phone-sized viewports."""
ui_source = UI_MODULE.read_text(encoding="utf-8")
tool_row = '[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"])'

assert tool_row in ui_source
assert '[data-testid="stColumn"]' in ui_source
assert "@media (max-width: 1180px)" in ui_source
assert "flex-wrap: wrap;" in ui_source
assert "flex: 1 1 calc(33.333% - 1rem) !important;" in ui_source
assert "@media (max-width: 860px)" in ui_source
assert "flex-basis: calc(50% - 0.75rem) !important;" in ui_source
assert "@media (max-width: 560px)" in ui_source
assert "flex-basis: 100% !important;" in ui_source


def test_home_pills_are_required_and_cannot_deselect_to_none():
"""Regression: st.pills defaults to required=False, meaning a click on an
already-selected pill deselects it to None. The sort pill's value used to
Expand Down
29 changes: 27 additions & 2 deletions tests/test_ip_geolocation.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from types import SimpleNamespace

from utils import ip_geolocation
from utils.ip_geolocation import lookup_ip_geolocation


Expand All @@ -15,12 +18,34 @@ def test_lookup_ip_geolocation_rejects_invalid_ip():
assert "valid IPv4 or IPv6" in result["error"]


def test_lookup_ip_geolocation_live_public_ip():
def test_lookup_ip_geolocation_public_ip_parses_successful_response(monkeypatch):
"""Public API behavior is covered without making the suite rate-limit- or
network-dependent; live endpoint availability is not an application unit
test contract."""
payload = {
"status": "success",
"country": "United States",
"regionName": "Virginia",
"city": "Ashburn",
"zip": "20149",
"lat": 39.03,
"lon": -77.5,
"timezone": "America/New_York",
"isp": "Google LLC",
"org": "Google Public DNS",
"as": "AS15169 Google LLC",
}
monkeypatch.setattr(
ip_geolocation.requests,
"get",
lambda *args, **kwargs: SimpleNamespace(status_code=200, json=lambda: payload),
)

result = lookup_ip_geolocation("8.8.8.8")

assert result["ok"] is True
assert result["country"] == "United States"
assert result["asn"]
assert result["asn"] == "AS15169 Google LLC"


def test_lookup_ip_geolocation_live_private_ip_returns_error():
Expand Down
32 changes: 32 additions & 0 deletions utils/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -4259,6 +4259,38 @@ def _inject_global_css(mode: str) -> None:
box-shadow: 0 18px 36px rgba(0, 0, 0, 0.28);
}

/* Streamlit columns stay on one row by default, which makes five-card
Home sections too narrow on laptops and tablet-sized windows. Scope
wrapping to rows containing tool-card containers so metric rows and
ordinary form columns retain Streamlit's native layout behavior. */
[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"]) {
align-items: stretch;
}

@media (max-width: 1180px) {
[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"]) {
flex-wrap: wrap;
Comment on lines +4270 to +4272

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Base wrapping on the grid's available width

When the sidebar is expanded on laptop/desktop viewports just above 1180px, the main content grid is substantially narrower than the viewport, but this media query does not activate, so render_tool_section() still compresses all five columns into the same unreadable row this change intends to prevent. Use a container query for the horizontal block or raise/adjust the breakpoint to account for the sidebar rather than keying solely off viewport width.

Useful? React with 👍 / 👎.

}

[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"]) > [data-testid="stColumn"] {
flex: 1 1 calc(33.333% - 1rem) !important;
min-width: min(17rem, 100%) !important;
}
}

@media (max-width: 860px) {
[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"]) > [data-testid="stColumn"] {
flex-basis: calc(50% - 0.75rem) !important;
}
}

@media (max-width: 560px) {
[data-testid="stHorizontalBlock"]:has([class*="st-key-tool_card_"]) > [data-testid="stColumn"] {
flex-basis: 100% !important;
min-width: 0 !important;
}
}

.tool-card-shell {
position: relative;
min-height: 15.1rem;
Expand Down