66import pkgutil
77import uuid
88
9+ import jsonschema
910import pytest
1011
1112from le_utils .constants import completion_criteria , embed_content_request , embed_topics_request , learning_objectives , mastery_criteria
1213
13- try :
14- # the jsonschema package for python 3.4 is too old, so if not present, we'll just skip
15- import jsonschema
16- except ImportError :
17- jsonschema = None
1814
19-
20- # create a common decorator to skip tests if jsonschema is not available
21- skip_if_jsonschema_unavailable = pytest .mark .skipif (jsonschema is None , reason = "jsonschema package is unavailable" )
22-
23-
24- resolver = None
25- if jsonschema is not None :
26- # this is an example of how to include the mastery criteria schema, which is referenced by the
27- # completion criteria schema, in the schema resolver so that it validates
28- resolver = jsonschema .RefResolver .from_schema (mastery_criteria .SCHEMA )
29- resolver .store .update (jsonschema .RefResolver .from_schema (completion_criteria .SCHEMA ).store )
15+ # this is an example of how to include the mastery criteria schema, which is referenced by the
16+ # completion criteria schema, in the schema resolver so that it validates
17+ resolver = jsonschema .RefResolver .from_schema (mastery_criteria .SCHEMA )
18+ resolver .store .update (jsonschema .RefResolver .from_schema (completion_criteria .SCHEMA ).store )
3019
3120
3221def _validate_embed_content_request (data ):
@@ -73,7 +62,6 @@ def _assert_not_raises(not_expected):
7362 raise e
7463
7564
76- @skip_if_jsonschema_unavailable
7765def test_completion_criteria__time_model__valid ():
7866 with _assert_not_raises (jsonschema .ValidationError ):
7967 _validate_completion_criteria ({"model" : "time" , "threshold" : 2 , "learner_managed" : False })
@@ -85,7 +73,6 @@ def test_completion_criteria__time_model__valid():
8573 )
8674
8775
88- @skip_if_jsonschema_unavailable
8976def test_completion_criteria__time_model__invalid ():
9077 with pytest .raises (jsonschema .ValidationError ):
9178 _validate_completion_criteria (
@@ -104,7 +91,6 @@ def test_completion_criteria__time_model__invalid():
10491 )
10592
10693
107- @skip_if_jsonschema_unavailable
10894def test_completion_criteria__approx_time_model__valid ():
10995 with _assert_not_raises (jsonschema .ValidationError ):
11096 _validate_completion_criteria ({"model" : "approx_time" , "threshold" : 2 , "learner_managed" : False })
@@ -116,7 +102,6 @@ def test_completion_criteria__approx_time_model__valid():
116102 )
117103
118104
119- @skip_if_jsonschema_unavailable
120105def test_completion_criteria__approx_time_model__invalid ():
121106 with pytest .raises (jsonschema .ValidationError ):
122107 _validate_completion_criteria (
@@ -135,7 +120,6 @@ def test_completion_criteria__approx_time_model__invalid():
135120 )
136121
137122
138- @skip_if_jsonschema_unavailable
139123def test_completion_criteria__pages_model__valid ():
140124 with _assert_not_raises (jsonschema .ValidationError ):
141125 _validate_completion_criteria ({"model" : "pages" , "threshold" : 2 , "learner_managed" : False })
@@ -147,7 +131,6 @@ def test_completion_criteria__pages_model__valid():
147131 )
148132
149133
150- @skip_if_jsonschema_unavailable
151134def test_completion_criteria__pages_model__percentage__valid ():
152135 with _assert_not_raises (jsonschema .ValidationError ):
153136 _validate_completion_criteria (
@@ -164,7 +147,6 @@ def test_completion_criteria__pages_model__percentage__valid():
164147 )
165148
166149
167- @skip_if_jsonschema_unavailable
168150def test_completion_criteria__pages_model__invalid ():
169151 with pytest .raises (jsonschema .ValidationError ):
170152 _validate_completion_criteria (
@@ -183,7 +165,6 @@ def test_completion_criteria__pages_model__invalid():
183165 )
184166
185167
186- @skip_if_jsonschema_unavailable
187168def test_completion_criteria__pages_model__percentage__invalid ():
188169 with pytest .raises (jsonschema .ValidationError ):
189170 _validate_completion_criteria (
@@ -202,7 +183,6 @@ def test_completion_criteria__pages_model__percentage__invalid():
202183 )
203184
204185
205- @skip_if_jsonschema_unavailable
206186def test_completion_criteria__mastery_model__valid ():
207187 with _assert_not_raises (jsonschema .ValidationError ):
208188 _validate_completion_criteria (
@@ -236,7 +216,6 @@ def test_completion_criteria__mastery_model__valid():
236216 )
237217
238218
239- @skip_if_jsonschema_unavailable
240219def test_completion_criteria__mastery_model__invalid ():
241220 with pytest .raises (jsonschema .ValidationError ):
242221 _validate_completion_criteria (
@@ -302,7 +281,6 @@ def test_completion_criteria__mastery_model__invalid():
302281 )
303282
304283
305- @skip_if_jsonschema_unavailable
306284def test_completion_criteria__reference__valid ():
307285 with _assert_not_raises (jsonschema .ValidationError ):
308286 _validate_completion_criteria ({"model" : "reference" , "learner_managed" : False })
@@ -313,7 +291,6 @@ def test_completion_criteria__reference__valid():
313291 )
314292
315293
316- @skip_if_jsonschema_unavailable
317294def test_completion_criteria__reference__invalid ():
318295 with pytest .raises (jsonschema .ValidationError ):
319296 _validate_completion_criteria (
@@ -333,7 +310,6 @@ def test_completion_criteria__reference__invalid():
333310 )
334311
335312
336- @skip_if_jsonschema_unavailable
337313def test_embed__topics__without_ancestors__valid ():
338314 with _assert_not_raises (jsonschema .ValidationError ):
339315 _validate_embed_topics_request (
@@ -355,7 +331,6 @@ def test_embed__topics__without_ancestors__valid():
355331 )
356332
357333
358- @skip_if_jsonschema_unavailable
359334def test_embed__topics__with_ancestors__valid ():
360335 with _assert_not_raises (jsonschema .ValidationError ):
361336 _validate_embed_topics_request (
@@ -385,7 +360,6 @@ def test_embed__topics__with_ancestors__valid():
385360 )
386361
387362
388- @skip_if_jsonschema_unavailable
389363def test_embed__topics__invalid_id ():
390364 with pytest .raises (jsonschema .ValidationError ):
391365 _validate_embed_topics_request (
@@ -407,7 +381,6 @@ def test_embed__topics__invalid_id():
407381 )
408382
409383
410- @skip_if_jsonschema_unavailable
411384def test_embed__topics__missing_language ():
412385 with pytest .raises (jsonschema .ValidationError ):
413386 _validate_embed_topics_request (
@@ -428,7 +401,6 @@ def test_embed__topics__missing_language():
428401 )
429402
430403
431- @skip_if_jsonschema_unavailable
432404def test_embed__topics__invalid_channel_id ():
433405 with pytest .raises (jsonschema .ValidationError ):
434406 _validate_embed_topics_request (
@@ -450,7 +422,6 @@ def test_embed__topics__invalid_channel_id():
450422 )
451423
452424
453- @skip_if_jsonschema_unavailable
454425def test_embed__topics__missing_channel_id ():
455426 with pytest .raises (jsonschema .ValidationError ):
456427 _validate_embed_topics_request (
@@ -471,7 +442,6 @@ def test_embed__topics__missing_channel_id():
471442 )
472443
473444
474- @skip_if_jsonschema_unavailable
475445def test_embed__topics__all_languagelookup_codes_valid ():
476446 """Every language code in languagelookup.json must be accepted by the topics schema.
477447
@@ -496,7 +466,6 @@ def test_embed__topics__all_languagelookup_codes_valid():
496466 )
497467
498468
499- @skip_if_jsonschema_unavailable
500469def test_embed__content__valid ():
501470 with _assert_not_raises (jsonschema .ValidationError ):
502471 _validate_embed_content_request (
@@ -521,7 +490,6 @@ def test_embed__content__valid():
521490 )
522491
523492
524- @skip_if_jsonschema_unavailable
525493def test_embed__content__valid_with_files ():
526494 with _assert_not_raises (jsonschema .ValidationError ):
527495 _validate_embed_content_request (
@@ -563,7 +531,6 @@ def test_embed__content__valid_with_files():
563531 )
564532
565533
566- @skip_if_jsonschema_unavailable
567534def test_embed__content__invalid_id ():
568535 with pytest .raises (jsonschema .ValidationError ):
569536 _validate_embed_content_request (
@@ -587,7 +554,6 @@ def test_embed__content__invalid_id():
587554 )
588555
589556
590- @skip_if_jsonschema_unavailable
591557def test_embed__content__invalid_channel_id ():
592558 with pytest .raises (jsonschema .ValidationError ):
593559 _validate_embed_content_request (
@@ -611,7 +577,6 @@ def test_embed__content__invalid_channel_id():
611577 )
612578
613579
614- @skip_if_jsonschema_unavailable
615580def test_embed__content__invalid_content_id ():
616581 with pytest .raises (jsonschema .ValidationError ):
617582 _validate_embed_content_request (
@@ -635,7 +600,6 @@ def test_embed__content__invalid_content_id():
635600 )
636601
637602
638- @skip_if_jsonschema_unavailable
639603def test_embed__content__invalid_channel_version ():
640604 with pytest .raises (jsonschema .ValidationError ):
641605 _validate_embed_content_request (
@@ -660,7 +624,6 @@ def test_embed__content__invalid_channel_version():
660624 )
661625
662626
663- @skip_if_jsonschema_unavailable
664627def test_embed__content__invalid_url_files ():
665628 with pytest .raises (jsonschema .ValidationError ):
666629 _validate_embed_content_request (
@@ -690,7 +653,6 @@ def test_embed__content__invalid_url_files():
690653 )
691654
692655
693- @skip_if_jsonschema_unavailable
694656def test_embed__content__invalid_preset_files ():
695657 with pytest .raises (jsonschema .ValidationError ):
696658 _validate_embed_content_request (
@@ -720,7 +682,6 @@ def test_embed__content__invalid_preset_files():
720682 )
721683
722684
723- @skip_if_jsonschema_unavailable
724685def test_embed__content__all_languagelookup_codes_valid ():
725686 """Every language code in languagelookup.json must be accepted by the content schema.
726687
@@ -756,7 +717,6 @@ def _validate_learning_objectives(data):
756717 jsonschema .validate (instance = data , schema = learning_objectives .SCHEMA )
757718
758719
759- @skip_if_jsonschema_unavailable
760720def test_learning_objectives__valid ():
761721 with _assert_not_raises (jsonschema .ValidationError ):
762722 _validate_learning_objectives (
@@ -787,7 +747,6 @@ def test_learning_objectives__valid():
787747 )
788748
789749
790- @skip_if_jsonschema_unavailable
791750def test_learning_objectives__valid_uuid_v5 ():
792751 with _assert_not_raises (jsonschema .ValidationError ):
793752 _validate_learning_objectives (
@@ -818,7 +777,6 @@ def test_learning_objectives__valid_uuid_v5():
818777 )
819778
820779
821- @skip_if_jsonschema_unavailable
822780def test_learning_objectives__invalid_lo_structure ():
823781 with pytest .raises (jsonschema .ValidationError ):
824782 _validate_learning_objectives (
@@ -832,7 +790,6 @@ def test_learning_objectives__invalid_lo_structure():
832790 )
833791
834792
835- @skip_if_jsonschema_unavailable
836793def test_learning_objectives__invalid_assessment_mapping ():
837794 with pytest .raises (jsonschema .ValidationError ):
838795 _validate_learning_objectives (
@@ -846,7 +803,6 @@ def test_learning_objectives__invalid_assessment_mapping():
846803 )
847804
848805
849- @skip_if_jsonschema_unavailable
850806def test_learning_objectives__invalid_lesson_mapping ():
851807 with pytest .raises (jsonschema .ValidationError ):
852808 _validate_learning_objectives (
@@ -860,7 +816,6 @@ def test_learning_objectives__invalid_lesson_mapping():
860816 )
861817
862818
863- @skip_if_jsonschema_unavailable
864819def test_learning_objectives__missing_required_fields ():
865820 # Missing learning_objectives
866821 with pytest .raises (jsonschema .ValidationError ):
@@ -890,7 +845,6 @@ def test_learning_objectives__missing_required_fields():
890845 )
891846
892847
893- @skip_if_jsonschema_unavailable
894848def test_learning_objectives__empty_structures ():
895849 # Empty learning_objectives
896850 with pytest .raises (jsonschema .ValidationError ):
@@ -923,7 +877,6 @@ def test_learning_objectives__empty_structures():
923877 )
924878
925879
926- @skip_if_jsonschema_unavailable
927880def test_learning_objectives__invalid_uuid_format_in_learning_objectives ():
928881 # Invalid UUID format for learning objective ID
929882 with pytest .raises (jsonschema .ValidationError ):
@@ -936,7 +889,6 @@ def test_learning_objectives__invalid_uuid_format_in_learning_objectives():
936889 )
937890
938891
939- @skip_if_jsonschema_unavailable
940892def test_learning_objectives__invalid_uuid_format_in_references ():
941893 # Invalid UUID format in assessment and lesson objective references
942894 with pytest .raises (jsonschema .ValidationError ):
@@ -949,7 +901,6 @@ def test_learning_objectives__invalid_uuid_format_in_references():
949901 )
950902
951903
952- @skip_if_jsonschema_unavailable
953904def test_learning_objectives__invalid_question_id_pattern ():
954905 # Invalid question ID pattern (not a valid UUID v4)
955906 with pytest .raises (jsonschema .ValidationError ):
@@ -962,7 +913,6 @@ def test_learning_objectives__invalid_question_id_pattern():
962913 )
963914
964915
965- @skip_if_jsonschema_unavailable
966916def test_learning_objectives__invalid_lesson_id_pattern ():
967917 # Invalid lesson ID pattern (has extra characters)
968918 with pytest .raises (jsonschema .ValidationError ):
@@ -975,7 +925,6 @@ def test_learning_objectives__invalid_lesson_id_pattern():
975925 )
976926
977927
978- @skip_if_jsonschema_unavailable
979928def test_learning_objectives__invalid_text_patterns ():
980929 # Empty text after trimming whitespace
981930 with pytest .raises (jsonschema .ValidationError ):
0 commit comments