88import io
99import bleach
1010
11- from unittest .mock import patch
11+ from unittest .mock import call , patch
1212from pathlib import Path
1313from pyquery import PyQuery
1414from tempfile import NamedTemporaryFile
1515
1616import debug # pyflakes:ignore
1717
1818from django .conf import settings
19+ from django .http import Http404 , HttpResponse
1920from django .test import RequestFactory
2021from django .test .utils import override_settings
2122from django .urls import reverse as urlreverse
3536 DatedGroupMilestoneFactory , DatelessGroupMilestoneFactory )
3637from ietf .group .forms import GroupForm
3738from ietf .group .models import Group , GroupEvent , GroupMilestone , GroupStateTransitions , Role
38- from ietf .group .tasks import generate_wg_charters_files_task
39+ from ietf .group .tasks import generate_wg_charters_files_task , generate_wg_summary_files_task
40+ from ietf .group .views import response_from_file
3941from ietf .group .utils import save_group_in_history , setup_default_community_list_for_group
4042from ietf .meeting .factories import SessionFactory
4143from ietf .name .models import DocTagName , GroupStateName , GroupTypeName , ExtResourceName , RoleName
@@ -58,7 +60,11 @@ def pklist(docs):
5860 return [ str (doc .pk ) for doc in docs .all () ]
5961
6062class GroupPagesTests (TestCase ):
61- settings_temp_path_overrides = TestCase .settings_temp_path_overrides + ['CHARTER_PATH' , 'CHARTER_COPY_PATH' ]
63+ settings_temp_path_overrides = TestCase .settings_temp_path_overrides + [
64+ "CHARTER_PATH" ,
65+ "CHARTER_COPY_PATH" ,
66+ "GROUP_SUMMARY_PATH" ,
67+ ]
6268
6369 def test_active_groups (self ):
6470 area = GroupFactory .create (type_id = 'area' )
@@ -112,63 +118,90 @@ def test_group_home(self):
112118 self .assertContains (r , draft .name )
113119 self .assertContains (r , draft .title )
114120
115- def test_wg_summaries (self ):
116- group = CharterFactory (group__type_id = 'wg' ,group__parent = GroupFactory (type_id = 'area' )).group
117- RoleFactory (group = group ,name_id = 'chair' ,person = PersonFactory ())
118- RoleFactory (group = group ,name_id = 'ad' ,person = PersonFactory ())
119-
120- chair = Email .objects .filter (role__group = group , role__name = "chair" )[0 ]
121-
122- url = urlreverse ('ietf.group.views.wg_summary_area' , kwargs = dict (group_type = "wg" ))
123- r = self .client .get (url )
121+ def test_response_from_file (self ):
122+ # n.b., GROUP_SUMMARY_PATH is a temp dir that will be cleaned up automatically
123+ fp = Path (settings .GROUP_SUMMARY_PATH ) / "some-file.txt"
124+ fp .write_text ("This is a charters file with an é" )
125+ r = response_from_file (fp )
124126 self .assertEqual (r .status_code , 200 )
125- self .assertContains (r , group .parent .name )
126- self .assertContains (r , group .acronym )
127- self .assertContains (r , group .name )
128- self .assertContains (r , chair .address )
129-
130- url = urlreverse ('ietf.group.views.wg_summary_acronym' , kwargs = dict (group_type = "wg" ))
131- r = self .client .get (url )
132- self .assertEqual (r .status_code , 200 )
133- self .assertContains (r , group .acronym )
134- self .assertContains (r , group .name )
135- self .assertContains (r , chair .address )
136-
137- def test_wg_charters (self ):
138- # file does not exist = 404
139- url = urlreverse ("ietf.group.views.wg_charters" , kwargs = dict (group_type = "wg" ))
140- r = self .client .get (url )
127+ self .assertEqual (r .headers ["Content-Type" ], "text/plain; charset=utf-8" )
128+ self .assertEqual (r .content .decode ("utf8" ), "This is a charters file with an é" )
129+ # now try with a nonexistent file
130+ fp .unlink ()
131+ with self .assertRaises (Http404 ):
132+ response_from_file (fp )
133+
134+ @patch ("ietf.group.views.response_from_file" )
135+ def test_wg_summary_area (self , mock ):
136+ r = self .client .get (
137+ urlreverse ("ietf.group.views.wg_summary_area" , kwargs = {"group_type" : "rg" })
138+ ) # not wg
141139 self .assertEqual (r .status_code , 404 )
142-
143- # should return expected file with expected encoding
144- wg_path = Path ( settings . CHARTER_PATH ) / "1wg-charters.txt"
145- wg_path . write_text ( "This is a charters file with an é" )
146- r = self . client . get ( url )
140+ self . assertFalse ( mock . called )
141+ mock . return_value = HttpResponse ( "yay" )
142+ r = self . client . get (
143+ urlreverse ( "ietf.group.views.wg_summary_area" , kwargs = { "group_type" : "wg" } )
144+ )
147145 self .assertEqual (r .status_code , 200 )
148- self .assertEqual (r .charset , "UTF-8" )
149- self .assertEqual (r .content .decode ("utf8" ), "This is a charters file with an é" )
150-
151- # non-wg request = 404 even if the file exists
152- url = urlreverse ("ietf.group.views.wg_charters" , kwargs = dict (group_type = "rg" ))
153- r = self .client .get (url )
146+ self .assertEqual (r .content .decode (), "yay" )
147+ self .assertEqual (mock .call_args , call (Path (settings .GROUP_SUMMARY_PATH ) / "1wg-summary.txt" ))
148+
149+ @patch ("ietf.group.views.response_from_file" )
150+ def test_wg_summary_acronym (self , mock ):
151+ r = self .client .get (
152+ urlreverse (
153+ "ietf.group.views.wg_summary_acronym" , kwargs = {"group_type" : "rg" }
154+ )
155+ ) # not wg
154156 self .assertEqual (r .status_code , 404 )
157+ self .assertFalse (mock .called )
158+ mock .return_value = HttpResponse ("yay" )
159+ r = self .client .get (
160+ urlreverse (
161+ "ietf.group.views.wg_summary_acronym" , kwargs = {"group_type" : "wg" }
162+ )
163+ )
164+ self .assertEqual (r .status_code , 200 )
165+ self .assertEqual (r .content .decode (), "yay" )
166+ self .assertEqual (
167+ mock .call_args , call (Path (settings .GROUP_SUMMARY_PATH ) / "1wg-summary-by-acronym.txt" )
168+ )
155169
156- def test_wg_charters_by_acronym (self ):
157- url = urlreverse ("ietf.group.views.wg_charters_by_acronym" , kwargs = dict (group_type = "wg" ))
158- r = self .client .get (url )
170+ @patch ("ietf.group.views.response_from_file" )
171+ def test_wg_charters (self , mock ):
172+ r = self .client .get (
173+ urlreverse ("ietf.group.views.wg_charters" , kwargs = {"group_type" : "rg" })
174+ ) # not wg
159175 self .assertEqual (r .status_code , 404 )
160-
161- wg_path = Path (settings .CHARTER_PATH ) / "1wg-charters-by-acronym.txt"
162- wg_path .write_text ("This is a charters file with an é" )
163- r = self .client .get (url )
176+ self .assertFalse (mock .called )
177+ mock .return_value = HttpResponse ("yay" )
178+ r = self .client .get (
179+ urlreverse ("ietf.group.views.wg_charters" , kwargs = {"group_type" : "wg" })
180+ )
164181 self .assertEqual (r .status_code , 200 )
165- self .assertEqual (r .charset , "UTF-8" )
166- self .assertEqual (r .content .decode ("utf8" ), "This is a charters file with an é" )
167-
168- # non-wg request = 404 even if the file exists
169- url = urlreverse ("ietf.group.views.wg_charters_by_acronym" , kwargs = dict (group_type = "rg" ))
170- r = self .client .get (url )
182+ self .assertEqual (r .content .decode (), "yay" )
183+ self .assertEqual (mock .call_args , call (Path (settings .CHARTER_PATH ) / "1wg-charters.txt" ))
184+
185+ @patch ("ietf.group.views.response_from_file" )
186+ def test_wg_charters_by_acronym (self , mock ):
187+ r = self .client .get (
188+ urlreverse (
189+ "ietf.group.views.wg_charters_by_acronym" , kwargs = {"group_type" : "rg" }
190+ )
191+ ) # not wg
171192 self .assertEqual (r .status_code , 404 )
193+ self .assertFalse (mock .called )
194+ mock .return_value = HttpResponse ("yay" )
195+ r = self .client .get (
196+ urlreverse (
197+ "ietf.group.views.wg_charters_by_acronym" , kwargs = {"group_type" : "wg" }
198+ )
199+ )
200+ self .assertEqual (r .status_code , 200 )
201+ self .assertEqual (r .content .decode (), "yay" )
202+ self .assertEqual (
203+ mock .call_args , call (Path (settings .CHARTER_PATH ) / "1wg-charters-by-acronym.txt" )
204+ )
172205
173206 def test_generate_wg_charters_files_task (self ):
174207 group = CharterFactory (
@@ -254,6 +287,30 @@ def test_generate_wg_charters_files_task_without_copy(self):
254287 )
255288 self .assertEqual (not_a_dir .read_text (), "Not a dir" )
256289
290+ def test_generate_wg_summary_files_task (self ):
291+ group = CharterFactory (group__type_id = 'wg' ,group__parent = GroupFactory (type_id = 'area' )).group
292+ RoleFactory (group = group ,name_id = 'chair' ,person = PersonFactory ())
293+ RoleFactory (group = group ,name_id = 'ad' ,person = PersonFactory ())
294+
295+ chair = Email .objects .filter (role__group = group , role__name = "chair" )[0 ]
296+
297+ generate_wg_summary_files_task ()
298+
299+ summary_by_area_contents = (
300+ Path (settings .GROUP_SUMMARY_PATH ) / "1wg-summary.txt"
301+ ).read_text (encoding = "utf8" )
302+ self .assertIn (group .parent .name , summary_by_area_contents )
303+ self .assertIn (group .acronym , summary_by_area_contents )
304+ self .assertIn (group .name , summary_by_area_contents )
305+ self .assertIn (chair .address , summary_by_area_contents )
306+
307+ summary_by_acronym_contents = (
308+ Path (settings .GROUP_SUMMARY_PATH ) / "1wg-summary-by-acronym.txt"
309+ ).read_text (encoding = "utf8" )
310+ self .assertIn (group .acronym , summary_by_acronym_contents )
311+ self .assertIn (group .name , summary_by_acronym_contents )
312+ self .assertIn (chair .address , summary_by_acronym_contents )
313+
257314 def test_chartering_groups (self ):
258315 group = CharterFactory (group__type_id = 'wg' ,group__parent = GroupFactory (type_id = 'area' ),states = [('charter' ,'intrev' )]).group
259316
0 commit comments