diff --git a/js/LearningObjectives.js b/js/LearningObjectives.js index ade682e..93d7e56 100644 --- a/js/LearningObjectives.js +++ b/js/LearningObjectives.js @@ -10,13 +10,13 @@ export const SCHEMA = { "description": "Schema for Learning Objectives mapping", "additionalProperties": false, "definitions": { - "uuid": { + "hex-uuid": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - "description": "A unique identifier in the form of a UUID v4 or v5" + "pattern": "^[0-9a-f]{32}$", + "description": "A unique identifier in the form of the compact hex representations of a UUID v4 or v5" }, "learning_objective_id": { - "$ref": "#/definitions/uuid", + "$ref": "#/definitions/hex-uuid", "description": "Unique identifier for the Learning Objective" } }, @@ -51,7 +51,7 @@ export const SCHEMA = { "minProperties": 1, "additionalProperties": false, "patternProperties": { - "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$": { + "^[0-9a-f]{32}$": { "type": "array", "items": { "$ref": "#/definitions/learning_objective_id" diff --git a/js/MasteryCriteria.js b/js/MasteryCriteria.js index e51c336..f750c9a 100644 --- a/js/MasteryCriteria.js +++ b/js/MasteryCriteria.js @@ -43,7 +43,7 @@ export const SCHEMA = { "minItems": 2, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version A and B of the pre/post test" }, @@ -52,7 +52,7 @@ export const SCHEMA = { "minItems": 1, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version A of the pre/post test" }, @@ -61,7 +61,7 @@ export const SCHEMA = { "minItems": 1, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version B of the pre/post test" } diff --git a/js/package.json b/js/package.json index 0228346..bbb389d 100644 --- a/js/package.json +++ b/js/package.json @@ -27,5 +27,5 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "version": "0.2.13" + "version": "0.2.14" } \ No newline at end of file diff --git a/le_utils/constants/learning_objectives.py b/le_utils/constants/learning_objectives.py index 542bdcb..0622abe 100644 --- a/le_utils/constants/learning_objectives.py +++ b/le_utils/constants/learning_objectives.py @@ -16,13 +16,13 @@ "description": "Schema for Learning Objectives mapping", "additionalProperties": False, "definitions": { - "uuid": { + "hex-uuid": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - "description": "A unique identifier in the form of a UUID v4 or v5", + "pattern": "^[0-9a-f]{32}$", + "description": "A unique identifier in the form of the compact hex representations of a UUID v4 or v5", }, "learning_objective_id": { - "$ref": "#/definitions/uuid", + "$ref": "#/definitions/hex-uuid", "description": "Unique identifier for the Learning Objective", }, }, @@ -55,7 +55,7 @@ "minProperties": 1, "additionalProperties": False, "patternProperties": { - "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$": { + "^[0-9a-f]{32}$": { "type": "array", "items": {"$ref": "#/definitions/learning_objective_id"}, } diff --git a/le_utils/constants/mastery_criteria.py b/le_utils/constants/mastery_criteria.py index 79ba4b1..f74d4b7 100644 --- a/le_utils/constants/mastery_criteria.py +++ b/le_utils/constants/mastery_criteria.py @@ -61,28 +61,19 @@ "assessment_item_ids": { "type": "array", "minItems": 2, - "items": { - "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - }, + "items": {"type": "string", "pattern": "^[0-9a-f]{32}$"}, "description": "List of assessment item UUIDs for version A and B of the pre/post test", }, "version_a_item_ids": { "type": "array", "minItems": 1, - "items": { - "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - }, + "items": {"type": "string", "pattern": "^[0-9a-f]{32}$"}, "description": "List of assessment item UUIDs for version A of the pre/post test", }, "version_b_item_ids": { "type": "array", "minItems": 1, - "items": { - "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - }, + "items": {"type": "string", "pattern": "^[0-9a-f]{32}$"}, "description": "List of assessment item UUIDs for version B of the pre/post test", }, }, diff --git a/setup.py b/setup.py index 142e6bc..64a8414 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="le-utils", packages=find_packages(), - version="0.2.13", + version="0.2.14", description="LE-Utils contains shared constants used in Kolibri, Ricecooker, and Kolibri Studio.", long_description=long_description, long_description_content_type="text/markdown", diff --git a/spec/schema-learning_objectives.json b/spec/schema-learning_objectives.json index 0c43fd5..1ed81e1 100644 --- a/spec/schema-learning_objectives.json +++ b/spec/schema-learning_objectives.json @@ -5,13 +5,13 @@ "description": "Schema for Learning Objectives mapping", "additionalProperties": false, "definitions": { - "uuid": { + "hex-uuid": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", - "description": "A unique identifier in the form of a UUID v4 or v5" + "pattern": "^[0-9a-f]{32}$", + "description": "A unique identifier in the form of the compact hex representations of a UUID v4 or v5" }, "learning_objective_id": { - "$ref": "#/definitions/uuid", + "$ref": "#/definitions/hex-uuid", "description": "Unique identifier for the Learning Objective" } }, @@ -46,7 +46,7 @@ "minProperties": 1, "additionalProperties": false, "patternProperties": { - "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$": { + "^[0-9a-f]{32}$": { "type": "array", "items": { "$ref": "#/definitions/learning_objective_id" diff --git a/spec/schema-mastery_criteria.json b/spec/schema-mastery_criteria.json index b67529e..9957a29 100644 --- a/spec/schema-mastery_criteria.json +++ b/spec/schema-mastery_criteria.json @@ -29,7 +29,7 @@ "minItems": 2, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version A and B of the pre/post test" }, @@ -38,7 +38,7 @@ "minItems": 1, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version A of the pre/post test" }, @@ -47,7 +47,7 @@ "minItems": 1, "items": { "type": "string", - "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[45][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + "pattern": "^[0-9a-f]{32}$" }, "description": "List of assessment item UUIDs for version B of the pre/post test" } diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 867a86e..706ea56 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -231,12 +231,12 @@ def test_completion_criteria__mastery_model__valid(): "mastery_model": "pre_post_test", "pre_post_test": { "assessment_item_ids": [ - str(uuid.uuid4()), - str(uuid.uuid4()), + uuid.uuid4().hex, + uuid.uuid4().hex, ], # v4 UUID - "version_a_item_ids": [str(uuid.uuid4())], # v4 UUID + "version_a_item_ids": [uuid.uuid4().hex], # v4 UUID "version_b_item_ids": [ - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test")) + uuid.uuid5(uuid.NAMESPACE_DNS, "test").hex ], # v5 UUID }, }, @@ -285,8 +285,8 @@ def test_completion_criteria__mastery_model__invalid(): "threshold": { "mastery_model": "pre_post_test", "pre_post_test": { - "assessment_item_ids": [str(uuid.uuid4())], # v4 UUID - "version_a_item_ids": [str(uuid.uuid4())], # v4 UUID + "assessment_item_ids": [uuid.uuid4().hex], # v4 UUID + "version_a_item_ids": [uuid.uuid4().hex], # v4 UUID }, }, "learner_managed": False, @@ -691,25 +691,25 @@ def test_learning_objectives__valid(): { "learning_objectives": [ { - "id": str(uuid.uuid4()), + "id": uuid.uuid4().hex, "text": "Learning Objective 1", }, { - "id": str(uuid.uuid4()), + "id": uuid.uuid4().hex, "text": "Learning Objective 2", "metadata": {"key": "value"}, }, ], "assessment_objectives": { - str(uuid.uuid4()): [str(uuid.uuid4())], - str(uuid.uuid4()): [ - str(uuid.uuid4()), - str(uuid.uuid4()), + uuid.uuid4().hex: [uuid.uuid4().hex], + uuid.uuid4().hex: [ + uuid.uuid4().hex, + uuid.uuid4().hex, ], }, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())], - "abcdef1234567890abcdef1234567891": [str(uuid.uuid4())], + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex], + "abcdef1234567890abcdef1234567891": [uuid.uuid4().hex], }, } ) @@ -722,30 +722,30 @@ def test_learning_objectives__valid_uuid_v5(): { "learning_objectives": [ { - "id": str(uuid.uuid5(uuid.NAMESPACE_DNS, "test")), + "id": uuid.uuid5(uuid.NAMESPACE_DNS, "test").hex, "text": "Learning Objective 1", }, { - "id": str(uuid.uuid5(uuid.NAMESPACE_DNS, "test2")), + "id": uuid.uuid5(uuid.NAMESPACE_DNS, "test2").hex, "text": "Learning Objective 2", "metadata": {"key": "value"}, }, ], "assessment_objectives": { - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test")): [ - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test3")) + uuid.uuid5(uuid.NAMESPACE_DNS, "test").hex: [ + uuid.uuid5(uuid.NAMESPACE_DNS, "test3").hex ], - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test2")): [ - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test4")), - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test5")), + uuid.uuid5(uuid.NAMESPACE_DNS, "test2").hex: [ + uuid.uuid5(uuid.NAMESPACE_DNS, "test4").hex, + uuid.uuid5(uuid.NAMESPACE_DNS, "test5").hex, ], }, "lesson_objectives": { "abcdef1234567890abcdef1234567890": [ - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test6")) + uuid.uuid5(uuid.NAMESPACE_DNS, "test6").hex ], "abcdef1234567890abcdef1234567891": [ - str(uuid.uuid5(uuid.NAMESPACE_DNS, "test7")) + uuid.uuid5(uuid.NAMESPACE_DNS, "test7").hex ], }, } @@ -758,11 +758,11 @@ def test_learning_objectives__invalid_lo_structure(): _validate_learning_objectives( { "learning_objectives": [ - {"id": str(uuid.uuid4())}, # Missing text + {"id": uuid.uuid4().hex}, # Missing text ], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -773,12 +773,12 @@ def test_learning_objectives__invalid_assessment_mapping(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], "assessment_objectives": { - str(uuid.uuid4()): str(uuid.uuid4()), # Should be an array + uuid.uuid4().hex: uuid.uuid4().hex, # Should be an array }, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -789,8 +789,8 @@ def test_learning_objectives__invalid_lesson_mapping(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { "abcdef1234567890abcdef1234567890": str( uuid.uuid4() @@ -806,9 +806,9 @@ def test_learning_objectives__missing_required_fields(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -817,8 +817,8 @@ def test_learning_objectives__missing_required_fields(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, } ) @@ -826,8 +826,8 @@ def test_learning_objectives__missing_required_fields(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, } ) @@ -839,9 +839,9 @@ def test_learning_objectives__empty_structures(): _validate_learning_objectives( { "learning_objectives": [], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -850,10 +850,10 @@ def test_learning_objectives__empty_structures(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], "assessment_objectives": {}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -862,8 +862,8 @@ def test_learning_objectives__empty_structures(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": {}, } ) @@ -876,9 +876,9 @@ def test_learning_objectives__invalid_uuid_format_in_learning_objectives(): _validate_learning_objectives( { "learning_objectives": [{"id": "invalid-uuid", "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -890,10 +890,10 @@ def test_learning_objectives__invalid_uuid_format_in_references(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): ["invalid-uuid"]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: ["invalid-uuid"]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -905,12 +905,12 @@ def test_learning_objectives__invalid_question_id_pattern(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], "assessment_objectives": { - "invalid-uuid-format": [str(uuid.uuid4())] + "invalid-uuid-format": [uuid.uuid4().hex] }, # Invalid UUID format "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -922,10 +922,10 @@ def test_learning_objectives__invalid_lesson_id_pattern(): with pytest.raises(jsonschema.ValidationError): _validate_learning_objectives( { - "learning_objectives": [{"id": str(uuid.uuid4()), "text": "LO1"}], - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "learning_objectives": [{"id": uuid.uuid4().hex, "text": "LO1"}], + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890:extra": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890:extra": [uuid.uuid4().hex] }, # Has extra characters } ) @@ -938,11 +938,11 @@ def test_learning_objectives__invalid_text_patterns(): _validate_learning_objectives( { "learning_objectives": [ - {"id": str(uuid.uuid4()), "text": " "} + {"id": uuid.uuid4().hex, "text": " "} ], # Only whitespace - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } ) @@ -952,11 +952,11 @@ def test_learning_objectives__invalid_text_patterns(): _validate_learning_objectives( { "learning_objectives": [ - {"id": str(uuid.uuid4()), "text": ""} + {"id": uuid.uuid4().hex, "text": ""} ], # Empty string - "assessment_objectives": {str(uuid.uuid4()): [str(uuid.uuid4())]}, + "assessment_objectives": {uuid.uuid4().hex: [uuid.uuid4().hex]}, "lesson_objectives": { - "abcdef1234567890abcdef1234567890": [str(uuid.uuid4())] + "abcdef1234567890abcdef1234567890": [uuid.uuid4().hex] }, } )