Coverage for website/sales/tests/test_api.py: 100.00%
332 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1from unittest import mock
3from django.contrib.auth.models import Permission
4from django.contrib.contenttypes.models import ContentType
5from django.test import TestCase
6from django.urls import reverse
7from django.utils import timezone
9from freezegun import freeze_time
10from rest_framework.test import APIClient
12from activemembers.models import Committee, MemberGroupMembership
13from members.models import Member
14from payments.models import Payment
15from payments.services import create_payment
16from sales import payables
17from sales.models.order import Order, OrderItem
18from sales.models.product import Product, ProductList
19from sales.models.shift import SelfOrderPeriod, Shift
22@freeze_time("2021-01-01")
23class OrderAPITest(TestCase):
24 fixtures = [
25 "members.json",
26 "bank_accounts.json",
27 "member_groups.json",
28 "products.json",
29 ]
31 @classmethod
32 def setUpTestData(cls):
33 """Create the following test data:
35 o0: an empty order
36 o1: an unpaid order of 2 beer
37 o2: an order of 2 soda that doesn't need a payment
38 o3: an unpaid order with 2 beer and 2 wine
39 o4: a paid order with 2 wine
40 o4: a paid order with 2 beer and 2 wine
41 """
42 payables.register()
44 cls.member = Member.objects.filter(last_name="Wiggers").first()
46 cls.beer = Product.objects.get(name="beer")
47 cls.wine = Product.objects.get(name="wine")
48 cls.soda = Product.objects.get(name="soda")
50 cls.normal = ProductList.objects.get(
51 name="normal",
52 )
53 cls.free = ProductList.objects.get(
54 name="free",
55 )
57 cls.shift = Shift.objects.create(
58 start=timezone.now(),
59 end=timezone.now() + timezone.timedelta(hours=1),
60 product_list=cls.normal,
61 )
63 cls.o0 = Order.objects.create(shift=cls.shift)
64 cls.o1 = Order.objects.create(shift=cls.shift)
65 OrderItem.objects.create(
66 order=cls.o1,
67 product=cls.shift.product_list.product_items.get(product=cls.beer),
68 amount=2,
69 )
70 cls.o2 = Order.objects.create(shift=cls.shift)
71 OrderItem.objects.create(
72 order=cls.o2,
73 product=cls.shift.product_list.product_items.get(product=cls.soda),
74 amount=2,
75 )
76 cls.o3 = Order.objects.create(shift=cls.shift)
77 OrderItem.objects.create(
78 order=cls.o3,
79 product=cls.shift.product_list.product_items.get(product=cls.beer),
80 amount=2,
81 )
82 OrderItem.objects.create(
83 order=cls.o3,
84 product=cls.shift.product_list.product_items.get(product=cls.wine),
85 amount=2,
86 )
87 cls.o4 = Order.objects.create(shift=cls.shift)
88 OrderItem.objects.create(
89 order=cls.o4,
90 product=cls.shift.product_list.product_items.get(product=cls.wine),
91 amount=2,
92 )
93 cls.o5 = Order.objects.create(shift=cls.shift)
94 OrderItem.objects.create(
95 order=cls.o5,
96 product=cls.shift.product_list.product_items.get(product=cls.beer),
97 amount=2,
98 )
99 OrderItem.objects.create(
100 order=cls.o5,
101 product=cls.shift.product_list.product_items.get(product=cls.wine),
102 amount=2,
103 )
104 cls.o4.payment = create_payment(
105 cls.o4, processed_by=cls.member, pay_type=Payment.CASH
106 )
107 cls.o4.save()
108 cls.o5.payment = create_payment(
109 cls.o5, processed_by=cls.member, pay_type=Payment.CASH
110 )
111 cls.o5.save()
113 cls.cie = Committee.objects.get(pk=1)
114 MemberGroupMembership.objects.create(group=cls.cie, member=cls.member)
115 content_type = ContentType.objects.get_for_model(Order)
116 permission1 = Permission.objects.get(
117 content_type=content_type, codename="add_order"
118 )
119 permission2 = Permission.objects.get(
120 content_type=content_type, codename="change_order"
121 )
122 permission3 = Permission.objects.get(
123 content_type=content_type, codename="delete_order"
124 )
125 permission4 = Permission.objects.get(
126 content_type=content_type, codename="view_order"
127 )
128 permission5 = Permission.objects.get(
129 content_type=ContentType.objects.get_for_model(Shift), codename="view_shift"
130 )
131 cls.cie.permissions.add(permission1)
132 cls.cie.permissions.add(permission2)
133 cls.cie.permissions.add(permission3)
134 cls.cie.permissions.add(permission4)
135 cls.cie.permissions.add(permission5)
137 def setUp(self):
138 self.client = APIClient()
139 self.client.force_login(self.member)
141 def test_detail_not_logged_in(self):
142 self.client.logout()
143 response = self.client.get(
144 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o0.pk})
145 )
146 self.assertEqual(403, response.status_code)
148 def test_detail_not_authorized__get(self):
149 response = self.client.get(
150 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk})
151 )
152 self.assertEqual(200, response.status_code)
154 self.member.is_superuser = False
155 self.member.save()
157 response = self.client.get(
158 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk})
159 )
160 self.assertEqual(404, response.status_code)
162 self.shift.managers.add(self.cie)
163 self.shift.save()
165 response = self.client.get(
166 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk})
167 )
168 self.assertEqual(200, response.status_code)
170 def test_detail_not_authorized__patch(self):
171 data = {"discount": "0.5"}
173 response = self.client.patch(
174 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
175 )
176 self.assertEqual(200, response.status_code)
178 self.member.is_superuser = False
179 self.member.save()
181 response = self.client.patch(
182 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
183 )
184 self.assertEqual(404, response.status_code)
186 self.shift.managers.add(self.cie)
187 self.shift.save()
189 response = self.client.patch(
190 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
191 )
192 self.assertEqual(200, response.status_code)
194 def test_detail_not_authorized__put(self):
195 data = {"discount": "0.5"}
197 response = self.client.put(
198 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
199 )
200 self.assertEqual(200, response.status_code)
202 self.member.is_superuser = False
203 self.member.save()
205 response = self.client.put(
206 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
207 )
208 self.assertEqual(404, response.status_code)
210 self.shift.managers.add(self.cie)
211 self.shift.save()
213 response = self.client.put(
214 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk}), data
215 )
216 self.assertEqual(200, response.status_code)
218 def test_detail_not_authorized__delete(self):
219 response = self.client.delete(
220 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o1.pk})
221 )
222 self.assertEqual(204, response.status_code)
224 self.member.is_superuser = False
225 self.member.save()
227 response = self.client.delete(
228 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o2.pk})
229 )
230 self.assertEqual(404, response.status_code)
232 self.shift.managers.add(self.cie)
233 self.shift.save()
235 response3 = self.client.delete(
236 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": self.o2.pk})
237 )
238 self.assertEqual(204, response3.status_code)
240 def test_list_not_logged_in(self):
241 self.client.logout()
242 response = self.client.get(
243 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk})
244 )
245 self.assertEqual(403, response.status_code)
247 def test_list_not_authorized__get(self):
248 response = self.client.get(
249 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk})
250 )
251 self.assertEqual(200, response.status_code)
253 self.member.is_superuser = False
254 self.member.save()
256 response = self.client.get(
257 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk})
258 )
259 self.assertEqual(403, response.status_code)
261 self.shift.managers.add(self.cie)
262 self.shift.save()
264 response = self.client.get(
265 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk})
266 )
267 self.assertEqual(200, response.status_code)
269 def test_list_not_authorized__post(self):
270 data = {"order_items": [{"product": "beer", "amount": 4}]}
272 response = self.client.post(
273 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk}),
274 data,
275 )
276 self.assertEqual(201, response.status_code)
278 self.member.is_superuser = False
279 self.member.save()
281 response = self.client.post(
282 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk}),
283 data,
284 )
285 self.assertEqual(403, response.status_code)
287 self.shift.managers.add(self.cie)
288 self.shift.save()
290 response = self.client.post(
291 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk}),
292 data,
293 )
294 self.assertEqual(201, response.status_code)
296 def test_create_order(self):
297 self.maxDiff = None
298 with self.subTest("Create new order with single item"):
299 data = {"order_items": [{"product": "beer", "amount": 4}]}
300 response = self.client.post(
301 reverse(
302 "api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk}
303 ),
304 data,
305 format="json",
306 )
307 self.assertEqual(201, response.status_code)
308 pk = response.data["pk"]
309 expected_response = {
310 "pk": pk,
311 "shift": self.shift.pk,
312 "created_at": "2021-01-01T01:00:00+01:00",
313 "order_items": [{"product": "beer", "amount": 4, "total": "2.00"}],
314 "order_description": "4x beer",
315 "age_restricted": True,
316 "subtotal": "2.00",
317 "discount": None,
318 "total_amount": "2.00",
319 "num_items": 4,
320 "payment": None,
321 "payer": None,
322 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
323 }
324 self.assertJSONEqual(response.content, expected_response)
326 with self.subTest("Add product item"):
327 data = {
328 "order_items": [
329 {"product": "beer", "amount": 5},
330 {"product": "soda", "amount": 2},
331 ]
332 }
333 response = self.client.put(
334 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
335 data,
336 format="json",
337 )
338 self.assertEqual(200, response.status_code)
339 expected_response = {
340 "pk": pk,
341 "shift": self.shift.pk,
342 "created_at": "2021-01-01T01:00:00+01:00",
343 "order_items": [
344 {"product": "beer", "amount": 5, "total": "2.50"},
345 {"product": "soda", "amount": 2, "total": "0.00"},
346 ],
347 "order_description": "5x beer, 2x soda",
348 "age_restricted": True,
349 "subtotal": "2.50",
350 "discount": None,
351 "total_amount": "2.50",
352 "num_items": 7,
353 "payment": None,
354 "payer": None,
355 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
356 }
357 self.assertJSONEqual(response.content, expected_response)
359 with self.subTest("Delete and add product item"):
360 data = {
361 "order_items": [
362 {"product": "wine", "amount": 1},
363 {"product": "soda", "amount": 2},
364 ]
365 }
366 response = self.client.put(
367 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
368 data,
369 format="json",
370 )
371 self.assertEqual(200, response.status_code)
372 expected_response = {
373 "pk": pk,
374 "shift": self.shift.pk,
375 "created_at": "2021-01-01T01:00:00+01:00",
376 "order_items": [
377 {"product": "wine", "amount": 1, "total": "0.50"},
378 {"product": "soda", "amount": 2, "total": "0.00"},
379 ],
380 "order_description": "1x wine, 2x soda",
381 "age_restricted": True,
382 "subtotal": "0.50",
383 "discount": None,
384 "total_amount": "0.50",
385 "num_items": 3,
386 "payment": None,
387 "payer": None,
388 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
389 }
390 self.assertJSONEqual(response.content, expected_response)
392 with self.subTest("Write discount"):
393 data = {"discount": 0.2}
394 response = self.client.patch(
395 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
396 data,
397 format="json",
398 )
399 self.assertEqual(200, response.status_code)
400 expected_response = {
401 "pk": pk,
402 "shift": self.shift.pk,
403 "created_at": "2021-01-01T01:00:00+01:00",
404 "order_items": [
405 {"product": "wine", "amount": 1, "total": "0.50"},
406 {"product": "soda", "amount": 2, "total": "0.00"},
407 ],
408 "order_description": "1x wine, 2x soda",
409 "age_restricted": True,
410 "subtotal": "0.50",
411 "discount": "0.20",
412 "total_amount": "0.30",
413 "num_items": 3,
414 "payment": None,
415 "payer": None,
416 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
417 }
418 self.assertJSONEqual(response.content, expected_response)
420 with self.subTest("Reset discount"):
421 data = {"discount": 0}
422 response = self.client.patch(
423 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
424 data,
425 format="json",
426 )
427 self.assertEqual(200, response.status_code)
428 expected_response = {
429 "pk": pk,
430 "shift": self.shift.pk,
431 "created_at": "2021-01-01T01:00:00+01:00",
432 "order_items": [
433 {"product": "wine", "amount": 1, "total": "0.50"},
434 {"product": "soda", "amount": 2, "total": "0.00"},
435 ],
436 "order_description": "1x wine, 2x soda",
437 "age_restricted": True,
438 "subtotal": "0.50",
439 "discount": "0.00",
440 "total_amount": "0.50",
441 "num_items": 3,
442 "payment": None,
443 "payer": None,
444 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
445 }
446 self.assertJSONEqual(response.content, expected_response)
448 with self.subTest("Override total field"):
449 data = {
450 "order_items": [
451 {"product": "wine", "amount": 1, "total": "1.30"},
452 {"product": "soda", "amount": 2, "total": "2.00"},
453 ]
454 }
455 response = self.client.patch(
456 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
457 data,
458 format="json",
459 )
460 self.assertEqual(200, response.status_code)
461 expected_response = {
462 "pk": pk,
463 "shift": self.shift.pk,
464 "created_at": "2021-01-01T01:00:00+01:00",
465 "order_items": [
466 {"product": "wine", "amount": 1, "total": "1.30"},
467 {"product": "soda", "amount": 2, "total": "2.00"},
468 ],
469 "order_description": "1x wine, 2x soda",
470 "age_restricted": True,
471 "subtotal": "3.30",
472 "discount": "0.00",
473 "total_amount": "3.30",
474 "num_items": 3,
475 "payment": None,
476 "payer": None,
477 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
478 }
479 self.assertJSONEqual(response.content, expected_response)
481 with self.subTest("Reset overridden total fields"):
482 data = {
483 "order_items": [
484 {"product": "wine", "amount": 1},
485 {"product": "soda", "amount": 2},
486 ]
487 }
488 response = self.client.patch(
489 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
490 data,
491 format="json",
492 )
493 self.assertEqual(200, response.status_code)
494 expected_response = {
495 "pk": pk,
496 "shift": self.shift.pk,
497 "created_at": "2021-01-01T01:00:00+01:00",
498 "order_items": [
499 {"product": "wine", "amount": 1, "total": "0.50"},
500 {"product": "soda", "amount": 2, "total": "0.00"},
501 ],
502 "order_description": "1x wine, 2x soda",
503 "age_restricted": True,
504 "subtotal": "0.50",
505 "discount": "0.00",
506 "total_amount": "0.50",
507 "num_items": 3,
508 "payment": None,
509 "payer": None,
510 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
511 }
512 self.assertJSONEqual(response.content, expected_response)
514 with self.subTest("Write discount without custom price permissions"):
515 self.member.is_superuser = False
516 self.member.save()
517 self.shift.managers.add(self.cie)
518 self.shift.save()
520 data = {"discount": 0.2}
521 response = self.client.patch(
522 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
523 data,
524 format="json",
525 )
526 self.assertEqual(200, response.status_code)
527 expected_response = {
528 "pk": pk,
529 "shift": self.shift.pk,
530 "created_at": "2021-01-01T01:00:00+01:00",
531 "order_items": [
532 {"product": "wine", "amount": 1, "total": "0.50"},
533 {"product": "soda", "amount": 2, "total": "0.00"},
534 ],
535 "order_description": "1x wine, 2x soda",
536 "age_restricted": True,
537 "subtotal": "0.50",
538 "discount": "0.00",
539 "total_amount": "0.50",
540 "num_items": 3,
541 "payment": None,
542 "payer": None,
543 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
544 }
545 self.assertJSONEqual(response.content, expected_response)
547 with self.subTest("Write total field without custom price permissions"):
548 data = {
549 "order_items": [
550 {"product": "wine", "amount": 1, "total": "1.30"},
551 {"product": "soda", "amount": 2, "total": "2.00"},
552 ]
553 }
554 response = self.client.patch(
555 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
556 data,
557 format="json",
558 )
559 self.assertEqual(200, response.status_code)
560 expected_response = {
561 "pk": pk,
562 "shift": self.shift.pk,
563 "created_at": "2021-01-01T01:00:00+01:00",
564 "order_items": [
565 {"product": "wine", "amount": 1, "total": "0.50"},
566 {"product": "soda", "amount": 2, "total": "0.00"},
567 ],
568 "order_description": "1x wine, 2x soda",
569 "age_restricted": True,
570 "subtotal": "0.50",
571 "discount": "0.00",
572 "total_amount": "0.50",
573 "num_items": 3,
574 "payment": None,
575 "payer": None,
576 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
577 }
578 self.assertJSONEqual(response.content, expected_response)
580 with self.subTest("Delete one product item"):
581 data = {
582 "order_items": [
583 {"product": "wine", "amount": 1},
584 ]
585 }
586 response = self.client.patch(
587 reverse("api:v2:admin:sales:order-detail", kwargs={"pk": pk}),
588 data,
589 format="json",
590 )
591 self.assertEqual(200, response.status_code)
592 expected_response = {
593 "pk": pk,
594 "shift": self.shift.pk,
595 "created_at": "2021-01-01T01:00:00+01:00",
596 "order_items": [
597 {"product": "wine", "amount": 1, "total": "0.50"},
598 ],
599 "order_description": "1x wine",
600 "age_restricted": True,
601 "subtotal": "0.50",
602 "discount": "0.00",
603 "total_amount": "0.50",
604 "num_items": 1,
605 "payment": None,
606 "payer": None,
607 "payment_url": f"http://localhost:8000/sales/order/{pk}/pay/",
608 }
609 self.assertJSONEqual(response.content, expected_response)
611 def test_invalid_product(self):
612 data = {"order_items": [{"product": "invalidproduct", "amount": 4}]}
613 response = self.client.post(
614 reverse("api:v2:admin:sales:shift-orders", kwargs={"pk": self.shift.pk}),
615 data,
616 format="json",
617 )
618 self.assertEqual(400, response.status_code)
620 def test_user_self_order(self):
621 SelfOrderPeriod.objects.create(
622 shift=self.shift,
623 start=(timezone.now() - timezone.timedelta(hours=1)),
624 end=timezone.now() + timezone.timedelta(hours=1),
625 )
626 data = {"order_items": [{"product": "beer", "amount": 4}]}
627 response = self.client.post(
628 reverse("api:v2:sales:user-order-list", kwargs={"pk": self.shift.pk}),
629 data,
630 format="json",
631 )
632 self.assertEqual(201, response.status_code)
633 order = Order.objects.get(pk=response.data["pk"])
634 self.assertEqual(order.payer, self.member)
636 def test_claim_order(self):
637 with self.subTest("Claim a normal order"):
638 response = self.client.patch(
639 reverse("api:v2:sales:order-claim", kwargs={"pk": self.o3.pk})
640 )
641 self.assertEqual(200, response.status_code)
642 self.assertEqual(
643 Order.objects.get(pk=response.data["pk"]).payer, self.member
644 )
646 self.o3.payer = None
647 self.o3.save()
649 with self.subTest("Claim an order that is already yours"):
650 self.o3.payer = self.member
651 self.o3.save()
653 response = self.client.patch(
654 reverse("api:v2:sales:order-claim", kwargs={"pk": self.o3.pk})
655 )
656 self.assertEqual(200, response.status_code)
657 self.assertEqual(
658 Order.objects.get(pk=response.data["pk"]).payer, self.member
659 )
661 self.o3.payer = None
662 self.o3.save()
664 with self.subTest("Claim an order that is not yours"):
665 member = Member.objects.create(
666 username="test1",
667 first_name="Test1",
668 last_name="Example",
669 email="test1@example.org",
670 is_staff=False,
671 is_superuser=False,
672 )
673 self.o3.payer = member
674 self.o3.save()
676 response = self.client.patch(
677 reverse("api:v2:sales:order-claim", kwargs={"pk": self.o3.pk})
678 )
679 self.assertEqual(403, response.status_code)
680 self.o3.refresh_from_db()
681 self.assertEqual(self.o3.payer, member)
683 self.o3.payer = None
684 self.o3.save()
686 with self.subTest("Claim a paid order"):
687 response = self.client.patch(
688 reverse("api:v2:sales:order-claim", kwargs={"pk": self.o4.pk})
689 )
690 self.assertEqual(403, response.status_code)
692 self.o3.payer = None
693 self.o3.save()
695 with self.subTest("Claim an age-restricted order as a minor"):
696 with mock.patch("sales.services.is_adult") as is_adult:
697 is_adult.return_value = False
698 response = self.client.patch(
699 reverse("api:v2:sales:order-claim", kwargs={"pk": self.o3.pk})
700 )
701 self.assertEqual(403, response.status_code)
702 self.o3.refresh_from_db()
703 self.assertEqual(self.o3.payer, self.member)
706class ShiftAPITest(TestCase):
707 fixtures = [
708 "members.json",
709 "bank_accounts.json",
710 "member_groups.json",
711 "products.json",
712 ]
714 @classmethod
715 def setUpTestData(cls):
716 """Create the following test data:
718 o0: an empty order
719 o1: an unpaid order of 2 beer
720 o2: an order of 2 soda that doesn't need a payment
721 o3: an unpaid order with 2 beer and 2 wine
722 o4: a paid order with 2 wine
723 o4: a paid order with 2 beer and 2 wine
724 """
725 cls.member = Member.objects.filter(last_name="Wiggers").first()
727 cls.beer = Product.objects.get(name="beer")
728 cls.wine = Product.objects.get(name="wine")
729 cls.soda = Product.objects.get(name="soda")
731 cls.normal = ProductList.objects.get(
732 name="normal",
733 )
734 cls.free = ProductList.objects.get(
735 name="free",
736 )
738 cls.shift = Shift.objects.create(
739 start=timezone.now(),
740 end=timezone.now() + timezone.timedelta(hours=1),
741 product_list=cls.normal,
742 )
744 cls.shift2 = Shift.objects.create(
745 start=timezone.now(),
746 end=timezone.now() + timezone.timedelta(hours=1),
747 product_list=cls.free,
748 )
750 cls.o0 = Order.objects.create(shift=cls.shift)
751 cls.o1 = Order.objects.create(shift=cls.shift)
752 OrderItem.objects.create(
753 order=cls.o1,
754 product=cls.shift.product_list.product_items.get(product=cls.beer),
755 amount=2,
756 )
757 cls.o2 = Order.objects.create(shift=cls.shift)
758 OrderItem.objects.create(
759 order=cls.o2,
760 product=cls.shift.product_list.product_items.get(product=cls.soda),
761 amount=2,
762 )
763 cls.o3 = Order.objects.create(shift=cls.shift)
764 OrderItem.objects.create(
765 order=cls.o3,
766 product=cls.shift.product_list.product_items.get(product=cls.beer),
767 amount=2,
768 )
769 OrderItem.objects.create(
770 order=cls.o3,
771 product=cls.shift.product_list.product_items.get(product=cls.wine),
772 amount=2,
773 )
774 cls.o4 = Order.objects.create(shift=cls.shift)
775 OrderItem.objects.create(
776 order=cls.o4,
777 product=cls.shift.product_list.product_items.get(product=cls.wine),
778 amount=2,
779 )
780 cls.o5 = Order.objects.create(shift=cls.shift)
781 OrderItem.objects.create(
782 order=cls.o5,
783 product=cls.shift.product_list.product_items.get(product=cls.beer),
784 amount=2,
785 )
786 OrderItem.objects.create(
787 order=cls.o5,
788 product=cls.shift.product_list.product_items.get(product=cls.wine),
789 amount=2,
790 )
791 cls.o4.payment = create_payment(
792 cls.o4, processed_by=cls.member, pay_type=Payment.CASH
793 )
794 cls.o4.save()
795 cls.o5.payment = create_payment(
796 cls.o5, processed_by=cls.member, pay_type=Payment.CASH
797 )
798 cls.o5.save()
800 cls.cie = Committee.objects.get(pk=1)
801 MemberGroupMembership.objects.create(group=cls.cie, member=cls.member)
802 content_type = ContentType.objects.get_for_model(Order)
803 permission1 = Permission.objects.get(
804 content_type=content_type, codename="add_order"
805 )
806 permission2 = Permission.objects.get(
807 content_type=content_type, codename="change_order"
808 )
809 permission3 = Permission.objects.get(
810 content_type=content_type, codename="delete_order"
811 )
812 permission4 = Permission.objects.get(
813 content_type=content_type, codename="view_order"
814 )
815 permission5 = Permission.objects.get(
816 content_type=ContentType.objects.get_for_model(Shift), codename="view_shift"
817 )
818 cls.cie.permissions.add(permission1)
819 cls.cie.permissions.add(permission2)
820 cls.cie.permissions.add(permission3)
821 cls.cie.permissions.add(permission4)
822 cls.cie.permissions.add(permission5)
824 def setUp(self):
825 self.client = APIClient()
826 self.client.force_login(self.member)
828 def test_detail_not_logged_in(self):
829 self.client.logout()
830 response = self.client.get(
831 reverse("api:v2:admin:sales:shift-detail", kwargs={"pk": self.shift.pk})
832 )
833 self.assertEqual(403, response.status_code)
835 def test_detail_not_authorized__get(self):
836 response = self.client.get(
837 reverse("api:v2:admin:sales:shift-detail", kwargs={"pk": self.shift.pk})
838 )
839 self.assertEqual(200, response.status_code)
841 self.member.is_superuser = False
842 self.member.save()
844 response = self.client.get(
845 reverse("api:v2:admin:sales:shift-detail", kwargs={"pk": self.shift.pk})
846 )
847 self.assertEqual(403, response.status_code)
849 self.shift.managers.add(self.cie)
850 self.shift.save()
852 response = self.client.get(
853 reverse("api:v2:admin:sales:shift-detail", kwargs={"pk": self.shift.pk})
854 )
855 self.assertEqual(200, response.status_code)
857 def test_list_not_logged_in(self):
858 self.client.logout()
859 response = self.client.get(reverse("api:v2:admin:sales:shift-list"))
860 self.assertEqual(403, response.status_code)
862 def test_list_not_authorized__get(self):
863 response = self.client.get(reverse("api:v2:admin:sales:shift-list"))
864 self.assertEqual(200, response.status_code)
865 self.assertEqual(2, response.data["count"])
867 self.member.is_superuser = False
868 self.member.save()
870 response = self.client.get(reverse("api:v2:admin:sales:shift-list"))
871 self.assertEqual(200, response.status_code)
872 self.assertEqual(0, response.data["count"])
874 self.shift.managers.add(self.cie)
875 self.shift.save()
877 response = self.client.get(reverse("api:v2:admin:sales:shift-list"))
878 self.assertEqual(200, response.status_code)
879 self.assertEqual(1, response.data["count"])