#!/usr/bin/env python3 """ Unit tests for the LLM restock fallback's prompt-content building (no LLM call needed): * _extract_jsonld() keeps only JSON-LD blocks carrying price/stock info, dropping noise (breadcrumbs, site metadata) that otherwise crowds out the useful data. * _strip_html() sends the page's visible text IN ADDITION to that structured metadata — the real/visible price is often not in JSON-LD (placeholder "0"). * the result cache evicts oldest-first and stays bounded. Run from the tests/ directory: python -m unittest unit/test_llm_restock_content.py """ import unittest from changedetectionio.processors.restock_diff.plugins import llm_restock as m PRODUCT_LD = '{"@type":"Product","offers":{"price":"319.01","priceCurrency":"CZK","availability":"http://schema.org/InStock"}}' BREADCRUMB_LD = '{"@type":"BreadcrumbList","itemListElement":[{"name":"a"},{"name":"b"}]}' HTML = f"""
VISIBLE_TEXT_MARKER add to cart
' out = m._strip_html(big_meta_html, max_chars=400) self.assertLessEqual(len(out), 400) self.assertIn('VISIBLE_TEXT_MARKER', out) def test_result_cache_is_bounded_fifo(self): m._LLM_RESULT_CACHE.clear() for i in range(m._LLM_RESULT_CACHE_MAX + 25): m._llm_cache_put(f'key{i}', {'price': i}) self.assertEqual(len(m._LLM_RESULT_CACHE), m._LLM_RESULT_CACHE_MAX) self.assertIsNone(m._llm_cache_get('key0')) # oldest evicted self.assertIsNotNone(m._llm_cache_get(f'key{m._LLM_RESULT_CACHE_MAX + 24}')) # newest kept m._LLM_RESULT_CACHE.clear() if __name__ == '__main__': unittest.main()