Skip to content

Commit 18637d0

Browse files
authored
fix/self_reference_validation
This PR fixes two bugs that prevented self-references (such as `objectiveAssessment.parentObjectiveAssessmentReference` from validating correctly: 1. reference fields were resolved to an endpoint by simply removing the `Reference` suffix, which obviously doesn't work for `parentObjectiveReference`s 2. cache keys (which are used to efficiently look up whether a referenced payload has been found) were sensitive to dict key ordering This PR fixes both bugs and ensures that self-references validate correctly.
1 parent cbfc1f8 commit 18637d0

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

lightbeam/validate.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def load_references_structure(self, swagger, definition):
146146
prefixes_to_remove = ["#/definitions/", "#/components/schemas/"]
147147
for k in schema["properties"].keys():
148148
if k.endswith("Reference"):
149-
original_endpoint = util.pluralize_endpoint(k.replace("Reference", ""))
149+
original_endpoint = self.resolve_reference_to_endpoint(k)
150150

151151
# this deals with the fact that an educationOrganizationReference may be to a school, LEA, etc.:
152152
endpoints_to_check = self.EDFI_GENERICS_TO_RESOURCES_MAPPING.get(original_endpoint, [original_endpoint])
@@ -409,7 +409,7 @@ def has_invalid_references(self, payload, path=""):
409409
if value!="": return value
410410
elif isinstance(payload[k], dict) and k.endswith("Reference"):
411411
is_valid_reference = False
412-
original_endpoint = util.pluralize_endpoint(k.replace("Reference",""))
412+
original_endpoint = self.resolve_reference_to_endpoint(k)
413413

414414
# this deals with the fact that an educationOrganizationReference may be to a school, LEA, etc.:
415415
endpoints_to_check = self.EDFI_GENERICS_TO_RESOURCES_MAPPING.get(original_endpoint, [original_endpoint])
@@ -434,6 +434,19 @@ def has_invalid_references(self, payload, path=""):
434434
return f"payload contains an invalid {k} " + (" (at "+path+"): " if path!="" else ": ") + json.dumps(params)
435435
return ""
436436

437+
@staticmethod
438+
def resolve_reference_to_endpoint(referenceName):
439+
endpoint = referenceName
440+
# remove final "Reference"
441+
if endpoint.endswith("Reference"):
442+
endpoint = endpoint[:-1*len("Reference")]
443+
# remove leading "parent" if whole endpoint name isn't just "parent"
444+
# (this handles things like parentObjectiveAssessmentReference)
445+
if endpoint.startswith("parent") and endpoint!="parent":
446+
endpoint = endpoint[len("parent"):]
447+
endpoint = endpoint[0].lower() + endpoint[1:]
448+
return util.pluralize_endpoint(endpoint)
449+
437450
# Tells you if a specified descriptor value is valid or not
438451
def is_valid_descriptor_value(self, namespace, codeValue):
439452
for row in self.lightbeam.api.descriptor_values:
@@ -444,7 +457,9 @@ def is_valid_descriptor_value(self, namespace, codeValue):
444457
@staticmethod
445458
def get_cache_key(payload):
446459
cache_key = ''
447-
for k in payload.keys():
460+
payload_keys = list(payload.keys())
461+
payload_keys.sort()
462+
for k in payload_keys:
448463
cache_key += f"{payload[k]}~~~"
449464
return cache_key
450465

0 commit comments

Comments
 (0)