"""Unit tests for the D-memo ingester (canlex/dmemo.py). Offline only. Covers the two failure modes that cost the corpus on 2026-07-27: CBSA replaced the static index with a JSON-fed DataTable (the link-scrape found zero memos), and the ingester wrote that empty result straight over 1,870 good chunks. """ import json import unittest from canlex import dmemo class DatasourceUrlTests(unittest.TestCase): RAW = json.dumps({"data": [ {"NUMBER": 'D1-2-1', "STATUS": "Active"}, {"NUMBER": 'D8-2-2', "STATUS": "Active"}, {"NUMBER": "D8-11-1", "STATUS": "Cancelled"}, {"NUMBER": '' 'D10-14-48', "STATUS": "Cancelled"}, ]}).encode("utf-8") def test_extracts_absolute_urls(self): self.assertEqual( dmemo.datasource_urls(self.RAW), ["https://www.cbsa-asfc.gc.ca/publications/dm-md/d1/d1-2-1-eng.html", "https://www.cbsa-asfc.gc.ca/publications/dm-md/d8/d8-2-2-eng.html"]) def test_cancelled_memos_are_skipped_even_when_still_linked(self): # Retired guidance must not surface as if it were current. self.assertNotIn("d10-14-48", " ".join(dmemo.datasource_urls(self.RAW))) def test_deduplicates(self): row = {"NUMBER": 'x', "STATUS": "Active"} raw = json.dumps({"data": [row, row]}).encode("utf-8") self.assertEqual(len(dmemo.datasource_urls(raw)), 1) def test_empty_datasource_yields_nothing(self): self.assertEqual(dmemo.datasource_urls(b'{"data": []}'), []) class IndexFallbackTests(unittest.TestCase): def test_scrapes_links_off_the_legacy_index(self): html = ('D1-2-1' 'menu') self.assertEqual( dmemo.index_urls(html), ["https://www.cbsa-asfc.gc.ca/publications/dm-md/d1/d1-2-1-eng.html"]) def test_rebuilt_index_has_no_links_to_find(self): # What CBSA now serves: an empty table, memo rows loaded by JS. self.assertEqual(dmemo.index_urls('
'), []) class PreserveFailedTests(unittest.TestCase): STORED = [{"section": "D10-14-3", "text": "seasonal duties"}, {"section": "D10-14-3", "text": "part two"}, {"section": "D1-2-1", "text": "special services"}] def test_unfetchable_memo_keeps_its_last_good_chunks(self): failures = [("https://x/publications/dm-md/d10/d10-14-3-eng.html", "404")] chunks, preserved = dmemo.preserve_failed([], failures, self.STORED) self.assertEqual(preserved, ["D10-14-3"]) self.assertEqual(len(chunks), 2) def test_freshly_parsed_chunks_win_over_stored(self): fresh = [{"section": "D10-14-3", "text": "new text"}] failures = [("https://x/publications/dm-md/d10/d10-14-3-eng.html", "404")] chunks, preserved = dmemo.preserve_failed(fresh, failures, self.STORED) self.assertEqual(preserved, []) self.assertEqual(chunks, fresh) def test_memo_we_never_had_cannot_be_preserved(self): failures = [("https://x/publications/dm-md/d8/d8-2-2-eng.html", "404")] chunks, preserved = dmemo.preserve_failed([], failures, self.STORED) self.assertEqual((chunks, preserved), ([], [])) def test_nothing_happens_without_failures(self): fresh = [{"section": "D1-2-1", "text": "x"}] chunks, preserved = dmemo.preserve_failed(fresh, [], self.STORED) self.assertEqual((chunks, preserved), (fresh, [])) if __name__ == "__main__": unittest.main()