1
1
from copy import deepcopy
2
2
from datetime import timedelta
3
3
4
+ from django .conf import settings
4
5
from django .core .exceptions import ValidationError
5
6
from django .core .files .uploadedfile import SimpleUploadedFile
6
- from django .conf import settings
7
7
8
8
from appointment .models import Service
9
9
from appointment .tests .base .base_test import BaseTest
10
10
11
11
12
- class ServiceModelGettersTestCase (BaseTest ):
12
+ class ServiceCreationAndBasicAttributesTests (BaseTest ):
13
13
@classmethod
14
14
def setUpTestData (cls ):
15
15
super ().setUpTestData ()
16
16
cls .service = cls .service1
17
17
18
- def test_service_is_created (self ):
18
+ @classmethod
19
+ def tearDownClass (cls ):
20
+ super ().tearDownClass ()
21
+
22
+ def test_service_creation (self ):
19
23
self .assertIsNotNone (self .service )
20
24
21
- def test_is_a_paid_service (self ):
25
+ def test_basic_attributes_verification (self ):
26
+ self .assertEqual (self .service .name , "Stargate Activation" )
27
+ self .assertEqual (self .service .description , "Activate the Stargate" )
28
+ self .assertEqual (self .service .duration , self .service1 .duration )
29
+
30
+ def test_timestamps_on_creation (self ):
31
+ """Newly created services should have created_at and updated_at values."""
32
+ self .assertIsNotNone (self .service .created_at )
33
+ self .assertIsNotNone (self .service .updated_at )
34
+
35
+
36
+ class ServicePriceTests (BaseTest ):
37
+ @classmethod
38
+ def setUpTestData (cls ):
39
+ super ().setUpTestData ()
40
+ cls .service = cls .service1
41
+
42
+ @classmethod
43
+ def tearDownClass (cls ):
44
+ super ().tearDownClass ()
45
+
46
+ def test_service_price_verification (self ):
47
+ self .assertEqual (self .service .price , 100000 )
48
+ self .assertEqual (self .service .get_price (), 100000 )
49
+
50
+ def test_paid_service_verification (self ):
22
51
self .assertTrue (self .service .is_a_paid_service ())
23
52
24
- def test_service_name (self ):
25
- self .assertEqual (self .service .name , "Stargate Activation" )
53
+ def check_price (self , price , expected_string ):
54
+ service = deepcopy (self .service )
55
+ service .price = price
56
+ self .assertEqual (service .get_price_text (), expected_string )
26
57
27
- def test_service_description (self ):
28
- self .assertEqual (self .service .description , "Activate the Stargate" )
58
+ def test_dynamic_price_representation (self ):
59
+ """Test that the get_price method returns the correct string for a service with a price of 100, 1000, etc."""
60
+ test_cases = [
61
+ (100 , '100$' ),
62
+ (100.50 , '100.5$' ),
63
+ (49.99 , '49.99$' ),
64
+ (0 , 'Free' )
65
+ ]
66
+ for price , expected in test_cases :
67
+ self .check_price (price , expected )
68
+
69
+
70
+ class ServiceDurationTests (BaseTest ):
71
+ @classmethod
72
+ def setUpTestData (cls ):
73
+ super ().setUpTestData ()
74
+ cls .service = cls .service1
29
75
30
- def test_service_duration (self ):
76
+ @classmethod
77
+ def tearDownClass (cls ):
78
+ super ().tearDownClass ()
79
+
80
+ def test_service_duration_verification (self ):
31
81
"""Test the duration of the service."""
32
82
self .assertEqual (self .service .duration , self .service1 .duration )
33
83
@@ -36,7 +86,7 @@ def check_duration(self, duration, expected_string):
36
86
service .duration = duration
37
87
self .assertEqual (service .get_duration (), expected_string )
38
88
39
- def test_various_durations_for_get_duration (self ):
89
+ def test_dynamic_duration_representation (self ):
40
90
"""Test that the get_duration method returns the correct string for a service with a duration of 30 seconds,
41
91
30 minutes, etc."""
42
92
test_cases = [
@@ -49,25 +99,16 @@ def test_various_durations_for_get_duration(self):
49
99
for duration , expected in test_cases :
50
100
self .check_duration (duration , expected )
51
101
52
- def test_service_price (self ):
53
- self .assertEqual (self .service .price , 100000 )
54
- self .assertEqual (self .service .get_price (), 100000 )
55
102
56
- def check_price (self , price , expected_string ):
57
- service = deepcopy (self .service )
58
- service .price = price
59
- self .assertEqual (service .get_price_text (), expected_string )
103
+ class ServiceDownPaymentTests (BaseTest ):
104
+ @classmethod
105
+ def setUpTestData (cls ):
106
+ super ().setUpTestData ()
107
+ cls .service = cls .service1
60
108
61
- def test_various_prices_for_get_price (self ):
62
- """Test that the get_price method returns the correct string for a service with a price of 100, 1000, etc."""
63
- test_cases = [
64
- (100 , '100$' ),
65
- (100.50 , '100.5$' ),
66
- (49.99 , '49.99$' ),
67
- (0 , 'Free' )
68
- ]
69
- for price , expected in test_cases :
70
- self .check_price (price , expected )
109
+ @classmethod
110
+ def tearDownClass (cls ):
111
+ super ().tearDownClass ()
71
112
72
113
def test_down_payment_value (self ):
73
114
"""By default, down payment value is 0"""
@@ -83,14 +124,6 @@ def test_down_payment_value(self):
83
124
84
125
self .assertEqual (s .get_down_payment_text (), "69.99$" )
85
126
86
- def test_price_and_down_payment_same (self ):
87
- """A service can be created with a price and down payment of the same value.
88
- This is useful when the service requires full payment upfront.
89
- """
90
- service = Service .objects .create (
91
- name = "Naquadah Generator Maintenance" , duration = timedelta (hours = 1 ), price = 100 , down_payment = 100 )
92
- self .assertEqual (service .price , service .down_payment )
93
-
94
127
def test_accepts_down_payment (self ):
95
128
"""By default, down payment is not accepted."""
96
129
self .assertFalse (self .service .accepts_down_payment ())
@@ -100,27 +133,32 @@ def test_accepts_down_payment(self):
100
133
s .down_payment = 69.99
101
134
self .assertTrue (s .accepts_down_payment ())
102
135
103
- def test_default_currency (self ):
104
- """The Default currency is USD."""
105
- self .assertEqual (self .service .currency , 'USD' )
136
+ def test_equal_price_and_down_payment_scenario (self ):
137
+ """A service can be created with a price and down payment of the same value.
138
+ This is useful when the service requires full payment upfront.
139
+ """
140
+ service = Service .objects .create (
141
+ name = "Naquadah Generator Maintenance" , duration = timedelta (hours = 1 ), price = 100 , down_payment = 100 )
142
+ self .assertEqual (service .price , service .down_payment )
106
143
107
- # Change the currency to EUR
108
- s = deepcopy (self .service )
109
- s .currency = 'EUR'
110
- self .assertEqual (s .currency , 'EUR' )
111
144
112
- def test_default_created_and_updated_at_not_none (self ):
113
- """Newly created services should have created_at and updated_at values."""
114
- self .assertIsNotNone (self .service .created_at )
115
- self .assertIsNotNone (self .service .updated_at )
145
+ class ServiceRepresentationAndMiscTests (BaseTest ):
146
+ @classmethod
147
+ def setUpTestData (cls ):
148
+ super ().setUpTestData ()
149
+ cls .service = cls .service1
150
+
151
+ @classmethod
152
+ def tearDownClass (cls ):
153
+ super ().tearDownClass ()
116
154
117
- def test_str_method (self ):
155
+ def test_string_representation_of_service (self ):
118
156
"""Test the string representation of the Service model."""
119
157
service_name = "Test Service"
120
158
service = Service .objects .create (name = service_name , duration = timedelta (hours = 1 ), price = 100 )
121
159
self .assertEqual (str (service ), service_name )
122
160
123
- def test_get_service_image_url_with_image (self ):
161
+ def test_image_url_with_attached_image (self ):
124
162
"""Service should return the correct URL for the image if provided."""
125
163
# Create an image and attach it to the service
126
164
image_path = settings .BASE_DIR / 'appointment/static/img/texture.webp' # Adjust the path as necessary
@@ -132,25 +170,18 @@ def test_get_service_image_url_with_image(self):
132
170
expected_url = f"{ settings .MEDIA_URL } { service .image } "
133
171
self .assertTrue (service .get_image_url ().endswith (expected_url ))
134
172
135
- def test_get_service_image_url_no_image (self ):
173
+ def test_image_url_without_attached_image (self ):
136
174
"""Service should handle cases where no image is provided gracefully."""
137
175
service = Service .objects .create (name = "Gate Travel Coordination" , duration = timedelta (hours = 1 ), price = 50 )
138
176
self .assertEqual (service .get_image_url (), "" )
139
177
140
- def test_service_auto_generate_background_color (self ):
178
+ def test_auto_generation_of_background_color (self ):
141
179
"""Service should auto-generate a background color if none is provided."""
142
180
service = Service .objects .create (name = "Wormhole Stability Analysis" , duration = timedelta (hours = 1 ), price = 50 )
143
181
self .assertIsNotNone (service .background_color )
144
182
self .assertNotEqual (service .background_color , "" )
145
183
146
- def test_reschedule_limit_and_allowance (self ):
147
- """Service should correctly handle reschedule limits and rescheduling allowance."""
148
- service = Service .objects .create (name = "Goa'uld Artifact Decryption" , duration = timedelta (hours = 1 ), price = 50 ,
149
- reschedule_limit = 3 , allow_rescheduling = True )
150
- self .assertEqual (service .reschedule_limit , 3 )
151
- self .assertTrue (service .allow_rescheduling )
152
-
153
- def test_to_dict_method (self ):
184
+ def test_service_to_dict_representation (self ):
154
185
"""Test the to_dict method returns the correct dictionary representation of the Service instance."""
155
186
service = Service .objects .create (name = "Off-world Tactical Training" , duration = timedelta (hours = 1 ), price = 150 ,
156
187
description = "Train for off-world missions" )
@@ -162,22 +193,42 @@ def test_to_dict_method(self):
162
193
}
163
194
self .assertEqual (service .to_dict (), expected_dict )
164
195
196
+ def test_reschedule_features (self ):
197
+ """Service should correctly handle reschedule limits and rescheduling allowance."""
198
+ service = Service .objects .create (name = "Goa'uld Artifact Decryption" , duration = timedelta (hours = 1 ), price = 50 ,
199
+ reschedule_limit = 3 , allow_rescheduling = True )
200
+ self .assertEqual (service .reschedule_limit , 3 )
201
+ self .assertTrue (service .allow_rescheduling )
202
+
203
+ def test_default_currency_setting (self ):
204
+ """The Default currency is USD."""
205
+ self .assertEqual (self .service .currency , 'USD' )
206
+
207
+ # Change the currency to EUR
208
+ s = deepcopy (self .service )
209
+ s .currency = 'EUR'
210
+ self .assertEqual (s .currency , 'EUR' )
211
+
165
212
166
213
class ServiceModelNegativeTestCase (BaseTest ):
167
214
@classmethod
168
215
def setUpTestData (cls ):
169
216
super ().setUpTestData ()
170
217
cls .service = cls .service1
171
218
172
- def test_invalid_service_name (self ):
219
+ @classmethod
220
+ def tearDownClass (cls ):
221
+ super ().tearDownClass ()
222
+
223
+ def test_exceeding_service_name_length (self ):
173
224
"""Test that the max_length of the name field is 100 characters."""
174
225
s = deepcopy (self .service )
175
226
s .name = ("Gate Diagnostics and Calibration for Intergalactic Travel through the Quantum Bridge Device "
176
227
"Portal - Series SG-1" ) # Exceeding the max_length (112 characters)
177
228
with self .assertRaises (ValidationError ):
178
229
s .full_clean ()
179
230
180
- def test_invalid_price_and_down_payment (self ):
231
+ def test_negative_price_and_down_payment_values (self ):
181
232
"""Test that the price and down_payment fields cannot be negative."""
182
233
s = deepcopy (self .service )
183
234
s .price = - 100
@@ -189,7 +240,7 @@ def test_invalid_price_and_down_payment(self):
189
240
with self .assertRaises (ValidationError ):
190
241
s .full_clean ()
191
242
192
- def test_invalid_service_currency_length (self ):
243
+ def test_invalid_currency_code_length (self ):
193
244
"""A service cannot be created with a currency of less or more than three characters."""
194
245
s = deepcopy (self .service )
195
246
s .currency = "US"
@@ -201,15 +252,15 @@ def test_invalid_service_currency_length(self):
201
252
with self .assertRaises (ValidationError ):
202
253
s .full_clean ()
203
254
204
- def test_service_invalid_duration (self ):
255
+ def test_zero_or_negative_duration_handling (self ):
205
256
"""A service cannot be created with a duration being zero or negative."""
206
257
service = Service (name = "Zat'nik'tel Tune-Up" , duration = timedelta (0 ), price = 100 , description = "Tune-up the Zat" )
207
258
self .assertRaises (ValidationError , service .full_clean )
208
259
service = Service (name = "Ancient's Archive Retrieval " , duration = timedelta (seconds = - 1 ), price = 50 ,
209
260
description = "Retrieve the Ancient's Archive" )
210
261
self .assertRaises (ValidationError , service .full_clean )
211
262
212
- def test_service_with_no_name (self ):
263
+ def test_creation_without_service_name (self ):
213
264
"""A service cannot be created with no name."""
214
265
with self .assertRaises (ValidationError ):
215
266
Service .objects .create (name = "" , duration = timedelta (hours = 1 ), price = 100 ).full_clean ()
0 commit comments