from backend.app.modelling.batching import pack_postcode_batches from backend.app.modelling.property_filters import FilteredProperty def _properties(postcode: str, count: int, start_id: int) -> list[FilteredProperty]: return [ FilteredProperty(property_id=start_id + i, postcode=postcode) for i in range(count) ] def test_postcodes_are_never_split_across_batches() -> None: # arrange — 30 + 30 + 10 with a cap of 50: the second postcode won't fit # alongside the first, the third rides with the second properties = ( _properties("B93 8SU", 30, start_id=0) + _properties("M20 4TF", 30, start_id=100) + _properties("SW1A 1AA", 10, start_id=200) ) # act batches = pack_postcode_batches(properties, batch_size=50) # assert assert [len(b) for b in batches] == [30, 40] for batch in batches: for postcode in {p.postcode for p in batch}: in_batch = [p for p in batch if p.postcode == postcode] everywhere = [p for p in properties if p.postcode == postcode] assert len(in_batch) == len(everywhere) # whole postcode, one batch def test_an_oversized_postcode_becomes_its_own_batch() -> None: # arrange — one postcode alone exceeds the cap; neighbours are unaffected properties = _properties("B93 8SU", 60, start_id=0) + _properties( "M20 4TF", 20, start_id=100 ) # act batches = pack_postcode_batches(properties, batch_size=50) # assert assert [len(b) for b in batches] == [60, 20]