88class UnitTestCase (ComponentTestCase ):
99
1010 def setUp (self ) -> None :
11- self .component_1 , self .component_version_1 = authoring_api .create_component_and_version (
11+ self .component_1 , self .component_1_v1 = authoring_api .create_component_and_version (
1212 self .learning_package .id ,
1313 component_type = self .problem_type ,
1414 local_key = "Query Counting" ,
1515 title = "Querying Counting Problem" ,
1616 created = self .now ,
1717 created_by = None ,
1818 )
19- self .component_2 , self .component_version_2 = authoring_api .create_component_and_version (
19+ self .component_2 , self .component_2_v2 = authoring_api .create_component_and_version (
2020 self .learning_package .id ,
2121 component_type = self .problem_type ,
2222 local_key = "Query Counting (2)" ,
@@ -82,7 +82,7 @@ def test_create_next_unit_version_with_two_components(self):
8282 self .component_2 .publishable_entity .id ,
8383 ],
8484 draft_version_pks = [None , None ],
85- published_version_pks = [None , None ],
85+ published_version_pks = [None , None ], # FIXME: why do we specify this?
8686 created = self .now ,
8787 created_by = None ,
8888 )
@@ -93,6 +93,119 @@ def test_create_next_unit_version_with_two_components(self):
9393 authoring_api .UnitListEntry (component_version = self .component_2 .versioning .draft , pinned = False ),
9494 ]
9595
96+ def test_add_component_after_publish (self ):
97+ """
98+ Adding a component to a published unit will create a new version and
99+ show that the unit has unpublished changes.
100+ """
101+ unit , unit_version = authoring_api .create_unit_and_version (
102+ learning_package_id = self .learning_package .id ,
103+ key = f"unit:key" ,
104+ title = "Unit" ,
105+ created = self .now ,
106+ created_by = None ,
107+ )
108+ assert unit .versioning .draft == unit_version
109+ assert unit .versioning .published is None
110+ assert unit .versioning .has_unpublished_changes == True
111+ # Publish the empty unit:
112+ authoring_api .publish_all_drafts (self .learning_package .id )
113+ unit .refresh_from_db () # Reloading the unit is necessary
114+ assert unit .versioning .has_unpublished_changes == False
115+
116+ # Add a published component (unpinned):
117+ assert self .component_1 .versioning .has_unpublished_changes == False
118+ unit_version_v2 = authoring_api .create_next_unit_version (
119+ unit = unit ,
120+ title = unit_version .title ,
121+ publishable_entities_pks = [
122+ self .component_1 .publishable_entity .id ,
123+ ],
124+ draft_version_pks = [None ],
125+ published_version_pks = [None ], # FIXME: why do we specify this?
126+ created = self .now ,
127+ created_by = None ,
128+ )
129+ # Now the unit should have unpublished changes:
130+ unit .refresh_from_db () # Reloading the unit is necessary
131+ assert unit .versioning .has_unpublished_changes == True
132+ assert unit .versioning .draft == unit_version_v2
133+ assert unit .versioning .published == unit_version
134+
135+ def test_modify_component_after_publish (self ):
136+ """
137+ Modifying a component in a published unit will NOT create a new version
138+ nor show that the unit has unpublished changes. The modifications will
139+ appear in the published version of the unit only after the component is
140+ published.
141+ """
142+ # Create a unit:
143+ unit , unit_version = authoring_api .create_unit_and_version (
144+ learning_package_id = self .learning_package .id ,
145+ key = f"unit:key" ,
146+ title = "Unit" ,
147+ created = self .now ,
148+ created_by = None ,
149+ )
150+ # Add a draft component (unpinned):
151+ assert self .component_1 .versioning .has_unpublished_changes == True
152+ unit_version_v2 = authoring_api .create_next_unit_version (
153+ unit = unit ,
154+ title = unit_version .title ,
155+ publishable_entities_pks = [
156+ self .component_1 .publishable_entity .id ,
157+ ],
158+ draft_version_pks = [None ],
159+ published_version_pks = [None ], # FIXME: why do we specify this?
160+ created = self .now ,
161+ created_by = None ,
162+ )
163+ # Publish the unit and the component:
164+ authoring_api .publish_all_drafts (self .learning_package .id )
165+ unit .refresh_from_db () # Reloading the unit is necessary
166+ self .component_1 .refresh_from_db ()
167+ assert unit .versioning .has_unpublished_changes == False
168+ assert self .component_1 .versioning .has_unpublished_changes == False
169+
170+ # Now modify the component by changing its title (it remains a draft):
171+ component_1_v2 = authoring_api .create_next_component_version (
172+ self .component_1 .pk ,
173+ content_to_replace = {},
174+ title = "Modified Counting Problem with new title" ,
175+ created = self .now ,
176+ created_by = None ,
177+ )
178+
179+ # The component now has unpublished changes, but the unit doesn't (⭐️ Is this what we want? ⭐️)
180+ unit .refresh_from_db () # Reloading the unit is necessary
181+ self .component_1 .refresh_from_db ()
182+ assert unit .versioning .has_unpublished_changes == False
183+ assert self .component_1 .versioning .has_unpublished_changes == True
184+
185+ # Since the component changes haven't been published, they should only appear in the draft unit
186+ assert authoring_api .get_components_in_draft_unit (unit ) == [
187+ authoring_api .UnitListEntry (component_version = component_1_v2 , pinned = False ), # new version
188+ ]
189+ assert authoring_api .get_components_in_published_unit (unit ) == [
190+ authoring_api .UnitListEntry (component_version = self .component_1_v1 , pinned = False ), # old version
191+ ]
192+
193+ # But if we publish the component, the changes will appear in the published version of the unit.
194+ self .publish_component (self .component_1 )
195+ assert authoring_api .get_components_in_draft_unit (unit ) == [
196+ authoring_api .UnitListEntry (component_version = component_1_v2 , pinned = False ), # new version
197+ ]
198+ assert authoring_api .get_components_in_published_unit (unit ) == [
199+ authoring_api .UnitListEntry (component_version = component_1_v2 , pinned = False ), # new version
200+ ]
201+
202+
203+ # Test that only components can be added to units
204+ # Test that components must be in the same learning package
205+ # Test that _version_pks=[] arguments must be related to publishable_entities_pks
206+ # Test that publishing a unit publishes its components
207+ # Test viewing old snapshots of units and components by passing in a timestamp to some get_historic_unit() API
208+
96209
97210 def test_next_version_with_different_different_title (self ):
98211 """Test creating a unit version with a different title.
0 commit comments