Skip to content

Commit d4679b1

Browse files
committed
Add unit learning objectives schema
1 parent 8cbc170 commit d4679b1

4 files changed

Lines changed: 330 additions & 0 deletions

File tree

js/LearningObjectives.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// -*- coding: utf-8 -*-
2+
// Generated by scripts/generate_from_specs.py
3+
// LearningObjectives
4+
5+
6+
export const SCHEMA = {
7+
"$id": "/schemas/learning_objectives",
8+
"$schema": "http://json-schema.org/draft-07/schema#",
9+
"type": "object",
10+
"description": "Schema for Learning Objectives mapping",
11+
"additionalProperties": false,
12+
"definitions": {
13+
"learning_objective_id": {
14+
"type": "string",
15+
"description": "Unique identifier for the Learning Objective"
16+
}
17+
},
18+
"properties": {
19+
"learning_objectives": {
20+
"type": "array",
21+
"description": "A list of Learning Objectives available in the unit",
22+
"minItems": 1,
23+
"items": {
24+
"type": "object",
25+
"properties": {
26+
"id": {
27+
"$ref": "#/definitions/learning_objective_id"
28+
},
29+
"text": {
30+
"type": "string",
31+
"description": "Human-readable text describing the Learning Objective"
32+
},
33+
"metadata": {
34+
"type": "object",
35+
"description": "Optional metadata associated with the Learning Objective"
36+
}
37+
},
38+
"required": ["id", "text"]
39+
}
40+
},
41+
"assessment_objectives": {
42+
"type": "object",
43+
"description": "Mapping of assessment question IDs to Learning Objective IDs",
44+
"minProperties": 1,
45+
"patternProperties": {
46+
"^.*$": {
47+
"type": "array",
48+
"items": { "$ref": "#/definitions/learning_objective_id" }
49+
}
50+
}
51+
},
52+
"lesson_objectives": {
53+
"type": "object",
54+
"description": "Mapping of lesson content node IDs to Learning Objective IDs",
55+
"minProperties": 1,
56+
"patternProperties": {
57+
"^.*$": {
58+
"type": "array",
59+
"items": { "$ref": "#/definitions/learning_objective_id" }
60+
}
61+
}
62+
}
63+
},
64+
"required": ["learning_objectives", "assessment_objectives", "lesson_objectives"]
65+
}
66+
;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by scripts/generate_from_specs.py
3+
from __future__ import unicode_literals
4+
5+
# LearningObjectives
6+
7+
8+
choices = ()
9+
10+
LEARNINGOBJECTIVESLIST = []
11+
12+
SCHEMA = {
13+
"$id": "/schemas/learning_objectives",
14+
"$schema": "http://json-schema.org/draft-07/schema#",
15+
"type": "object",
16+
"description": "Schema for Learning Objectives mapping",
17+
"additionalProperties": False,
18+
"definitions": {
19+
"learning_objective_id": {
20+
"type": "string",
21+
"description": "Unique identifier for the Learning Objective",
22+
}
23+
},
24+
"properties": {
25+
"learning_objectives": {
26+
"type": "array",
27+
"description": "A list of Learning Objectives available in the unit",
28+
"minItems": 1,
29+
"items": {
30+
"type": "object",
31+
"properties": {
32+
"id": {"$ref": "#/definitions/learning_objective_id"},
33+
"text": {
34+
"type": "string",
35+
"description": "Human-readable text describing the Learning Objective",
36+
},
37+
"metadata": {
38+
"type": "object",
39+
"description": "Optional metadata associated with the Learning Objective",
40+
},
41+
},
42+
"required": ["id", "text"],
43+
},
44+
},
45+
"assessment_objectives": {
46+
"type": "object",
47+
"description": "Mapping of assessment question IDs to Learning Objective IDs",
48+
"minProperties": 1,
49+
"patternProperties": {
50+
"^.*$": {
51+
"type": "array",
52+
"items": {"$ref": "#/definitions/learning_objective_id"},
53+
}
54+
},
55+
},
56+
"lesson_objectives": {
57+
"type": "object",
58+
"description": "Mapping of lesson content node IDs to Learning Objective IDs",
59+
"minProperties": 1,
60+
"patternProperties": {
61+
"^.*$": {
62+
"type": "array",
63+
"items": {"$ref": "#/definitions/learning_objective_id"},
64+
}
65+
},
66+
},
67+
},
68+
"required": ["learning_objectives", "assessment_objectives", "lesson_objectives"],
69+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"$id": "/schemas/learning_objectives",
3+
"$schema": "http://json-schema.org/draft-07/schema#",
4+
"type": "object",
5+
"description": "Schema for Learning Objectives mapping",
6+
"additionalProperties": false,
7+
"definitions": {
8+
"learning_objective_id": {
9+
"type": "string",
10+
"description": "Unique identifier for the Learning Objective"
11+
}
12+
},
13+
"properties": {
14+
"learning_objectives": {
15+
"type": "array",
16+
"description": "A list of Learning Objectives available in the unit",
17+
"minItems": 1,
18+
"items": {
19+
"type": "object",
20+
"properties": {
21+
"id": {
22+
"$ref": "#/definitions/learning_objective_id"
23+
},
24+
"text": {
25+
"type": "string",
26+
"description": "Human-readable text describing the Learning Objective"
27+
},
28+
"metadata": {
29+
"type": "object",
30+
"description": "Optional metadata associated with the Learning Objective"
31+
}
32+
},
33+
"required": ["id", "text"]
34+
}
35+
},
36+
"assessment_objectives": {
37+
"type": "object",
38+
"description": "Mapping of assessment question IDs to Learning Objective IDs",
39+
"minProperties": 1,
40+
"patternProperties": {
41+
"^.*$": {
42+
"type": "array",
43+
"items": { "$ref": "#/definitions/learning_objective_id" }
44+
}
45+
}
46+
},
47+
"lesson_objectives": {
48+
"type": "object",
49+
"description": "Mapping of lesson content node IDs to Learning Objective IDs",
50+
"minProperties": 1,
51+
"patternProperties": {
52+
"^.*$": {
53+
"type": "array",
54+
"items": { "$ref": "#/definitions/learning_objective_id" }
55+
}
56+
}
57+
}
58+
},
59+
"required": ["learning_objectives", "assessment_objectives", "lesson_objectives"]
60+
}

