@@ -1416,4 +1416,59 @@ private static String decodeCanonicalFromCvId(String id) {
14161416 byte [] bytes = Base64 .getDecoder ().decode (base64 );
14171417 return new String (bytes , StandardCharsets .UTF_8 );
14181418 }
1419+
1420+ @ Test
1421+ void filterUnversionedCanonicalParams_dropsUrlsWithoutPin_keepsOthers () throws Exception {
1422+ var visitor = new PackageVisitor (repo );
1423+
1424+ var params = parameters ();
1425+ params .addParameter ("system-version" , "http://snomed.info/sct" ); // unversioned canonical — drop
1426+ params .addParameter ("system-version" , "http://loinc.org|2.81" ); // versioned — keep
1427+ params .addParameter ("canonicalVersion" , "http://example.org/ValueSet/foo" ); // unversioned canonical — drop
1428+ params .addParameter ("canonicalVersion" , "http://example.org/ValueSet/bar|1.0.0" ); // versioned — keep
1429+ params .addParameter ("system-version" , "urn:oid:1.2.3.4" ); // unversioned urn canonical — drop
1430+ params .addParameter ("system-version" , "urn:oid:1.2.3.4|2024" ); // versioned urn canonical — keep
1431+ params .addParameter ("displayLanguage" , "en-US" ); // non-canonical — keep
1432+ params .addParameter ("activeOnly" , true ); // boolean — keep
1433+
1434+ var adapter = (IParametersAdapter )
1435+ IAdapterFactory .forFhirVersion (FhirVersionEnum .R4 ).createParameters (params );
1436+
1437+ var method =
1438+ PackageVisitor .class .getDeclaredMethod ("filterUnversionedCanonicalParams" , IParametersAdapter .class );
1439+ method .setAccessible (true );
1440+ method .invoke (visitor , adapter );
1441+
1442+ var remainingValues = adapter .getParameter ().stream ()
1443+ .map (p -> p .getName () + "=" + (p .hasValue () ? p .getPrimitiveValue () : "<no-value>" ))
1444+ .toList ();
1445+
1446+ assertEquals (5 , remainingValues .size (), "should drop all three unversioned canonical entries" );
1447+ assertTrue (remainingValues .contains ("system-version=http://loinc.org|2.81" ));
1448+ assertTrue (remainingValues .contains ("canonicalVersion=http://example.org/ValueSet/bar|1.0.0" ));
1449+ assertTrue (remainingValues .contains ("system-version=urn:oid:1.2.3.4|2024" ));
1450+ assertTrue (remainingValues .contains ("displayLanguage=en-US" ));
1451+ assertTrue (remainingValues .contains ("activeOnly=true" ));
1452+ assertFalse (remainingValues .stream ().anyMatch (v -> v .equals ("system-version=http://snomed.info/sct" )));
1453+ assertFalse (
1454+ remainingValues .stream ().anyMatch (v -> v .equals ("canonicalVersion=http://example.org/ValueSet/foo" )));
1455+ assertFalse (remainingValues .stream ().anyMatch (v -> v .equals ("system-version=urn:oid:1.2.3.4" )));
1456+ }
1457+
1458+ @ Test
1459+ void filterUnversionedCanonicalParams_handlesNullAndEmptyInputs () throws Exception {
1460+ var visitor = new PackageVisitor (repo );
1461+ var method =
1462+ PackageVisitor .class .getDeclaredMethod ("filterUnversionedCanonicalParams" , IParametersAdapter .class );
1463+ method .setAccessible (true );
1464+
1465+ // Null adapter — should not throw
1466+ method .invoke (visitor , new Object [] {null });
1467+
1468+ // Empty parameters — should not throw, no-op
1469+ var empty = (IParametersAdapter )
1470+ IAdapterFactory .forFhirVersion (FhirVersionEnum .R4 ).createParameters (parameters ());
1471+ method .invoke (visitor , empty );
1472+ assertTrue (empty .getParameter ().isEmpty ());
1473+ }
14191474}
0 commit comments