Skip to content

Commit cffae05

Browse files
committed
Add earning objectives schema
1 parent 8cbc170 commit cffae05

File tree

4 files changed

+334
-0
lines changed

4 files changed

+334
-0
lines changed

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

0 commit comments

Comments
 (0)