11from django .forms .models import model_to_dict
22from core .tests .base import BaseTestCase
3+ from django .core .exceptions import ValidationError
34from django .core .management import call_command
4- from core .models import Service
5+ from core .models import Service , Program
56from rest_framework import status
67import random
78import json
89
10+
911def get_random_service ():
10- #gets random service from DB
12+ # gets random service from DB
1113 random_pk = random .randint (1 , 40 )
1214 return model_to_dict (Service .objects .get (pk = random_pk ))
1315
14- class ServicesTests (BaseTestCase ):
15- fixtures = ['services.yaml' , 'programs.yaml' ]
1616
17+ class ServicesTests (BaseTestCase ):
18+ fixtures = ["services.yaml" , "programs.yaml" ]
1719
1820 def test_get_services_list (self ):
1921 """
2022 Ensures that list of services is returned
2123 """
22- headers = self .auth_headers_for_user (' admin' )
23- response = self .client .get ( ' /api/services/' , follow = True , ** headers )
24+ headers = self .auth_headers_for_user (" admin" )
25+ response = self .client .get (" /api/services/" , follow = True , ** headers )
2426
2527 self .assertEqual (response .status_code , status .HTTP_200_OK )
2628 self .assertEqual (Service .objects .count (), 43 )
@@ -29,15 +31,21 @@ def test_update_availability(self):
2931 """
3032 Ensures the 'available' boolean can update
3133 """
32- headers = self .auth_headers_for_user (' admin' )
34+ headers = self .auth_headers_for_user (" admin" )
3335 random_service = get_random_service ()
3436
35- service_availability = random_service [' available' ]
36- random_service [' available' ] = not service_availability
37- route = ' /api/services/{}/' .format (random_service ['id' ])
37+ service_availability = random_service [" available" ]
38+ random_service [" available" ] = not service_availability
39+ route = " /api/services/{}/" .format (random_service ["id" ])
3840
39- response = self .client .put (route , json .dumps (random_service ), content_type = 'application/json' , follow = True , ** headers )
40- updated_availabilty = Service .objects .get (pk = random_service ['id' ]).available
41+ response = self .client .put (
42+ route ,
43+ json .dumps (random_service ),
44+ content_type = "application/json" ,
45+ follow = True ,
46+ ** headers
47+ )
48+ updated_availabilty = Service .objects .get (pk = random_service ["id" ]).available
4149
4250 self .assertNotEqual (service_availability , updated_availabilty )
4351 self .assertEqual (response .status_code , status .HTTP_200_OK )
@@ -46,13 +54,80 @@ def test_disallow_service_name_change(self):
4654 """
4755 Ensures that name field is read only
4856 """
49- headers = self .auth_headers_for_user (' admin' )
57+ headers = self .auth_headers_for_user (" admin" )
5058 random_service = get_random_service ()
51- service_name = random_service [' name' ]
52- random_service [' name' ] = ' Some nonexistent service'
53- route = ' /api/services/{}/' .format (random_service ['id' ])
59+ service_name = random_service [" name" ]
60+ random_service [" name" ] = " Some nonexistent service"
61+ route = " /api/services/{}/" .format (random_service ["id" ])
5462
55- self .client .put (route , json .dumps (random_service ), content_type = 'application/json' , follow = True , ** headers )
56- unchanged_name = Service .objects .get (pk = random_service ['id' ]).name
57- #returns a 200 status, but field is unchanged
63+ self .client .put (
64+ route ,
65+ json .dumps (random_service ),
66+ content_type = "application/json" ,
67+ follow = True ,
68+ ** headers
69+ )
70+ unchanged_name = Service .objects .get (pk = random_service ["id" ]).name
71+ # returns a 200 status, but field is unchanged
5872 self .assertEqual (service_name , unchanged_name )
73+
74+ def test_service_has_slug_field (self ):
75+ """
76+ Ensure Service has slug field
77+ """
78+ headers = self .auth_headers_for_user ("admin" )
79+ random_service = get_random_service ()
80+ route = "/api/services/{}/" .format (random_service ["id" ])
81+ res = self .client .get (route , follow = True , ** headers )
82+ content = json .loads (res .content )
83+ self .assertTrue ("slug" in content )
84+ self .assertTrue (content ["slug" ], random_service ["slug" ])
85+
86+ def test_disallow_slug_change (self ):
87+ """
88+ Ensure slug field read only
89+ """
90+ headers = self .auth_headers_for_user ("admin" )
91+ random_service = get_random_service ()
92+ service_slug = random_service ["slug" ]
93+ random_service ["name" ] = "a fake slug"
94+ route = "/api/services/{}/" .format (random_service ["id" ])
95+
96+ self .client .put (
97+ route ,
98+ json .dumps (random_service ),
99+ content_type = "application/json" ,
100+ follow = True ,
101+ ** headers
102+ )
103+ unchanged_slug = Service .objects .get (pk = random_service ["id" ]).name
104+ # returns a 200 status, but field is unchanged
105+ self .assertEqual (service_slug , unchanged_slug )
106+
107+ def test_slug_uniqueness (self ):
108+ """
109+ Ensure slug field is unique.
110+ Note: since serializer removes name and slug
111+ bc read_only=true for all request types at the moment,
112+ we're testing the model directly
113+ """
114+
115+ slug = "banana"
116+
117+ program = Program .objects .all ().first ()
118+ Service .objects .create (name = "some name" , slug = slug , program = program )
119+ count_before_error = Service .objects .count ()
120+ with self .assertRaises (Exception ) as context :
121+ Service .objects .create (name = "another name" , slug = slug , program = program )
122+
123+ self .assertEqual (Service .objects .count (), count_before_error )
124+
125+ def test_slug_normalization (self ):
126+ """
127+ Ensure slug gets normalized when created
128+ """
129+
130+ slug = " $%^$# 543 Sligh Bannaga *&^%*& "
131+ program = Program .objects .all ().first ()
132+ service = Service .objects .create (name = "some name" , slug = slug , program = program )
133+ self .assertRegex (service .slug , r"[a-z0-9\-]" )
0 commit comments