1
+ """
2
+ Tests for course optimizer
3
+ """
4
+
5
+ import unittest
6
+ from unittest .mock import Mock , patch
7
+
8
+ from cms .djangoapps .contentstore .tests .utils import CourseTestCase
9
+ from cms .djangoapps .contentstore .core .course_optimizer_provider import (
10
+ generate_broken_links_descriptor ,
11
+ _update_node_tree_and_dictionary ,
12
+ _get_node_path ,
13
+ _create_dto_recursive
14
+ )
15
+
16
+ class TestLinkCheckProvider (CourseTestCase ):
17
+ """
18
+ Tests for functions that generate a json structure of locked and broken links
19
+ to send to the frontend.
20
+ """
21
+ def setUp (self ):
22
+ """Setup course blocks for tests"""
23
+ super ().setUp ()
24
+ self .mock_course = Mock ()
25
+ self .mock_section = Mock (
26
+ location = Mock (block_id = 'chapter_1' ),
27
+ display_name = 'Section Name' ,
28
+ category = 'chapter'
29
+ )
30
+ self .mock_subsection = Mock (
31
+ location = Mock (block_id = 'sequential_1' ),
32
+ display_name = 'Subsection Name' ,
33
+ category = 'sequential'
34
+ )
35
+ self .mock_unit = Mock (
36
+ location = Mock (block_id = 'vertical_1' ),
37
+ display_name = 'Unit Name' ,
38
+ category = 'vertical'
39
+ )
40
+ self .mock_block = Mock (
41
+ location = Mock (block_id = 'block_1' ),
42
+ display_name = 'Block Name' ,
43
+ course_id = self .course .id ,
44
+ category = 'html'
45
+ )
46
+ self .mock_course .get_parent .return_value = None
47
+ self .mock_section .get_parent .return_value = self .mock_course
48
+ self .mock_subsection .get_parent .return_value = self .mock_section
49
+ self .mock_unit .get_parent .return_value = self .mock_subsection
50
+ self .mock_block .get_parent .return_value = self .mock_unit
51
+
52
+
53
+ def test_update_node_tree_and_dictionary_returns_node_tree (self ):
54
+ """
55
+ Verify _update_node_tree_and_dictionary creates a node tree structure
56
+ when passed a block level xblock.
57
+ """
58
+ expected_tree = {
59
+ 'chapter_1' : {
60
+ 'sequential_1' : {
61
+ 'vertical_1' : {
62
+ 'block_1' : {}
63
+ }
64
+ }
65
+ }
66
+ }
67
+ result_tree , result_dictionary = _update_node_tree_and_dictionary (
68
+ self .mock_block , 'example_link' , True , {}, {}
69
+ )
70
+
71
+ self .assertEqual (expected_tree , result_tree )
72
+
73
+
74
+ def test_update_node_tree_and_dictionary_returns_dictionary (self ):
75
+ """
76
+ Verify _update_node_tree_and_dictionary creates a dictionary of parent xblock entries
77
+ when passed a block level xblock.
78
+ """
79
+ expected_dictionary = {
80
+ 'chapter_1' : {
81
+ 'display_name' : 'Section Name' ,
82
+ 'category' : 'chapter'
83
+ },
84
+ 'sequential_1' : {
85
+ 'display_name' : 'Subsection Name' ,
86
+ 'category' : 'sequential'
87
+ },
88
+ 'vertical_1' : {
89
+ 'display_name' : 'Unit Name' ,
90
+ 'category' : 'vertical'
91
+ },
92
+ 'block_1' : {
93
+ 'display_name' : 'Block Name' ,
94
+ 'category' : 'html' ,
95
+ 'url' : f'/course/{ self .course .id } /editor/html/{ self .mock_block .location } ' ,
96
+ 'locked_links' : ['example_link' ]
97
+ }
98
+ }
99
+ result_tree , result_dictionary = _update_node_tree_and_dictionary (
100
+ self .mock_block , 'example_link' , True , {}, {}
101
+ )
102
+
103
+ self .assertEqual (expected_dictionary , result_dictionary )
104
+
105
+
106
+ def test_create_dto_recursive_returns_for_empty_node (self ):
107
+ """
108
+ Test _create_dto_recursive behavior at the end of recursion.
109
+ Function should return None when given empty node tree and empty dictionary.
110
+ """
111
+ expected = _create_dto_recursive ({}, {})
112
+ self .assertEqual (None , expected )
113
+
114
+
115
+ def test_create_dto_recursive_returns_for_leaf_node (self ):
116
+ """
117
+ Test _create_dto_recursive behavior at the step before the end of recursion.
118
+ When evaluating a leaf node in the node tree, the function should return broken links
119
+ and locked links data from the leaf node.
120
+ """
121
+ expected_result = {
122
+ 'blocks' : [
123
+ {
124
+ 'id' : 'block_1' ,
125
+ 'displayName' : 'Block Name' ,
126
+ 'url' : '/block/1' ,
127
+ 'brokenLinks' : ['broken_link_1' , 'broken_link_2' ],
128
+ 'lockedLinks' : ['locked_link' ]
129
+ }
130
+ ]
131
+ }
132
+
133
+ mock_node_tree = {
134
+ 'block_1' : {}
135
+ }
136
+ mock_dictionary = {
137
+ 'chapter_1' : {
138
+ 'display_name' : 'Section Name' ,
139
+ 'category' : 'chapter'
140
+ },
141
+ 'sequential_1' : {
142
+ 'display_name' : 'Subsection Name' ,
143
+ 'category' : 'sequential'
144
+ },
145
+ 'vertical_1' : {
146
+ 'display_name' : 'Unit Name' ,
147
+ 'category' : 'vertical'
148
+ },
149
+ 'block_1' : {
150
+ 'display_name' : 'Block Name' ,
151
+ 'url' : '/block/1' ,
152
+ 'broken_links' : ['broken_link_1' , 'broken_link_2' ],
153
+ 'locked_links' : ['locked_link' ]
154
+ }
155
+ }
156
+ expected = _create_dto_recursive (mock_node_tree , mock_dictionary )
157
+ self .assertEqual (expected_result , expected )
158
+
159
+
160
+ def test_create_dto_recursive_returns_for_full_tree (self ):
161
+ """
162
+ Test _create_dto_recursive behavior when recursing many times.
163
+ When evaluating a fully mocked node tree and dictionary, the function should return
164
+ a full json DTO prepared for frontend.
165
+ """
166
+ expected_result = {
167
+ 'sections' : [
168
+ {
169
+ 'id' : 'chapter_1' ,
170
+ 'displayName' : 'Section Name' ,
171
+ 'subsections' : [
172
+ {
173
+ 'id' : 'sequential_1' ,
174
+ 'displayName' : 'Subsection Name' ,
175
+ 'units' : [
176
+ {
177
+ 'id' : 'vertical_1' ,
178
+ 'displayName' : 'Unit Name' ,
179
+ 'blocks' : [
180
+ {
181
+ 'id' : 'block_1' ,
182
+ 'displayName' : 'Block Name' ,
183
+ 'url' : '/block/1' ,
184
+ 'brokenLinks' : ['broken_link_1' , 'broken_link_2' ],
185
+ 'lockedLinks' : ['locked_link' ]
186
+ }
187
+ ]
188
+ }
189
+ ]
190
+ }
191
+ ]
192
+ }
193
+ ]
194
+ }
195
+
196
+ mock_node_tree = {
197
+ 'chapter_1' : {
198
+ 'sequential_1' : {
199
+ 'vertical_1' : {
200
+ 'block_1' : {}
201
+ }
202
+ }
203
+ }
204
+ }
205
+ mock_dictionary = {
206
+ 'chapter_1' : {
207
+ 'display_name' : 'Section Name' ,
208
+ 'category' : 'chapter'
209
+ },
210
+ 'sequential_1' : {
211
+ 'display_name' : 'Subsection Name' ,
212
+ 'category' : 'sequential'
213
+ },
214
+ 'vertical_1' : {
215
+ 'display_name' : 'Unit Name' ,
216
+ 'category' : 'vertical'
217
+ },
218
+ 'block_1' : {
219
+ 'display_name' : 'Block Name' ,
220
+ 'url' : '/block/1' ,
221
+ 'broken_links' : ['broken_link_1' , 'broken_link_2' ],
222
+ 'locked_links' : ['locked_link' ]
223
+ }
224
+ }
225
+ expected = _create_dto_recursive (mock_node_tree , mock_dictionary )
226
+
227
+ self .assertEqual (expected_result , expected )
228
+
0 commit comments