Skip to content

Commit 205fb7e

Browse files
authored
Merge pull request #71 from edanalytics/fix/self_reference_validation
fix/self_reference_validation
2 parents cbfc1f8 + b8ad7f9 commit 205fb7e

1 file changed

Lines changed: 22 additions & 5 deletions

File tree

lightbeam/validate.py

Lines changed: 22 additions & 5 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])
@@ -217,10 +217,12 @@ async def validate_endpoint(self, endpoint):
217217

218218
for file_name in data_files:
219219
self.logger.info(f"validating {file_name} against {definition} schema...")
220+
file_counter = 0
220221
with open(file_name) as file:
221222
for i, line in enumerate(file):
222223
line_number = i + 1
223224
total_counter += 1
225+
file_counter += 1
224226
data = line.strip()
225227

226228
tasks.append(asyncio.create_task(
@@ -255,7 +257,7 @@ async def validate_endpoint(self, endpoint):
255257
num_others = self.lightbeam.num_errors - self.MAX_VALIDATION_ERRORS_TO_DISPLAY
256258
if self.lightbeam.num_errors > self.MAX_VALIDATION_ERRORS_TO_DISPLAY:
257259
self.logger.warn(f"... and {num_others} others!")
258-
self.logger.warn(f"... VALIDATION ERRORS on {self.lightbeam.num_errors} of {line_counter} lines in {file_name}; see details above.")
260+
self.logger.warn(f"... VALIDATION ERRORS on {self.lightbeam.num_errors} of {file_counter} lines in {file_name}; see details above.")
259261

260262
# free up some memory
261263
self.uniqueness_hashes = {}
@@ -298,7 +300,7 @@ async def do_validate_payload(self, endpoint, file_name, data, line_number):
298300
if "uniqueness" in self.validation_methods:
299301
error_message = self.violates_uniqueness(endpoint, payload, path="")
300302
if error_message != "":
301-
self.log_validation_error(endpoint, file_name, line_counter, "uniqueness", error_message)
303+
self.log_validation_error(endpoint, file_name, line_number, "uniqueness", error_message)
302304

303305
# check references values are valid
304306
if "references" in self.validation_methods and "Descriptor" not in endpoint: # Descriptors have no references
@@ -409,7 +411,7 @@ def has_invalid_references(self, payload, path=""):
409411
if value!="": return value
410412
elif isinstance(payload[k], dict) and k.endswith("Reference"):
411413
is_valid_reference = False
412-
original_endpoint = util.pluralize_endpoint(k.replace("Reference",""))
414+
original_endpoint = self.resolve_reference_to_endpoint(k)
413415

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

439+
@staticmethod
440+
def resolve_reference_to_endpoint(referenceName):
441+
endpoint = referenceName
442+
# remove final "Reference"
443+
if endpoint.endswith("Reference"):
444+
endpoint = endpoint[:-1*len("Reference")]
445+
# remove leading "parent" if whole endpoint name isn't just "parent"
446+
# (this handles things like parentObjectiveAssessmentReference)
447+
if endpoint.startswith("parent") and endpoint!="parent":
448+
endpoint = endpoint[len("parent"):]
449+
endpoint = endpoint[0].lower() + endpoint[1:]
450+
return util.pluralize_endpoint(endpoint)
451+
437452
# Tells you if a specified descriptor value is valid or not
438453
def is_valid_descriptor_value(self, namespace, codeValue):
439454
for row in self.lightbeam.api.descriptor_values:
@@ -444,7 +459,9 @@ def is_valid_descriptor_value(self, namespace, codeValue):
444459
@staticmethod
445460
def get_cache_key(payload):
446461
cache_key = ''
447-
for k in payload.keys():
462+
payload_keys = list(payload.keys())
463+
payload_keys.sort()
464+
for k in payload_keys:
448465
cache_key += f"{payload[k]}~~~"
449466
return cache_key
450467

0 commit comments

Comments
 (0)