@@ -189,6 +189,7 @@ def test_exact_artifact_reuse_is_immutable_and_requires_full_match() -> None:
189189 inventory = inventory ,
190190 context = AllocationContext .exact_artifact_reuse (),
191191 requested_artifacts = RequestedArtifactSet (False , False ),
192+ display_placement = DisplayPlacement (True , 2 ),
192193 )
193194
194195 assert result .reused_existing is True
@@ -204,9 +205,77 @@ def test_exact_artifact_reuse_is_immutable_and_requires_full_match() -> None:
204205 inventory = inventory ,
205206 context = AllocationContext .exact_artifact_reuse (),
206207 requested_artifacts = REQUESTED ,
208+ display_placement = DISPLAY ,
209+ )
210+
211+
212+ @pytest .mark .parametrize (
213+ ("requested" , "display" ),
214+ [
215+ (RequestedArtifactSet (True , False ), DisplayPlacement (True , 2 )),
216+ (RequestedArtifactSet (False , True ), DisplayPlacement (True , 2 )),
217+ (RequestedArtifactSet (False , False ), DisplayPlacement (False , 2 )),
218+ (RequestedArtifactSet (False , False ), DisplayPlacement (True , 3 )),
219+ ],
220+ )
221+ def test_exact_reuse_rejects_publication_policy_mismatch (
222+ requested : RequestedArtifactSet , display : DisplayPlacement
223+ ) -> None :
224+ report = build_report ()
225+ binding = binding_for (report , display_primary = True , display_order = 2 )
226+
227+ with pytest .raises (IdentityMetadataError , match = "identity_reuse_mismatch" ):
228+ allocate_v3_identity (
229+ report ,
230+ inventory = inventory_for ((binding , report )),
231+ context = AllocationContext .exact_artifact_reuse (),
232+ requested_artifacts = requested ,
233+ display_placement = display ,
234+ )
235+
236+
237+ @pytest .mark .parametrize (
238+ "display" ,
239+ [None , DisplayPlacement (True , True ), DisplayPlacement (True , - 1 )],
240+ )
241+ def test_exact_reuse_requires_valid_matching_display_placement (display : object ) -> None :
242+ report = build_report ()
243+ binding = binding_for (report , display_primary = True , display_order = 2 )
244+
245+ with pytest .raises (IdentityMetadataError , match = "display_placement" ):
246+ allocate_v3_identity (
247+ report ,
248+ inventory = inventory_for ((binding , report )),
249+ context = AllocationContext .exact_artifact_reuse (),
250+ requested_artifacts = REQUESTED ,
251+ display_placement = display , # type: ignore[arg-type]
252+ )
253+
254+
255+ @pytest .mark .parametrize ("schema_version" , [2 , 4 , True , "3" ])
256+ def test_inventory_rejects_declared_schema_version_other_than_v3 (schema_version : object ) -> None :
257+ report = build_report ()
258+ binding = binding_for (report )
259+
260+ with pytest .raises (IdentityMetadataError , match = "identity_inventory_invalid" ):
261+ make_complete_source_inventory (
262+ V3IdentityIndex (schema_version , (binding ,)), # type: ignore[arg-type]
263+ {binding .json_name : report },
207264 )
208265
209266
267+ def test_inventory_accepts_declared_v3_schema_version () -> None :
268+ report = build_report ()
269+ binding = binding_for (report )
270+
271+ inventory = make_complete_source_inventory (
272+ V3IdentityIndex (3 , (binding ,)),
273+ {binding .json_name : report },
274+ )
275+
276+ assert inventory .index .schema_version == 3
277+
278+
210279def test_semantic_same_artifact_different_is_not_reused () -> None :
211280 report = build_report ()
212281 changed = dict (report )
@@ -279,6 +348,7 @@ def test_display_and_identity_ownership_are_independent() -> None:
279348 inventory = inventory ,
280349 context = AllocationContext .exact_artifact_reuse (),
281350 requested_artifacts = REQUESTED ,
351+ display_placement = DisplayPlacement (False , 0 ),
282352 )
283353
284354 assert result .binding .canonical_identity is True
0 commit comments