"""Tests for servers page search history payload rules and API.""" from __future__ import annotations import pytest from server.utils.server_search_history import ( MAX_PUSH_SEARCH_HISTORY, MAX_SERVER_SEARCH_HISTORY, MAX_TERMINAL_SEARCH_HISTORY, apply_search_record, parse_search_state, ) def test_apply_search_record_dedupes_and_caps(): state = {"history": ["b", "c"], "last": "b"} next_state = apply_search_record(state, "a") assert next_state["last"] == "a" assert next_state["history"] == ["a", "b", "c"] long_state = {"history": [f"q{i}" for i in range(MAX_SERVER_SEARCH_HISTORY)], "last": "q0"} capped = apply_search_record(long_state, "new") assert capped["history"][0] == "new" assert len(capped["history"]) == MAX_SERVER_SEARCH_HISTORY def test_apply_search_record_clear_last_on_empty_query(): state = {"history": ["a"], "last": "a"} cleared = apply_search_record(state, " ") assert cleared["last"] is None assert cleared["history"] == ["a"] def test_parse_search_state_normalizes(): raw = {"history": [" 1.2.3.4 ", 123, "1.2.3.4"], "last": " x "} parsed = parse_search_state(raw) assert parsed["history"] == ["1.2.3.4"] assert parsed["last"] == "x" def test_push_search_history_caps_at_five(): raw = {"history": [f"q{i}" for i in range(8)], "last": "q0"} parsed = parse_search_state(raw, max_history=MAX_PUSH_SEARCH_HISTORY) assert len(parsed["history"]) == MAX_PUSH_SEARCH_HISTORY state = {"history": [f"q{i}" for i in range(MAX_PUSH_SEARCH_HISTORY)], "last": "q0"} capped = apply_search_record(state, "new", max_history=MAX_PUSH_SEARCH_HISTORY) assert capped["history"][0] == "new" assert len(capped["history"]) == MAX_PUSH_SEARCH_HISTORY @pytest.mark.asyncio async def test_push_search_history_api_roundtrip(integration_env, api_client, auth_headers): r = await api_client.get("/api/servers/push-search-history", headers=auth_headers) assert r.status_code == 200 assert r.json() == {"history": [], "last": None} for i in range(6): r = await api_client.put( "/api/servers/push-search-history", headers=auth_headers, json={"query": f"push-{i}"}, ) assert r.status_code == 200 body = r.json() assert len(body["history"]) == MAX_PUSH_SEARCH_HISTORY assert body["history"][0] == "push-5" @pytest.mark.asyncio async def test_terminal_search_history_api_roundtrip(integration_env, api_client, auth_headers): r = await api_client.get("/api/servers/terminal-search-history", headers=auth_headers) assert r.status_code == 200 assert r.json() == {"history": [], "last": None} for i in range(12): r = await api_client.put( "/api/servers/terminal-search-history", headers=auth_headers, json={"query": f"term-{i}"}, ) assert r.status_code == 200 body = r.json() assert len(body["history"]) == MAX_TERMINAL_SEARCH_HISTORY assert body["history"][0] == "term-11" @pytest.mark.asyncio async def test_search_scopes_do_not_share(integration_env, api_client, auth_headers): await api_client.put( "/api/servers/search-history", headers=auth_headers, json={"query": "servers-only"}, ) await api_client.put( "/api/servers/terminal-search-history", headers=auth_headers, json={"query": "terminal-only"}, ) await api_client.put( "/api/servers/push-search-history", headers=auth_headers, json={"query": "push-only"}, ) servers = (await api_client.get("/api/servers/search-history", headers=auth_headers)).json() terminal = (await api_client.get("/api/servers/terminal-search-history", headers=auth_headers)).json() push = (await api_client.get("/api/servers/push-search-history", headers=auth_headers)).json() assert servers["history"] == ["servers-only"] assert terminal["history"] == ["terminal-only"] assert push["history"] == ["push-only"] @pytest.mark.asyncio async def test_search_history_api_roundtrip(integration_env, api_client, auth_headers): r = await api_client.get("/api/servers/search-history", headers=auth_headers) assert r.status_code == 200 assert r.json() == {"history": [], "last": None} r = await api_client.put( "/api/servers/search-history", headers=auth_headers, json={"query": "10.0.0.1"}, ) assert r.status_code == 200 body = r.json() assert body["last"] == "10.0.0.1" assert body["history"] == ["10.0.0.1"] r = await api_client.put( "/api/servers/search-history", headers=auth_headers, json={"query": "web-01"}, ) body = r.json() assert body["history"] == ["web-01", "10.0.0.1"] r = await api_client.get("/api/servers/search-history", headers=auth_headers) assert r.json()["last"] == "web-01"