@@ -63,6 +63,11 @@ def _list(self, kwargs):
6363 def _detail (self , kwargs ):
6464 return self .client .get (reverse ("api-v2-users-detail" , kwargs = kwargs ))
6565
66+ def _patch (self , kwargs , data ):
67+ return self .client .patch (
68+ reverse ("api-v2-users-detail" , kwargs = kwargs ), data = data
69+ )
70+
6671 def setUp (self ):
6772 self .org = OwnerFactory (service = "github" )
6873 self .current_owner = OwnerFactory (service = "github" , organizations = [self .org .pk ])
@@ -179,6 +184,302 @@ def test_retrieve_cannot_get_details_if_not_member_of_org(self):
179184 "email" : another_user .email ,
180185 }
181186
187+ def test_update_activate_by_username (self ):
188+ another_user = OwnerFactory (service = "github" , organizations = [self .org .pk ])
189+
190+ # Activate user
191+ response = self ._patch (
192+ kwargs = {
193+ "service" : self .org .service ,
194+ "owner_username" : self .org .username ,
195+ "user_username_or_ownerid" : another_user .username ,
196+ },
197+ data = {"activated" : True },
198+ )
199+ assert response .status_code == status .HTTP_200_OK
200+ assert response .data == {
201+ "service" : "github" ,
202+ "username" : another_user .username ,
203+ "name" : another_user .name ,
204+ "activated" : True ,
205+ "is_admin" : False ,
206+ "email" : another_user .email ,
207+ }
208+
209+ # Deactivate user
210+ response = self ._patch (
211+ kwargs = {
212+ "service" : self .org .service ,
213+ "owner_username" : self .org .username ,
214+ "user_username_or_ownerid" : another_user .username ,
215+ },
216+ data = {"activated" : False },
217+ )
218+ assert response .status_code == status .HTTP_200_OK
219+ assert response .data == {
220+ "service" : "github" ,
221+ "username" : another_user .username ,
222+ "name" : another_user .name ,
223+ "activated" : False ,
224+ "is_admin" : False ,
225+ "email" : another_user .email ,
226+ }
227+
228+ def test_update_activate_by_ownerid (self ):
229+ another_user = OwnerFactory (service = "github" , organizations = [self .org .pk ])
230+
231+ # Activate user
232+ response = self ._patch (
233+ kwargs = {
234+ "service" : self .org .service ,
235+ "owner_username" : self .org .username ,
236+ "user_username_or_ownerid" : another_user .ownerid ,
237+ },
238+ data = {"activated" : True },
239+ )
240+ assert response .status_code == status .HTTP_200_OK
241+ assert response .data == {
242+ "service" : "github" ,
243+ "username" : another_user .username ,
244+ "name" : another_user .name ,
245+ "activated" : True ,
246+ "is_admin" : False ,
247+ "email" : another_user .email ,
248+ }
249+
250+ # Deactivate user
251+ response = self ._patch (
252+ kwargs = {
253+ "service" : self .org .service ,
254+ "owner_username" : self .org .username ,
255+ "user_username_or_ownerid" : another_user .ownerid ,
256+ },
257+ data = {"activated" : False },
258+ )
259+ assert response .status_code == status .HTTP_200_OK
260+ assert response .data == {
261+ "service" : "github" ,
262+ "username" : another_user .username ,
263+ "name" : another_user .name ,
264+ "activated" : False ,
265+ "is_admin" : False ,
266+ "email" : another_user .email ,
267+ }
268+
269+ def test_update_activate_unauthorized_members_of_other_orgs (self ):
270+ another_org = OwnerFactory (service = "github" )
271+ another_user = OwnerFactory (service = "github" , organizations = [another_org .pk ])
272+
273+ # Activate user - not allowed
274+ response = self ._patch (
275+ kwargs = {
276+ "service" : self .org .service ,
277+ "owner_username" : self .org .username ,
278+ "user_username_or_ownerid" : another_user .username ,
279+ },
280+ data = {"activated" : True },
281+ )
282+ assert response .status_code == status .HTTP_404_NOT_FOUND
283+
284+ # Deactivate user - not allowed
285+ response = self ._patch (
286+ kwargs = {
287+ "service" : self .org .service ,
288+ "owner_username" : self .org .username ,
289+ "user_username_or_ownerid" : another_user .username ,
290+ },
291+ data = {"activated" : False },
292+ )
293+ assert response .status_code == status .HTTP_404_NOT_FOUND
294+
295+ # Request allowed after user joins the org
296+ another_user .organizations .append (self .org .pk )
297+ another_user .save ()
298+
299+ # Activate user
300+ response = self ._patch (
301+ kwargs = {
302+ "service" : self .org .service ,
303+ "owner_username" : self .org .username ,
304+ "user_username_or_ownerid" : another_user .username ,
305+ },
306+ data = {"activated" : True },
307+ )
308+ assert response .status_code == status .HTTP_200_OK
309+ assert response .data == {
310+ "service" : "github" ,
311+ "username" : another_user .username ,
312+ "name" : another_user .name ,
313+ "activated" : True ,
314+ "is_admin" : False ,
315+ "email" : another_user .email ,
316+ }
317+
318+ # Deactivate user
319+ response = self ._patch (
320+ kwargs = {
321+ "service" : self .org .service ,
322+ "owner_username" : self .org .username ,
323+ "user_username_or_ownerid" : another_user .username ,
324+ },
325+ data = {"activated" : False },
326+ )
327+ assert response .status_code == status .HTTP_200_OK
328+ assert response .data == {
329+ "service" : "github" ,
330+ "username" : another_user .username ,
331+ "name" : another_user .name ,
332+ "activated" : False ,
333+ "is_admin" : False ,
334+ "email" : another_user .email ,
335+ }
336+
337+ def test_update_activate_unauthorized_not_member_of_org (self ):
338+ another_org = OwnerFactory (service = "github" )
339+ another_user = OwnerFactory (service = "github" , organizations = [another_org .pk ])
340+
341+ # Activate user - not allowed
342+ response = self ._patch (
343+ kwargs = {
344+ "service" : another_org .service ,
345+ "owner_username" : another_org .username ,
346+ "user_username_or_ownerid" : another_user .username ,
347+ },
348+ data = {"activated" : True },
349+ )
350+ assert response .status_code == status .HTTP_404_NOT_FOUND
351+
352+ # Deactivate user - not allowed
353+ response = self ._patch (
354+ kwargs = {
355+ "service" : another_org .service ,
356+ "owner_username" : another_org .username ,
357+ "user_username_or_ownerid" : another_user .username ,
358+ },
359+ data = {"activated" : False },
360+ )
361+ assert response .status_code == status .HTTP_404_NOT_FOUND
362+
363+ # Request owner now joins the other org and thus is allowed to activate/deactivate
364+ self .current_owner .organizations .append (another_org .pk )
365+ self .current_owner .save ()
366+
367+ # Activate user
368+ response = self ._patch (
369+ kwargs = {
370+ "service" : another_org .service ,
371+ "owner_username" : another_org .username ,
372+ "user_username_or_ownerid" : another_user .username ,
373+ },
374+ data = {"activated" : True },
375+ )
376+ assert response .status_code == status .HTTP_200_OK
377+ assert response .data == {
378+ "service" : "github" ,
379+ "username" : another_user .username ,
380+ "name" : another_user .name ,
381+ "activated" : True ,
382+ "is_admin" : False ,
383+ "email" : another_user .email ,
384+ }
385+
386+ # Deactivate user
387+ response = self ._patch (
388+ kwargs = {
389+ "service" : another_org .service ,
390+ "owner_username" : another_org .username ,
391+ "user_username_or_ownerid" : another_user .username ,
392+ },
393+ data = {"activated" : False },
394+ )
395+ assert response .status_code == status .HTTP_200_OK
396+ assert response .data == {
397+ "service" : "github" ,
398+ "username" : another_user .username ,
399+ "name" : another_user .name ,
400+ "activated" : False ,
401+ "is_admin" : False ,
402+ "email" : another_user .email ,
403+ }
404+
405+ def test_update_activate_no_seats_left (self ):
406+ another_user = OwnerFactory (service = "github" , organizations = [self .org .pk ])
407+ another_user_2 = OwnerFactory (service = "github" , organizations = [self .org .pk ])
408+
409+ # Activate user 1
410+ response = self ._patch (
411+ kwargs = {
412+ "service" : self .org .service ,
413+ "owner_username" : self .org .username ,
414+ "user_username_or_ownerid" : another_user .username ,
415+ },
416+ data = {"activated" : True },
417+ )
418+ assert response .status_code == status .HTTP_200_OK
419+ assert response .data == {
420+ "service" : "github" ,
421+ "username" : another_user .username ,
422+ "name" : another_user .name ,
423+ "activated" : True ,
424+ "is_admin" : False ,
425+ "email" : another_user .email ,
426+ }
427+
428+ # Activate user 2
429+ response = self ._patch (
430+ kwargs = {
431+ "service" : self .org .service ,
432+ "owner_username" : self .org .username ,
433+ "user_username_or_ownerid" : another_user_2 .username ,
434+ },
435+ data = {"activated" : True },
436+ )
437+ assert response .status_code == status .HTTP_400_BAD_REQUEST
438+ assert response .data == {
439+ "detail" : ErrorDetail (
440+ string = "Cannot activate user -- not enough seats left." ,
441+ code = "no_seats_left" ,
442+ )
443+ }
444+
445+ # Deactivate user 1 to make room for user 2
446+ response = self ._patch (
447+ kwargs = {
448+ "service" : self .org .service ,
449+ "owner_username" : self .org .username ,
450+ "user_username_or_ownerid" : another_user .username ,
451+ },
452+ data = {"activated" : False },
453+ )
454+ assert response .status_code == status .HTTP_200_OK
455+ assert response .data == {
456+ "service" : "github" ,
457+ "username" : another_user .username ,
458+ "name" : another_user .name ,
459+ "activated" : False ,
460+ "is_admin" : False ,
461+ "email" : another_user .email ,
462+ }
463+
464+ # Activate user 2 now that there's room
465+ response = self ._patch (
466+ kwargs = {
467+ "service" : self .org .service ,
468+ "owner_username" : self .org .username ,
469+ "user_username_or_ownerid" : another_user_2 .username ,
470+ },
471+ data = {"activated" : True },
472+ )
473+ assert response .status_code == status .HTTP_200_OK
474+ assert response .data == {
475+ "service" : "github" ,
476+ "username" : another_user_2 .username ,
477+ "name" : another_user_2 .name ,
478+ "activated" : True ,
479+ "is_admin" : False ,
480+ "email" : another_user_2 .email ,
481+ }
482+
182483
183484class UserSessionViewSetTests (APITestCase ):
184485 def _list (self , kwargs ):
0 commit comments