from unittest.mock import MagicMock, patch from authlib.integrations.base_client import BaseApp from django.contrib.sessions.middleware import SessionMiddleware from django.test import TestCase, RequestFactory from graphene.test import Client from api.schema import schema from core.factories import UserFactory from oauth.factories import Oauth2TokenFactory from users.tests.mock_hep_data_factory import MockResponse from users.models import License, Role, SchoolClass REDEEM_MYSKILLBOX_SUCCESS_RESPONSE = { "data": { "id": 3433, "uri": "\/products\/myskillbox-lehrpersonen", "url": None, "title": "mySkillbox für Lehrpersonen ", "subtitle": "Lizenz gültig für 1 Jahr", "isbn": "978-3-0355-1861-0", "slug": "myskillbox-lehrpersonen", "product_type": "eLehrmittel", "product_form": "", "cover": "https:\/\/hep-verlag.fra1.digitaloceanspaces.com\/staging\/products\/2921\/978-3-0355-1861-0.jpg", "price": 100, "price_total": 100, "amount": 1, "authors": [], } } REDEEM_OTHER_LICENSE_RESPONSE = { "data": { "id": 3433, "uri": "\/products\/someothe", "url": None, "title": "Ein e-Lehrmittel", "subtitle": "Lizenz gültig für 1 Jahr", "isbn": "111-2-3333-4444-0", "slug": "some-other", "product_type": "eLehrmittel", "product_form": "", "cover": "https:\/\/hep-verlag.fra1.digitaloceanspaces.com\/staging\/products\/2921\/978-3-0355-123.jpg", "price": 100, "price_total": 100, "amount": 1, "authors": [], } } INVALID_LICENSE = { "message": "The given data was invalid.", "errors": {"code": ["The coupons was already redeemed."]}, } class CouponTests(TestCase): def setUp(self): get_response = MagicMock() self.user = UserFactory( username="aschi@iterativ.ch", email="aschi@iterativ.ch", hep_id=3 ) Role.objects.create_default_roles() self.teacher_role = Role.objects.get_default_teacher_role() Oauth2TokenFactory(user=self.user) # adding session request = RequestFactory().post("/") middleware = SessionMiddleware(get_response) middleware.process_request(request) request.user = self.user request.session.save() self.client = Client(schema=schema, context_value=request) def make_coupon_mutation(self, coupon_code, client): mutation = """ mutation Coupon($input: CouponInput!){ coupon(input: $input) { result { __typename ...on InvalidCoupon { reason } ...on Success { message } } } } """ return client.execute( mutation, variables={"input": {"couponCode": coupon_code}} ) @patch.object( BaseApp, "post", return_value=MockResponse(200, data=REDEEM_MYSKILLBOX_SUCCESS_RESPONSE), ) def test_user_has_valid_skillbox_coupon(self, response_mock): result = self.make_coupon_mutation("COUPON--1234", self.client) user_role = self.user.user_roles.get(user=self.user) self.assertEqual(user_role.role.key, Role.objects.TEACHER_KEY) license = License.objects.get(licensee=self.user) self.assertIsNotNone(license) school_class = SchoolClass.objects.get(users__in=[self.user]) self.assertIsNotNone(school_class) self.assertEqual( result.get("data").get("coupon").get("result").get("__typename"), "Success" ) self.assertTrue(self.user.is_authenticated) @patch.object( BaseApp, "post", return_value=MockResponse(200, data=REDEEM_OTHER_LICENSE_RESPONSE), ) def test_user_has_valid_non_skillbox_coupon(self, response_mock): result = self.make_coupon_mutation("COUPON--1234", self.client) try: self.user.user_roles.get(user=self.user) self.fail( "CouponTests.test_user_has_valid_non_skillbox_coupon: Should not have created user role" ) except: pass try: License.objects.get(licensee=self.user) self.fail( "CouponTests.test_user_has_valid_non_skillbox_coupon: License should not exist" ) except License.DoesNotExist: pass self.assertEqual( result.get("errors")[0].get("message"), "non_myskillbox_product" ) self.assertTrue(self.user.is_authenticated) @patch.object(BaseApp, "post", return_value=MockResponse(404, data=INVALID_LICENSE)) def test_user_has_invalid_coupon(self, response_mock): result = self.make_coupon_mutation("COUPON--1234", self.client) self.assertEqual( result.get("data").get("coupon").get("result").get("__typename"), "InvalidCoupon", ) @patch.object(BaseApp, "post", return_value=MockResponse(422, data=INVALID_LICENSE)) def test_user_has_already_used_coupon(self, response_mock): result = self.make_coupon_mutation("COUPON--1234", self.client) self.assertEqual( result.get("data").get("coupon").get("result").get("__typename"), "InvalidCoupon", ) @patch.object( BaseApp, "put", return_value=MockResponse(200, data=["201", "Invalid Coupon"]) ) def test_unauthenticated_user_cannot_redeem(self, response_mock): get_response = MagicMock() request = RequestFactory().post("/") middleware = SessionMiddleware(get_response) middleware.process_request(request) request.session.save() client = Client(schema=schema, context_value=request) result = self.make_coupon_mutation("COUPON--1234", client) self.assertEqual(result.get("errors")[0].get("message"), "not_authenticated")