def test_successful_flat_redirect(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when response = self.client.get(reverse('external_login'), data={ 'redirect': 'https://some-page', 'app_id': 'test' }) # then self.assertRegex(text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='https://some-page\?jwt=.*') # check jwt url_params = response.url.split("?")[1] jwt_str = url_params.split("=")[1] payload = jwt.decode(jwt_str, verify=False) self.assertIsNotNone(payload) self.assertEqual(payload['user_slug'], self.new_user.slug) self.assertEqual(payload['user_name'], self.new_user.full_name) self.assertIsNotNone(payload['exp'])
def test_param_redirect_absent(self): self.client = HelperClient(user=self.new_user) self.client.authorise() response = self.client.get(reverse('external_login'), data={'app_id': 'test'}) self.assertContains(response=response, text="Нужен параметр ?redirect", status_code=400)
def setUp(self): self.client = HelperClient() self.existed_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4")
def test_user_unauthorized(self): # given client = HelperClient() self.assertFalse(client.is_authorised()) # when response = client.get(reverse('membership_expired')) self.assertRedirects(response=response, expected_url=f'/', fetch_redirect_response=False)
class ViewExternalLoginTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4" ) def setUp(self): self.client = HelperClient() def test_successful_flat_redirect(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when with self.settings(JWT_PRIVATE_KEY=JWT_STUB_VALUES.JWT_PRIVATE_KEY): response = self.client.get(reverse('external_login'), data={'redirect': 'some-page'}) # then self.assertRegex(text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='\/auth\/external\/some-page\?jwt=.*') # check jwt url_params = response.url.split("?")[1] jwt_str = url_params.split("=")[1] payload = jwt.decode(jwt_str, verify=False) self.assertIsNotNone(payload) self.assertEqual(payload['user_slug'], self.new_user.slug) self.assertEqual(payload['user_name'], self.new_user.full_name) self.assertIsNotNone(payload['exp']) def test_successful_redirect_with_query_params(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when with self.settings(JWT_PRIVATE_KEY=JWT_STUB_VALUES.JWT_PRIVATE_KEY): response = self.client.get(reverse('external_login'), data={'redirect': 'some-page?param1=value1'}) # then self.assertRegex(text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='\/auth\/external\/some-page\?param1=value1&jwt=.*') def test_param_redirect_absent(self): response = self.client.get(reverse('external_login')) self.assertContains(response=response, text="Нужен параметр ?redirect", status_code=200) def test_user_is_unauthorised(self): response = self.client.get(reverse('external_login'), data={'redirect': 'some-page'}) self.assertRedirects(response=response, expected_url='/auth/login/?goto=%2Fauth%2Fexternal%2F%3Fredirect%3Dsome-page', fetch_redirect_response=False) self.assertFalse(self.client.is_authorised())
def test_param_wrong_app_id(self): self.client = HelperClient(user=self.new_user) self.client.authorise() response = self.client.get(reverse('external_login'), data={ 'app_id': 'UNKNOWN', 'redirect': 'https://some-page' }) self.assertContains( response=response, text="Неизвестное приложение, проверьте параметр ?app_id", status_code=400)
def test_successful_redirect_with_query_params(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when with self.settings(JWT_PRIVATE_KEY=JWT_STUB_VALUES.JWT_PRIVATE_KEY): response = self.client.get(reverse('external_login'), data={'redirect': 'some-page?param1=value1'}) # then self.assertRegex(text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='\/auth\/external\/some-page\?param1=value1&jwt=.*')
def test_membership_expires_future(self): # given new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4") client = HelperClient(user=new_user) client.authorise() # when response = client.get(reverse('membership_expired')) self.assertRedirects(response=response, expected_url=f'/user/{new_user.slug}/', fetch_redirect_response=False)
def test_membership_already_expired(self): # given new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=10), membership_expires_at=datetime.now() - timedelta(days=5), slug="ujlbu4") client = HelperClient(user=new_user) client.authorise() # when response = client.get(reverse('membership_expired')) self.assertContains(response=response, text="Ваша клубная карта истекла", status_code=200)
class TestDoneView(TestCase): def setUp(self): self.client = HelperClient(user=None) def test_club_member(self): existed_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.utcnow() - timedelta(days=5), membership_expires_at=datetime.utcnow() + timedelta(days=5), moderation_status=User.MODERATION_STATUS_APPROVED, slug="ujlbu4", ) existed_payment: Payment = Payment.create( reference=f"random-reference-{uuid.uuid4()}", user=existed_user, product=PRODUCTS["club1"]) response = self.client.get( reverse('done'), data={'reference': existed_payment.reference}) self.assertContains(response=response, text="Ваша клубная карта продлена", status_code=200) def test_not_club_member(self): existed_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.utcnow() - timedelta(days=5), membership_expires_at=datetime.utcnow() + timedelta(days=5), moderation_status=User.MODERATION_STATUS_INTRO, slug="ujlbu4", ) existed_payment: Payment = Payment.create( reference=f"random-reference-{uuid.uuid4()}", user=existed_user, product=PRODUCTS["club1"]) response = self.client.get( reverse('done'), data={'reference': existed_payment.reference}) self.assertContains(response=response, text="Теперь у вас есть аккаунт в Клубе", status_code=200) def test_reference_not_found(self): response = self.client.get(reverse('done'), data={'reference': 'wrong-reference'}) self.assertContains(response=response, text="Теперь у вас есть аккаунт в Клубе", status_code=200)
def test_successful_redirect_with_query_params(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when response = self.client.get(reverse('external_login'), data={ 'redirect': 'https://some-page?param1=value1', 'app_id': 'test' }) # then self.assertRegex( text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='https://some-page\?param1=value1&jwt=.*')
def setUp(self): self.client = HelperClient() self.stub_patreon_response_oauth_token = { "access_token": "xxx-access-token", "refresh_token": "xxx-refresh-token", "expires_in": (datetime.utcnow() + timedelta(minutes=5)).microsecond, "scope": "scope??", "token_type": "Bearer" } self.stub_patreon_response_oauth_identity = None # doesn't need for now self.stub_parse_membership = Membership( platform=Platform.patreon, user_id=str(uuid.uuid4()), full_name="PatreonMember FullName", email="*****@*****.**", image="http://xxx.url", started_at=datetime.utcnow(), charged_at=None, expires_at=datetime.utcnow() + timedelta(days=100 * 365), lifetime_support_cents=400, currently_entitled_amount_cents=0 )
class ViewEmailLoginCodeTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4") cls.code = Code.create_for_user(user=cls.new_user, recipient=cls.new_user.email) def setUp(self): self.client = HelperClient(user=self.new_user) def test_correct_code(self): # given # email is not verified yet self.assertFalse( User.objects.get(id=self.new_user.id).is_email_verified) # when response = self.client.get(reverse('email_login_code'), data={ 'email': self.new_user.email, 'code': self.code.code }) self.assertRedirects(response=response, expected_url=f'/user/{self.new_user.slug}/', fetch_redirect_response=False) self.assertTrue(self.client.is_authorised()) self.assertTrue( User.objects.get(id=self.new_user.id).is_email_verified) def test_empty_params(self): response = self.client.get(reverse('email_login_code'), data={}) self.assertRedirects(response=response, expected_url=f'/auth/login/', fetch_redirect_response=False) self.assertFalse(self.client.is_authorised()) self.assertFalse( User.objects.get(id=self.new_user.id).is_email_verified) def test_wrong_code(self): response = self.client.get(reverse('email_login_code'), data={ 'email': self.new_user.email, 'code': 'intentionally-wrong-code' }) self.assertEqual(response.status_code, HttpResponseBadRequest.status_code) self.assertFalse(self.client.is_authorised()) self.assertFalse( User.objects.get(id=self.new_user.id).is_email_verified)
class TestStripeWebhookView(TestCase): def setUp(self): self.client = HelperClient() self.existed_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4") @staticmethod def read_json_event(event_file_name): current_dir = os.path.dirname(os.path.abspath(__file__)) file_path = os.path.join(current_dir, f'./_stubs/{event_file_name}.json') with open(file_path, 'r') as f: json_event = yaml.safe_load(f.read()) return json_event def test_event_checkout_session_completed_positive(self): # links: # https://stripe.com/docs/webhooks/signatures # https://stripe.com/docs/api/events/object # given product = PRODUCTS["club1"] opened_payment: Payment = Payment.create( reference=f"random-reference-{uuid.uuid4()}", user=self.existed_user, product=product) strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): json_event = self.read_json_event('checkout.session.completed') json_event['data']['object']['id'] = opened_payment.reference timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then self.assertEqual(response.status_code, 200) # subscription prolongated user = User.objects.get(id=self.existed_user.id) self.assertAlmostEquals(user.membership_expires_at, self.existed_user.membership_expires_at + product['data']['timedelta'], delta=timedelta(seconds=10)) @skip("do we need throw error in case payment not found?") def test_event_checkout_session_completed_negative_payment_not_found(self): # given strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): json_event = self.read_json_event('checkout.session.completed') json_event['data']['object'][ 'id'] = "some-payment-reference-not-existed" # not existed payment reference timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then self.assertEqual( response.status_code, 409) # conflict due to payment not found (let it try latter) # subscription expiration not prolongated user = User.objects.get(id=self.existed_user.id) self.assertEqual(user.membership_expires_at, self.existed_user.membership_expires_at) def test_event_invoice_paid_with_billing_reason_subscription_create_positive( self): # links: # https://stripe.com/docs/webhooks/signatures # https://stripe.com/docs/api/events/object # given strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): json_event = self.read_json_event('invoice.paid') json_event['data']['object']['id'] = f'payment-id-{uuid.uuid4()}' json_event['data']['object'][ 'billing_reason'] = "subscription_create" timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then self.assertEqual(response.status_code, 200) # subscription not prolonging, cause it assumes it has already done in `checkout.session.completed` event user = User.objects.get(id=self.existed_user.id) self.assertEqual(user.membership_expires_at, self.existed_user.membership_expires_at) def test_event_invoice_paid_with_billing_reason_subscription_cycle_positive( self): # given strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): self.existed_user.stripe_id = f'stripe-id-{uuid.uuid4()}' self.existed_user.save() json_event = self.read_json_event('invoice.paid') json_event['data']['object']['id'] = f'payment-id-{uuid.uuid4()}' json_event['data']['object'][ 'billing_reason'] = "subscription_cycle" json_event['data']['object'][ 'customer'] = self.existed_user.stripe_id product = PRODUCTS['club1_recurrent_yearly'] json_event['data']['object']['lines']["data"][0]["plan"][ "id"] = product['stripe_id'] timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then # subscription prolonged self.assertEqual(response.status_code, 200) # subscription prolonged user = User.objects.get(id=self.existed_user.id) self.assertAlmostEquals(user.membership_expires_at, self.existed_user.membership_expires_at + product['data']['timedelta'], delta=timedelta(seconds=10)) @skip("do we need throw error in case payment not found?") def test_event_invoice_paid_negative_user_not_found(self): # given strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): self.existed_user.stripe_id = f'stripe-id-{uuid.uuid4()}' self.existed_user.save() json_event = self.read_json_event('invoice.paid') json_event['data']['object'][ 'id'] = f'payment-id-{uuid.uuid4()}' json_event['data']['object'][ 'billing_reason'] = "subscription_cycle" json_event['data']['object']['customer'] = "not-existed-user" timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then self.assertEqual( response.status_code, 409 ) # conflict due to payment not found (let it try latter) # subscription expiration not prolonged user = User.objects.get(id=self.existed_user.id) self.assertEqual(user.membership_expires_at, self.existed_user.membership_expires_at) def test_event_customer_updated_positive(self): strip_secret = "stripe_secret" with self.settings(STRIPE_WEBHOOK_SECRET=strip_secret): self.assertEqual(self.existed_user.stripe_id, None) json_event = self.read_json_event('customer.updated') json_event['data']['object']['email'] = self.existed_user.email timestamp = int(time.time()) signed_payload = f"{timestamp}.{json.dumps(json_event)}" computed_signature = WebhookSignature._compute_signature( signed_payload, strip_secret) # when header = { 'HTTP_STRIPE_SIGNATURE': f't={timestamp},v1={computed_signature}' } response = self.client.post(reverse("stripe_webhook"), data=json_event, content_type='application/json', **header) # then self.assertEqual(response.status_code, 200) # subscription not prolonging, cause it assumes it has already done in `checkout.session.completed` event user = User.objects.get(id=self.existed_user.id) self.assertEqual(user.stripe_id, json_event['data']['object']['id']) self.assertEqual(user.membership_expires_at, self.existed_user.membership_expires_at) def test_negative_no_payload(self): header = {'HTTP_STRIPE_SIGNATURE': 'xxx'} response = self.client.post(reverse("stripe_webhook"), content_type='application/json', **header) self.assertEqual(response.status_code, 400) def test_negative_no_signature(self): response = self.client.post(reverse("stripe_webhook"), data={"xxx": 1}, content_type='application/json') self.assertEqual(response.status_code, 400) def test_negative_invalid_signature(self): header = {'HTTP_STRIPE_SIGNATURE': 'invalid-signature'} with self.settings(STRIPE_WEBHOOK_SECRET="stripe_secret"): response = self.client.post(reverse("stripe_webhook"), data={"xxx": 1}, content_type='application/json', **header) self.assertEqual(response.status_code, 400)
def setUp(self): self.client = HelperClient(user=self.existed_user)
class TestPayView(TestCase): @classmethod def setUpTestData(cls): cls.existed_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4") def setUp(self): self.client = HelperClient(user=self.existed_user) def test_positive_new_user(self, mocked_stripe): # given product_code = "club1" email = f"new-user-{uuid.uuid4()}@email.com" StripeSession = namedtuple('Session', "id") session = StripeSession(id=f"{uuid.uuid4()}") mocked_stripe.checkout.Session.create.return_value = session # when response = self.client.get( reverse("pay"), data={ "product_code": product_code, # "is_recurrent": PRODUCTS[product_code]["recurrent"], "email": email }) # check self.assertTrue(User.objects.filter(email=email).exists(), ) created_user: User = User.objects.get(email=email) self.assertEqual(created_user.email, email) self.assertEqual(created_user.membership_platform_type, User.MEMBERSHIP_PLATFORM_DIRECT) self.assertEqual(created_user.full_name, email.replace("@email.com", "")) self.assertAlmostEquals(created_user.membership_started_at, datetime.utcnow(), delta=timedelta(seconds=5)) self.assertAlmostEquals(created_user.membership_expires_at, datetime.utcnow(), delta=timedelta(seconds=5)) self.assertEqual(created_user.moderation_status, User.MODERATION_STATUS_INTRO) self.assertTrue(Payment.get(reference=session.id)) self.assertContains(response=response, text="Платим 💰", status_code=200) def test_positive_existed_authorised_user(self, mocked_stripe): # given product_code = "club1" StripeSession = namedtuple('Session', "id") session = StripeSession(id=f"{uuid.uuid4()}") mocked_stripe.checkout.Session.create.return_value = session self.client.authorise() # when response = self.client.get(reverse("pay"), data={ "product_code": product_code, }) # check self.assertTrue( User.objects.filter(email=self.existed_user.email).exists(), ) user_after: User = User.objects.get(email=self.existed_user.email) self.assertEqual(user_after.membership_platform_type, self.existed_user.membership_platform_type) self.assertEqual(user_after.full_name, self.existed_user.full_name) self.assertEqual(user_after.membership_started_at, self.existed_user.membership_started_at) self.assertAlmostEquals(user_after.membership_expires_at, self.existed_user.membership_expires_at) self.assertEqual(user_after.moderation_status, self.existed_user.moderation_status) self.assertTrue(Payment.get(reference=session.id)) self.assertContains(response=response, text="Платим 💰", status_code=200) def test_negative_new_user_with_broken_email(self, mocked_stripe): # given product_code = "club1" broken_email = f"email-invalid" # when response = self.client.get(reverse("pay"), data={ "product_code": product_code, "email": broken_email }) # check self.assertFalse(User.objects.filter(email=broken_email).exists(), ) self.assertContains(response=response, text="Плохой e-mail адрес", status_code=200) def test_product_not_found(self, mocked_stripe): product_code = "unexisted-product-code" # when response = self.client.get(reverse("pay"), data={ "product_code": product_code, }) # check self.assertContains(response=response, text="Не выбран пакет", status_code=200)
def _authorized_client(user): client = HelperClient(user) if user is not None: client.authorise() return client
def setUp(self): self.client = HelperClient(user=self.new_user)
class ViewExternalLoginTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4") cls.app: Apps = Apps.objects.create( id="test", name="test", jwt_secret=JWT_STUB_VALUES.JWT_PRIVATE_KEY, jwt_algorithm="RS256", jwt_expire_hours=1, redirect_urls=["https://some-page"], ) def setUp(self): self.client = HelperClient() def test_successful_flat_redirect(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when response = self.client.get(reverse('external_login'), data={ 'redirect': 'https://some-page', 'app_id': 'test' }) # then self.assertRegex(text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='https://some-page\?jwt=.*') # check jwt url_params = response.url.split("?")[1] jwt_str = url_params.split("=")[1] payload = jwt.decode(jwt_str, verify=False) self.assertIsNotNone(payload) self.assertEqual(payload['user_slug'], self.new_user.slug) self.assertEqual(payload['user_name'], self.new_user.full_name) self.assertIsNotNone(payload['exp']) def test_successful_redirect_with_query_params(self): # given self.client = HelperClient(user=self.new_user) self.client.authorise() # when response = self.client.get(reverse('external_login'), data={ 'redirect': 'https://some-page?param1=value1', 'app_id': 'test' }) # then self.assertRegex( text=urljoin(response.request['PATH_INFO'], response.url), expected_regex='https://some-page\?param1=value1&jwt=.*') def test_param_wrong_app_id(self): self.client = HelperClient(user=self.new_user) self.client.authorise() response = self.client.get(reverse('external_login'), data={ 'app_id': 'UNKNOWN', 'redirect': 'https://some-page' }) self.assertContains( response=response, text="Неизвестное приложение, проверьте параметр ?app_id", status_code=400) def test_param_redirect_absent(self): self.client = HelperClient(user=self.new_user) self.client.authorise() response = self.client.get(reverse('external_login'), data={'app_id': 'test'}) self.assertContains(response=response, text="Нужен параметр ?redirect", status_code=400) def test_user_is_unauthorised(self): response = self.client.get(reverse('external_login'), data={ 'redirect': 'some-page', 'app_id': 'test' }) self.assertRedirects( response=response, expected_url= '/auth/login/?goto=%2Fauth%2Fexternal%2F%3Fredirect%3Dsome-page', fetch_redirect_response=False) self.assertFalse(self.client.is_authorised())
def setUp(self): self.client = HelperClient()
class ViewEmailLoginTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4" ) cls.broker = brokers.get_broker() cls.assertTrue(cls.broker.ping(), 'broker is not available') def setUp(self): self.client = HelperClient(user=self.new_user) self.broker.purge_queue() def test_login_by_email_positive(self): # when response = self.client.post(reverse('email_login'), data={'email_or_login': self.new_user.email, }) # then self.assertContains(response=response, text="Вам отправлен код!", status_code=200) issued_code = Code.objects.filter(recipient=self.new_user.email).get() self.assertIsNotNone(issued_code) # check email was sent packages = self.broker.dequeue() task_signed = packages[0][1] task = SignedPackage.loads(task_signed) self.assertEqual(task['func'].__name__, 'send_auth_email') self.assertEqual(task['args'][0].id, self.new_user.id) self.assertEqual(task['args'][1].id, issued_code.id) # check notify wast sent packages = self.broker.dequeue() task_signed = packages[0][1] task = SignedPackage.loads(task_signed) self.assertEqual(task['func'].__name__, 'notify_user_auth') self.assertEqual(task['args'][0].id, self.new_user.id) self.assertEqual(task['args'][1].id, issued_code.id) # it's not yet authorised, only code was sent self.assertFalse(self.client.is_authorised()) def test_login_user_not_exist(self): response = self.client.post(reverse('email_login'), data={'email_or_login': '******', }) self.assertContains(response=response, text="Такого юзера нет 🤔", status_code=200) def test_secret_hash_login(self): response = self.client.post(reverse('email_login'), data={'email_or_login': self.new_user.secret_auth_code, }) self.assertRedirects(response=response, expected_url=f'/user/{self.new_user.slug}/', fetch_redirect_response=False) self.assertTrue(self.client.is_authorised()) def test_secret_hash_user_not_exist(self): response = self.client.post(reverse('email_login'), data={'email_or_login': '******', }) self.assertContains(response=response, text="Такого юзера нет 🤔", status_code=200) @skip("todo") def test_secret_hash_cancel_user_deletion(self): # todo: mark user as deleted self.assertTrue(False) def test_email_login_missed_input_data(self): response = self.client.post(reverse('email_login'), data={}) self.assertRedirects(response=response, expected_url=f'/auth/login/', fetch_redirect_response=False) def test_email_login_wrong_method(self): response = self.client.get(reverse('email_login')) self.assertRedirects(response=response, expected_url=f'/auth/login/', fetch_redirect_response=False) response = self.client.put(reverse('email_login')) self.assertRedirects(response=response, expected_url=f'/auth/login/', fetch_redirect_response=False) response = self.client.delete(reverse('email_login')) self.assertRedirects(response=response, expected_url=f'/auth/login/', fetch_redirect_response=False)
class ViewsAuthTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4" ) def setUp(self): self.client = HelperClient(user=self.new_user) def test_join_anonymous(self): response = self.client.get(reverse('join')) # check auth/join.html is rendered self.assertContains(response=response, text="Всегда рады новым членам", status_code=200) def test_join_authorised(self): self.client.authorise() response = self.client.get(reverse('join')) self.assertRedirects(response=response, expected_url=f'/user/{self.new_user.slug}/', fetch_redirect_response=False) def test_login_anonymous(self): response = self.client.get(reverse('login')) # check auth/join.html is rendered self.assertContains(response=response, text="Вход по почте или нику", status_code=200) def test_login_authorised(self): self.client.authorise() response = self.client.get(reverse('login')) self.assertRedirects(response=response, expected_url=f'/user/{self.new_user.slug}/', fetch_redirect_response=False) def test_logout_success(self): self.client.authorise() response = self.client.post(reverse('logout')) self.assertRedirects(response=response, expected_url=f'/', fetch_redirect_response=False) self.assertFalse(self.client.is_authorised()) def test_logout_unauthorised(self): response = self.client.post(reverse('logout')) self.assertTrue(self.client.is_access_denied(response)) def test_logout_wrong_method(self): self.client.authorise() response = self.client.get(reverse('logout')) self.assertEqual(response.status_code, HttpResponseNotAllowed.status_code) response = self.client.put(reverse('logout')) self.assertEqual(response.status_code, HttpResponseNotAllowed.status_code) response = self.client.delete(reverse('logout')) self.assertEqual(response.status_code, HttpResponseNotAllowed.status_code) def test_debug_dev_login_unauthorised(self): response = self.client.post(reverse('debug_dev_login')) self.assertTrue(self.client.is_authorised()) me = self.client.print_me() self.assertIsNotNone(me['id']) self.assertEqual(me['email'], '*****@*****.**') self.assertTrue(me['is_email_verified']) self.assertTrue(me['slug'], 'dev') self.assertEqual(me['moderation_status'], 'approved') self.assertEqual(me['roles'], ['god']) # todo: check created post (intro) def test_debug_dev_login_authorised(self): self.client.authorise() response = self.client.post(reverse('debug_dev_login')) self.assertTrue(self.client.is_authorised()) me = self.client.print_me() self.assertTrue(me['slug'], self.new_user.slug) def test_debug_random_login_unauthorised(self): response = self.client.post(reverse('debug_random_login')) self.assertTrue(self.client.is_authorised()) me = self.client.print_me() self.assertIsNotNone(me['id']) self.assertIn('@random.dev', me['email']) self.assertTrue(me['is_email_verified']) self.assertEqual(me['moderation_status'], 'approved') self.assertEqual(me['roles'], [])
def setUp(self): self.client = HelperClient(user=self.new_user) self.broker.purge_queue()
def setUp(self): self.client = HelperClient(user=None)
class ViewPatreonOauthCallbackTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.new_user: User = User.objects.create( email="*****@*****.**", membership_started_at=datetime.now() - timedelta(days=5), membership_expires_at=datetime.now() + timedelta(days=5), slug="ujlbu4" ) def setUp(self): self.client = HelperClient() self.stub_patreon_response_oauth_token = { "access_token": "xxx-access-token", "refresh_token": "xxx-refresh-token", "expires_in": (datetime.utcnow() + timedelta(minutes=5)).microsecond, "scope": "scope??", "token_type": "Bearer" } self.stub_patreon_response_oauth_identity = None # doesn't need for now self.stub_parse_membership = Membership( platform=Platform.patreon, user_id=str(uuid.uuid4()), full_name="PatreonMember FullName", email="*****@*****.**", image="http://xxx.url", started_at=datetime.utcnow(), charged_at=None, expires_at=datetime.utcnow() + timedelta(days=100 * 365), lifetime_support_cents=400, currently_entitled_amount_cents=0 ) def test_successful_login_new_member(self, mocked_patreon): # given mocked_patreon.fetch_auth_data.return_value = self.stub_patreon_response_oauth_token mocked_patreon.fetch_user_data.return_value = self.stub_patreon_response_oauth_identity membership = self.stub_parse_membership membership.user_id = str(uuid.uuid4()) membership.email = f"{membership.user_id}@email.com" mocked_patreon.parse_active_membership.return_value = membership # when response = self.client.get(reverse('patreon_oauth_callback'), data={'code': '1234'}) # then self.assertRedirects(response=response, expected_url=f'/user/PatreonMemberFullName/', fetch_redirect_response=False) self.assertTrue(self.client.is_authorised()) # created user created_user: User = User.objects.filter(email=membership.email).get() self.assertIsNotNone(created_user) self.assertEqual(created_user.patreon_id, membership.user_id) self.assertEqual(created_user.full_name, "PatreonMember FullName") self.assertEqual(created_user.membership_platform_type, "patreon") self.assertEqual(created_user.membership_started_at, membership.started_at) self.assertEqual(created_user.membership_expires_at, membership.expires_at) self.assertEqual(created_user.balance, 4) # 400 / 100 self.assertFalse(created_user.is_email_verified) self.assertEqual(created_user.membership_platform_data, {'access_token': 'xxx-access-token', 'refresh_token': 'xxx-refresh-token'}) def test_successful_login_existed_member(self, mocked_patreon): # given mocked_patreon.fetch_auth_data.return_value = self.stub_patreon_response_oauth_token mocked_patreon.fetch_user_data.return_value = self.stub_patreon_response_oauth_identity membership = self.stub_parse_membership membership.email = "*****@*****.**" membership.lifetime_support_cents = 100500 mocked_patreon.parse_active_membership.return_value = membership # when response = self.client.get(reverse('patreon_oauth_callback'), data={'code': '1234'}) # then self.assertRedirects(response=response, expected_url=f'/user/ujlbu4/', fetch_redirect_response=False) self.assertTrue(self.client.is_authorised()) # user updated attributes created_user: User = User.objects.filter(email="*****@*****.**").get() self.assertIsNotNone(created_user) self.assertEqual(created_user.membership_expires_at, membership.expires_at) self.assertEqual(created_user.balance, 1005) # 100500 / 100 self.assertEqual(created_user.membership_platform_data, {'access_token': 'xxx-access-token', 'refresh_token': 'xxx-refresh-token'}) def test_patreon_exception(self, mocked_patreon): # given mocked_patreon.fetch_auth_data.side_effect = PatreonException("custom_test_exception") # when response = self.client.get(reverse('patreon_oauth_callback'), data={'code': '1234'}) # then self.assertContains(response=response, text="Не получилось загрузить ваш профиль с серверов патреона", status_code=200) def test_patreon_not_membership(self, mocked_patreon): # given mocked_patreon.fetch_auth_data.return_value = self.stub_patreon_response_oauth_token mocked_patreon.fetch_user_data.return_value = None mocked_patreon.parse_active_membership.return_value = None # no membership # when response = self.client.get(reverse('patreon_oauth_callback'), data={'code': '1234'}) # then self.assertContains(response=response, text="Надо быть патроном, чтобы состоять в Клубе", status_code=200) def test_param_code_absent(self, mocked_patreon=None): response = self.client.get(reverse('patreon_oauth_callback'), data={}) self.assertContains(response=response, text="Что-то сломалось между нами и патреоном", status_code=200)