tests/test_schemas.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from le_utils.constants import completion_criteria
1010
from le_utils.constants import embed_content_request
1111
from le_utils.constants import embed_topics_request
12+
from le_utils.constants import learning_objectives
1213
from le_utils.constants import mastery_criteria
1314

1415
try:
@@ -622,5 +623,139 @@ def test_embed__content__invalid_preset_files():
622623
"channel_title": "Channel title",
623624
"some_additional_field": "some_random_value",
624625
},
626+
def _validate_learning_objectives(data):
627+
"""
628+
:param data: Dictionary of data to validate
629+
:raises: jsonschema.ValidationError: When invalid
630+
"""
631+
jsonschema.validate(instance=data, schema=learning_objectives.SCHEMA)
632+
633+
634+
@skip_if_jsonschema_unavailable
635+
def test_learning_objectives__valid():
636+
with _assert_not_raises(jsonschema.ValidationError):
637+
_validate_learning_objectives(
638+
{
639+
"learning_objectives": [
640+
{"id": "lo1", "text": "Learning Objective 1"},
641+
{
642+
"id": "lo2",
643+
"text": "Learning Objective 2",
644+
"metadata": {"key": "value"},
645+
},
646+
],
647+
"assessment_objectives": {
648+
"q1": ["lo1"],
649+
"q2": ["lo1", "lo2"],
650+
},
651+
"lesson_objectives": {
652+
"lesson1": ["lo1"],
653+
"lesson2": ["lo2"],
654+
},
655+
}
656+
)
657+
658+
659+
@skip_if_jsonschema_unavailable
660+
def test_learning_objectives__invalid_lo_structure():
661+
with pytest.raises(jsonschema.ValidationError):
662+
_validate_learning_objectives(
663+
{
664+
"learning_objectives": [
665+
{"id": "lo1"}, # Missing text
666+
],
667+
"assessment_objectives": {"q1": ["lo1"]},
668+
"lesson_objectives": {"lesson1": ["lo1"]},
669+
}
670+
)
671+
672+
673+
@skip_if_jsonschema_unavailable
674+
def test_learning_objectives__invalid_assessment_mapping():
675+
with pytest.raises(jsonschema.ValidationError):
676+
_validate_learning_objectives(
677+
{
678+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
679+
"assessment_objectives": {
680+
"q1": "lo1", # Should be an array
681+
},
682+
"lesson_objectives": {"lesson1": ["lo1"]},
683+
}
684+
)
685+
686+
687+
@skip_if_jsonschema_unavailable
688+
def test_learning_objectives__invalid_lesson_mapping():
689+
with pytest.raises(jsonschema.ValidationError):
690+
_validate_learning_objectives(
691+
{
692+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
693+
"assessment_objectives": {"q1": ["lo1"]},
694+
"lesson_objectives": {
695+
"lesson1": "lo1", # Should be an array
696+
},
697+
}
698+
)
699+
700+
701+
@skip_if_jsonschema_unavailable
702+
def test_learning_objectives__missing_required_fields():
703+
# Missing learning_objectives
704+
with pytest.raises(jsonschema.ValidationError):
705+
_validate_learning_objectives(
706+
{
707+
"assessment_objectives": {"q1": ["lo1"]},
708+
"lesson_objectives": {"lesson1": ["lo1"]},
709+
}
710+
)
711+
712+
# Missing assessment_objectives
713+
with pytest.raises(jsonschema.ValidationError):
714+
_validate_learning_objectives(
715+
{
716+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
717+
"lesson_objectives": {"lesson1": ["lo1"]},
718+
}
719+
)
720+
721+
# Missing lesson_objectives
722+
with pytest.raises(jsonschema.ValidationError):
723+
_validate_learning_objectives(
724+
{
725+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
726+
"assessment_objectives": {"q1": ["lo1"]},
727+
}
728+
)
729+
730+
731+
@skip_if_jsonschema_unavailable
732+
def test_learning_objectives__empty_structures():
733+
# Empty learning_objectives
734+
with pytest.raises(jsonschema.ValidationError):
735+
_validate_learning_objectives(
736+
{
737+
"learning_objectives": [],
738+
"assessment_objectives": {"q1": ["lo1"]},
739+
"lesson_objectives": {"lesson1": ["lo1"]},
740+
}
741+
)
742+
743+
# Empty assessment_objectives
744+
with pytest.raises(jsonschema.ValidationError):
745+
_validate_learning_objectives(
746+
{
747+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
748+
"assessment_objectives": {},
749+
"lesson_objectives": {"lesson1": ["lo1"]},
750+
}
751+
)
752+
753+
# Empty lesson_objectives
754+
with pytest.raises(jsonschema.ValidationError):
755+
_validate_learning_objectives(
756+
{
757+
"learning_objectives": [{"id": "lo1", "text": "LO1"}],
758+
"assessment_objectives": {"q1": ["lo1"]},
759+
"lesson_objectives": {},
625760
}
626761
)

0 commit comments

Comments
 (0)