diff --git a/Pipfile.lock b/Pipfile.lock index 53e6e997..a4832918 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -224,11 +224,11 @@ }, "django-pagarme": { "hashes": [ - "sha256:2afdc7a515bde810b625dab6f5a19b2a90c428e71b1be882e8485b06d36386d1", - "sha256:fec385a79c36e3172500f8e714c234f5562207116a936d7024afebf2645c42e5" + "sha256:0db3dd97fbca1a2abf286bd2bce3933f5ee6471a5233b6beabab061778072a01", + "sha256:adff29f3fc8cece4d07ca0eae27a7454273876dd6a7531c889c0db95eacfddb1" ], "index": "pypi", - "version": "==0.3" + "version": "==0.4" }, "django-phonenumber-field": { "extras": [ diff --git a/pythonpro/checkout/templates/django_pagarme/show_boleto_data.html b/pythonpro/checkout/templates/django_pagarme/show_boleto_data.html new file mode 100644 index 00000000..e710411f --- /dev/null +++ b/pythonpro/checkout/templates/django_pagarme/show_boleto_data.html @@ -0,0 +1,21 @@ +{% extends 'core/base_without_nav.html' %} +{% load django_pagarme %} +{% block title %}Dados do Boleto{% endblock %} +{% block description %}Dados de Boleto para Pagamento{% endblock %} +{% block head %} +{% endblock head %} + +{% block body %} +
+
+
+

Dados do Boleto

+

Código de Barras: {{ payment.boleto_barcode }}

+

Abrir em Boleto em Outra Aba

+ +
+
+
+{% endblock body %} + +{% block footer %}{% endblock footer %} \ No newline at end of file diff --git a/pythonpro/core/facade.py b/pythonpro/core/facade.py index 64da9c56..c50dc8f9 100644 --- a/pythonpro/core/facade.py +++ b/pythonpro/core/facade.py @@ -222,3 +222,11 @@ def subscribe_to_waiting_list(user: User, source: str): def is_client(user: User): return has_role(user, 'client') + + +def is_lead(user: User): + return has_role(user, 'lead') + + +def is_member(user: User): + return has_role(user, 'member') diff --git a/pythonpro/domain/checkout_domain.py b/pythonpro/domain/checkout_domain.py index 6cd91aa7..92039b77 100644 --- a/pythonpro/domain/checkout_domain.py +++ b/pythonpro/domain/checkout_domain.py @@ -1,7 +1,9 @@ # Setup django pagarme listener +from celery import shared_task from django_pagarme import facade as django_pagarme_facade from pythonpro.core import facade as core_facade +from pythonpro.domain import user_facade from pythonpro.email_marketing import facade as email_marketing_facade @@ -20,3 +22,34 @@ def contact_info_listener(name, email, phone, payment_item_slug, user=None): django_pagarme_facade.add_contact_info_listener(contact_info_listener) + + +def user_factory(pagarme_transaction): + customer = pagarme_transaction['customer'] + customer_email = customer['email'].lower() + customer_first_name = customer['name'].split()[0] + return user_facade.force_register_lead(customer_first_name, customer_email) + + +django_pagarme_facade.set_user_factory(user_factory) + + +@shared_task() +def payment_handler_task(payment_id): + payment = django_pagarme_facade.find_payment(payment_id) + status = payment.status() + if status == django_pagarme_facade.PAID: + slug = payment.first_item_slug() + if 'pytools' in slug: + user_facade.promote_client(payment.user, 'unknow') + elif 'membership' in slug: + user_facade.promote_member(payment.user, 'unknow') + else: + raise ValueError(f'{slug} should contain pytools or membership') + + +def payment_change_handler(payment_id): + payment_handler_task.delay(payment_id) + + +django_pagarme_facade.add_payment_status_changed(payment_change_handler) diff --git a/pythonpro/domain/tests/test_checkout/conftest.py b/pythonpro/domain/tests/test_checkout/conftest.py index 16fdb522..8b7bf89d 100644 --- a/pythonpro/domain/tests/test_checkout/conftest.py +++ b/pythonpro/domain/tests/test_checkout/conftest.py @@ -1,9 +1,11 @@ from importlib import import_module import pytest +from django_pagarme import facade from django_pagarme.models import PagarmeFormConfig, PagarmeItemConfig # Workaround since module beginning with number can't be imported in regular way + migration_module = import_module('pythonpro.checkout.migrations.0001_payment_setup') @@ -11,3 +13,26 @@ def execute_migration(db, pytestconfig): if pytestconfig.known_args_namespace.nomigrations: migration_module.setup_payment_configs_function(PagarmeFormConfig, PagarmeItemConfig) + + +@pytest.fixture(autouse=True) +def disable_email_marketing(settings): + settings.ACTIVE_CAMPAIGN_TURNED_ON = False + + +@pytest.fixture(autouse=True) +def disable_forum_integration(settings): + settings.DISCOURSE_BASE_URL = '' + settings.DISCOURSE_SSO_SECRET = '' + settings.DISCOURSE_API_KEY = '' + settings.DISCOURSE_API_USER = '' + + +@pytest.fixture +def pytools_item(execute_migration): + return facade.find_payment_item_config('pytools') + + +@pytest.fixture +def membership_item(execute_migration, cohort): + return facade.find_payment_item_config('membership') diff --git a/pythonpro/domain/tests/test_checkout/test_boleto_generation.py b/pythonpro/domain/tests/test_checkout/test_boleto_generation.py new file mode 100644 index 00000000..0d222b84 --- /dev/null +++ b/pythonpro/domain/tests/test_checkout/test_boleto_generation.py @@ -0,0 +1,309 @@ +import pytest +import responses +from django.urls import reverse +from django_pagarme import facade as django_pagarme_facade + +from pythonpro.core import facade as core_facade +from pythonpro.domain import checkout_domain +from pythonpro.email_marketing import facade as email_marketing_facade + + +@pytest.fixture +def pagarme_responses(transaction_json, captura_json): + with responses.RequestsMock() as rsps: + rsps.add(responses.GET, f'https://api.pagar.me/1/transactions/{TOKEN}', json=transaction_json) + rsps.add(responses.POST, f'https://api.pagar.me/1/transactions/{TOKEN}/capture', json=captura_json) + yield rsps + + +TRANSACTION_ID = 7656690 +TOKEN = 'test_transaction_aJx9ibUmRqYcQrrUaNtQ3arTO4tF1z' +BOLETO_URL = 'www.some.boleto.com' +BOLETO_BARCODE = '123455' + + +# test user not logged +@pytest.fixture +def create_or_update_lead_mock(mocker): + return mocker.patch( + 'pythonpro.domain.user_facade._email_marketing_facade.create_or_update_lead.delay', + side_effect=email_marketing_facade.create_or_update_lead + ) + + +@pytest.fixture +def payment_handler_task_mock(mocker): + return mocker.patch( + 'pythonpro.domain.checkout_domain.payment_handler_task.delay', + side_effect=checkout_domain.payment_handler_task + ) + + +@pytest.fixture +def resp(client, pagarme_responses, create_or_update_lead_mock, payment_handler_task_mock): + return client.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_status_code(resp): + assert resp.status_code == 200 + + +def test_user_is_created(resp, django_user_model): + User = django_user_model + assert User.objects.exists() + + +def test_user_is_lead(resp, django_user_model): + User = django_user_model + user = User.objects.first() + assert core_facade.is_lead(user) + + +def test_payment_linked_with_created_user(resp, django_user_model): + User = django_user_model + user = User.objects.first() + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert user == payment.user + + +# Tests user logged + +@pytest.fixture +def resp_logged_user(client_with_lead, pagarme_responses, payment_handler_task_mock): + return client_with_lead.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_logged_user_become_lead(resp_logged_user, logged_user): + assert core_facade.is_lead(logged_user) + + +def test_payment_linked_with_logged_user(resp_logged_user, logged_user): + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert logged_user == payment.user + + +@pytest.fixture +def transaction_json(pytools_item): + return { + 'object': 'transaction', + 'status': 'authorized', + 'refuse_reason': None, + 'status_reason': 'acquirer', + 'acquirer_response_code': None, + 'acquirer_name': 'pagarme', + 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': None, + 'soft_descriptor': None, + 'tid': TRANSACTION_ID, + 'nsu': TRANSACTION_ID, + 'date_created': '2020-03-07T17:04:58.279Z', + 'date_updated': '2020-03-07T17:04:58.502Z', + 'authorized_amount': pytools_item.price, + 'paid_amount': 0, + 'refunded_amount': 0, + 'installments': 1, + 'id': TRANSACTION_ID, + 'cost': 0, + 'card_holder_name': None, + 'card_last_digits': None, + 'card_first_digits': None, + 'card_brand': None, + 'card_pin_mode': None, + 'card_magstripe_fallback': False, + 'cvm_pin': False, + 'postback_url': 'https://e0f89dca.ngrok.io/django_pagarme/notification', + 'payment_method': 'boleto', + 'capture_method': 'ecommerce', + 'antifraud_score': None, + 'boleto_url': None, + 'boleto_barcode': None, + 'boleto_expiration_date': '2020-03-09T03:00:00.000Z', + 'referer': 'encryption_key', + 'ip': '177.170.213.5', + 'subscription_id': None, + 'phone': None, + 'address': None, + 'customer': { + 'object': 'customer', + 'id': 2725813, + 'external_id': 'foo@email.com', + 'type': 'individual', + 'country': 'br', + 'document_number': None, + 'document_type': 'cpf', + 'name': 'Foo', + 'email': 'foo@email.com', + 'phone_numbers': ['+5512999999999'], + 'born_at': None, + 'birthday': None, + 'gender': None, + 'date_created': '2020-03-07T17:04:58.220Z', + 'documents': [ + { + 'object': 'document', + 'id': 'doc_ck7huyv07072mmp6f59af8u8h', + 'type': 'cpf', + 'number': '04367331024' + }] + }, + 'billing': { + 'object': 'billing', + 'id': 1168861, + 'name': 'Foo', + 'address': { + 'object': 'address', + 'street': 'Rua Buenos Aires', + 'complementary': 'Sem complemento', + 'street_number': '7', + 'neighborhood': 'Cidade Vista Verde', + 'city': 'São José dos Campos', + 'state': 'SP', + 'zipcode': '12223730', + 'country': 'br', + 'id': 2641028 + } + }, + 'shipping': None, + 'items': [{ + 'object': 'item', + 'id': f'{pytools_item.slug}', + 'title': f'{pytools_item.name}', + 'unit_price': pytools_item.price, + 'quantity': 1, + 'category': None, + 'tangible': False, + 'venue': None, + 'date': None + }], + 'card': None, + 'split_rules': None, + 'metadata': {}, + 'antifraud_metadata': {}, + 'reference_key': None, + 'device': None, + 'local_transaction_id': None, + 'local_time': None, + 'fraud_covered': False, + 'fraud_reimbursed': None, + 'order_id': None, + 'risk_level': 'unknown', + 'receipt_url': None, + 'payment': None, + 'addition': None, + 'discount': None, + 'private_label': None + } + + +@pytest.fixture +def captura_json(pytools_item): + return { + 'object': 'transaction', + 'status': 'waiting_payment', + 'refuse_reason': None, + 'status_reason': 'acquirer', + 'acquirer_response_code': None, + 'acquirer_name': 'pagarme', + 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': None, + 'soft_descriptor': None, + 'tid': TRANSACTION_ID, + 'nsu': TRANSACTION_ID, + 'date_created': '2020-03-07T17:04:58.279Z', + 'date_updated': '2020-03-07T17:11:14.957Z', + 'amount': pytools_item.price, + 'authorized_amount': pytools_item.price, + 'paid_amount': 0, + 'refunded_amount': 0, + 'installments': 1, + 'id': TRANSACTION_ID, + 'cost': 0, + 'card_holder_name': None, + 'card_last_digits': None, + 'card_first_digits': None, + 'card_brand': None, + 'card_pin_mode': None, + 'card_magstripe_fallback': False, + 'cvm_pin': False, + 'postback_url': 'https://e0f89dca.ngrok.io/django_pagarme/notification', + 'payment_method': 'boleto', + 'capture_method': 'ecommerce', + 'antifraud_score': None, + 'boleto_url': BOLETO_URL, + 'boleto_barcode': BOLETO_BARCODE, + 'boleto_expiration_date': '2020-03-09T03:00:00.000Z', + 'referer': 'encryption_key', + 'ip': '177.170.213.5', + 'subscription_id': None, + 'phone': None, + 'address': None, + 'customer': { + 'object': 'customer', + 'id': 2725813, + 'external_id': 'foo@email.com', + 'type': 'individual', + 'country': 'br', + 'document_number': None, + 'document_type': 'cpf', + 'name': 'Foo', + 'email': 'foo@email.com', + 'phone_numbers': ['+5512999999999'], + 'born_at': None, + 'birthday': None, + 'gender': None, + 'date_created': '2020-03-07T17:04:58.220Z', + 'documents': [ + { + 'object': 'document', + 'id': 'doc_ck7huyv07072mmp6f59af8u8h', + 'type': 'cpf', + 'number': '04367331024' + }] + }, + 'billing': { + 'object': 'billing', + 'id': 1168861, + 'name': 'Foo', + 'address': { + 'object': 'address', + 'street': 'Rua Buenos Aires', + 'complementary': 'Sem complemento', + 'street_number': '7', + 'neighborhood': 'Cidade Vista Verde', + 'city': 'São José dos Campos', + 'state': 'SP', + 'zipcode': '12223730', + 'country': 'br', + 'id': 2641028 + } + }, + 'shipping': None, + 'items': [{ + 'object': 'item', + 'id': f'{pytools_item.slug}', + 'title': f'{pytools_item.name}', + 'unit_price': pytools_item.price, + 'quantity': 1, + 'category': None, + 'tangible': False, + 'venue': None, + 'date': None + }], + 'card': None, + 'split_rules': None, + 'metadata': {}, + 'antifraud_metadata': {}, + 'reference_key': None, + 'device': None, + 'local_transaction_id': None, + 'local_time': None, + 'fraud_covered': False, + 'fraud_reimbursed': None, + 'order_id': None, + 'risk_level': 'unknown', + 'receipt_url': None, + 'payment': None, + 'addition': None, + 'discount': None, + 'private_label': None + } diff --git a/pythonpro/domain/tests/test_checkout/test_credit_card_payment_client.py b/pythonpro/domain/tests/test_checkout/test_credit_card_payment_client.py new file mode 100644 index 00000000..dca9b92b --- /dev/null +++ b/pythonpro/domain/tests/test_checkout/test_credit_card_payment_client.py @@ -0,0 +1,170 @@ +import pytest +import responses +from django.urls import reverse +from django_pagarme import facade as django_pagarme_facade + +from pythonpro.core import facade as core_facade +from pythonpro.domain import checkout_domain +from pythonpro.email_marketing import facade as email_marketing_facade + + +@pytest.fixture +def pagarme_responses(transaction_json, captura_json): + with responses.RequestsMock() as rsps: + rsps.add(responses.GET, f'https://api.pagar.me/1/transactions/{TOKEN}', json=transaction_json) + rsps.add(responses.POST, f'https://api.pagar.me/1/transactions/{TOKEN}/capture', json=captura_json) + yield rsps + + +TRANSACTION_ID = 7656690 +TOKEN = 'test_transaction_aJx9ibUmRqYcQrrUaNtQ3arTO4tF1z' + + +@pytest.fixture +def create_or_update_client_mock(mocker): + return mocker.patch( + 'pythonpro.domain.user_facade._email_marketing_facade.create_or_update_client.delay', + side_effect=email_marketing_facade.create_or_update_client + ) + + +@pytest.fixture +def create_or_update_lead_mock(mocker): + return mocker.patch( + 'pythonpro.domain.user_facade._email_marketing_facade.create_or_update_lead.delay', + side_effect=email_marketing_facade.create_or_update_lead + ) + + +@pytest.fixture +def payment_handler_task_mock(mocker): + return mocker.patch( + 'pythonpro.domain.checkout_domain.payment_handler_task.delay', + side_effect=checkout_domain.payment_handler_task + ) + + +# test user not logged +@pytest.fixture +def resp(client, pagarme_responses, payment_handler_task_mock, create_or_update_client_mock, + create_or_update_lead_mock): + return client.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_status_code(resp, pytools_item, payment_handler_task_mock, create_or_update_client_mock): + assert resp.status_code == 302 + assert resp.url == reverse('django_pagarme:thanks', kwargs={'slug': pytools_item.slug}) + + +def test_user_is_created(resp, django_user_model): + User = django_user_model + assert User.objects.exists() + + +def test_user_is_client(resp, django_user_model): + User = django_user_model + user = User.objects.first() + assert core_facade.is_client(user) + + +def test_payment_linked_with_created_user(resp, django_user_model): + User = django_user_model + user = User.objects.first() + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert user == payment.user + + +# Tests user logged + +@pytest.fixture +def resp_logged_user(client_with_user, pagarme_responses, payment_handler_task_mock): + return client_with_user.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_logged_user_become_client(resp_logged_user, logged_user): + assert core_facade.is_client(logged_user) + + +def test_payment_linked_with_logged_user(resp_logged_user, logged_user): + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert logged_user == payment.user + + +@pytest.fixture +def transaction_json(pytools_item): + return { + 'object': 'transaction', 'status': 'authorized', 'refuse_reason': None, 'status_reason': 'antifraud', + 'acquirer_response_code': '0000', 'acquirer_name': 'pagarme', 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': '727706', 'soft_descriptor': None, 'tid': TRANSACTION_ID, 'nsu': TRANSACTION_ID, + 'date_created': '2020-01-21T01:10:13.015Z', 'date_updated': '2020-01-21T01:10:13.339Z', + 'amount': pytools_item.price, + 'authorized_amount': pytools_item.price, 'paid_amount': 0, 'refunded_amount': 0, 'installments': 1, + 'id': TRANSACTION_ID, 'cost': 70, + 'card_holder_name': 'Bar Baz', 'card_last_digits': '1111', 'card_first_digits': '411111', 'card_brand': 'visa', + 'card_pin_mode': None, 'card_magstripe_fallback': False, 'cvm_pin': False, 'postback_url': None, + 'payment_method': 'credit_card', 'capture_method': 'ecommerce', 'antifraud_score': None, 'boleto_url': None, + 'boleto_barcode': None, 'boleto_expiration_date': None, 'referer': 'encryption_key', 'ip': '177.27.238.139', + 'items': [{ + 'object': 'item', + 'id': f'{pytools_item.slug}', + 'title': f'{pytools_item.name}', + 'unit_price': pytools_item.price, + 'quantity': 1, 'category': None, 'tangible': False, 'venue': None, 'date': None + }], 'card': { + 'object': 'card', 'id': 'card_ck5n7vtbi010or36dojq96sb1', 'date_created': '2020-01-21T01:45:57.294Z', + 'date_updated': '2020-01-21T01:45:57.789Z', 'brand': 'visa', 'holder_name': 'agora captura', + 'first_digits': '411111', 'last_digits': '1111', 'country': 'UNITED STATES', + 'fingerprint': 'cj5bw4cio00000j23jx5l60cq', 'valid': True, 'expiration_date': '1227' + } + } + + +@pytest.fixture +def captura_json(pytools_item): + return { + 'object': 'transaction', 'status': 'paid', 'refuse_reason': None, 'status_reason': 'acquirer', + 'acquirer_response_code': '0000', 'acquirer_name': 'pagarme', 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': '408324', 'soft_descriptor': None, 'tid': TRANSACTION_ID, 'nsu': TRANSACTION_ID, + 'date_created': '2020-01-21T01:45:57.309Z', 'date_updated': '2020-01-21T01:47:27.105Z', 'amount': 8000, + 'authorized_amount': pytools_item.price, + 'paid_amount': pytools_item.price, 'refunded_amount': 0, + 'installments': 1, + 'id': TRANSACTION_ID, + 'cost': 100, + 'card_holder_name': 'agora captura', 'card_last_digits': '1111', 'card_first_digits': '411111', + 'card_brand': 'visa', 'card_pin_mode': None, 'card_magstripe_fallback': False, 'cvm_pin': False, + 'postback_url': None, + 'payment_method': 'credit_card', 'capture_method': 'ecommerce', 'antifraud_score': None, + 'boleto_url': None, 'boleto_barcode': None, 'boleto_expiration_date': None, 'referer': 'encryption_key', + 'ip': '177.27.238.139', 'subscription_id': None, 'phone': None, 'address': None, + 'customer': { + 'object': 'customer', 'id': 2601905, 'external_id': 'captura@gmail.com', 'type': 'individual', + 'country': 'br', + 'document_number': None, 'document_type': 'cpf', 'name': 'Agora Captura', 'email': 'captura@gmail.com', + 'phone_numbers': ['+5512997411854'], 'born_at': None, 'birthday': None, 'gender': None, + 'date_created': '2020-01-21T01:45:57.228Z', 'documents': [ + {'object': 'document', 'id': 'doc_ck5n7vta0010nr36d01k1zzzw', 'type': 'cpf', 'number': '29770166863'}] + }, 'billing': { + 'object': 'billing', 'id': 1135539, 'name': 'Agora Captura', 'address': { + 'object': 'address', 'street': 'Rua Bahamas', 'complementary': 'Sem complemento', 'street_number': '56', + 'neighborhood': 'Cidade Vista Verde', 'city': 'São José dos Campos', 'state': 'SP', + 'zipcode': '12223770', + 'country': 'br', 'id': 2559019 + } + }, 'shipping': None, + 'items': [{ + 'object': 'item', + 'id': f'{pytools_item.slug}', + 'title': f'{pytools_item.name}', + 'unit_price': pytools_item.price, + 'quantity': 1, 'category': None, 'tangible': False, 'venue': None, 'date': None + }], 'card': { + 'object': 'card', 'id': 'card_ck5n7vtbi010or36dojq96sb1', 'date_created': '2020-01-21T01:45:57.294Z', + 'date_updated': '2020-01-21T01:45:57.789Z', 'brand': 'visa', 'holder_name': 'agora captura', + 'first_digits': '411111', 'last_digits': '1111', 'country': 'UNITED STATES', + 'fingerprint': 'cj5bw4cio00000j23jx5l60cq', 'valid': True, 'expiration_date': '1227' + }, 'split_rules': None, 'metadata': {}, 'antifraud_metadata': {}, 'reference_key': None, 'device': None, + 'local_transaction_id': None, 'local_time': None, 'fraud_covered': False, 'fraud_reimbursed': None, + 'order_id': None, 'risk_level': 'very_low', 'receipt_url': None, 'payment': None, 'addition': None, + 'discount': None, 'private_label': None + } diff --git a/pythonpro/domain/tests/test_checkout/test_credit_card_payment_member.py b/pythonpro/domain/tests/test_checkout/test_credit_card_payment_member.py new file mode 100644 index 00000000..22761237 --- /dev/null +++ b/pythonpro/domain/tests/test_checkout/test_credit_card_payment_member.py @@ -0,0 +1,181 @@ +import pytest +import responses +from django.urls import reverse +from django_pagarme import facade as django_pagarme_facade + +from pythonpro.core import facade as core_facade +from pythonpro.domain import checkout_domain +from pythonpro.email_marketing import facade as email_marketing_facade + + +@pytest.fixture +def pagarme_responses(transaction_json, captura_json): + with responses.RequestsMock() as rsps: + rsps.add(responses.GET, f'https://api.pagar.me/1/transactions/{TOKEN}', json=transaction_json) + rsps.add(responses.POST, f'https://api.pagar.me/1/transactions/{TOKEN}/capture', json=captura_json) + yield rsps + + +TRANSACTION_ID = 7656690 +TOKEN = 'test_transaction_aJx9ibUmRqYcQrrUaNtQ3arTO4tF1z' + + +@pytest.fixture +def create_or_update_member_mock(mocker): + return mocker.patch( + 'pythonpro.domain.user_facade._email_marketing_facade.create_or_update_member.delay', + side_effect=email_marketing_facade.create_or_update_member + ) + + +@pytest.fixture +def create_or_update_lead_mock(mocker): + return mocker.patch( + 'pythonpro.domain.user_facade._email_marketing_facade.create_or_update_lead.delay', + side_effect=email_marketing_facade.create_or_update_lead + ) + + +@pytest.fixture +def payment_handler_task_mock(mocker): + return mocker.patch( + 'pythonpro.domain.checkout_domain.payment_handler_task.delay', + side_effect=checkout_domain.payment_handler_task + ) + + +# test user not logged + +@pytest.fixture +def resp(client, pagarme_responses, payment_handler_task_mock, create_or_update_lead_mock, + create_or_update_member_mock): + return client.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_status_code(resp, membership_item): + assert resp.status_code == 302 + assert resp.url == reverse('django_pagarme:thanks', kwargs={'slug': membership_item.slug}) + + +def test_user_is_created(resp, django_user_model): + User = django_user_model + assert User.objects.exists() + + +def test_user_is_member(resp, django_user_model): + User = django_user_model + user = User.objects.first() + assert core_facade.is_member(user) + + +def test_user_is_subscribed_to_cohort(resp, django_user_model, cohort): + User = django_user_model + user = User.objects.first() + assert cohort.students.first() == user + + +def test_payment_linked_with_created_user(resp, django_user_model): + User = django_user_model + user = User.objects.first() + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert user == payment.user + + +# Tests user logged + +@pytest.fixture +def resp_logged_user(client_with_user, pagarme_responses, payment_handler_task_mock): + return client_with_user.get(reverse('django_pagarme:capture', kwargs={'token': TOKEN}), secure=True) + + +def test_logged_user_become_member(resp_logged_user, logged_user): + assert core_facade.is_member(logged_user) + + +def test_payment_linked_with_logged_user(resp_logged_user, logged_user): + payment = django_pagarme_facade.find_payment_by_transaction(TRANSACTION_ID) + assert logged_user == payment.user + + +def test_logged_user_is_subscribed_to_cohort(resp_logged_user, logged_user, cohort): + assert cohort.students.first() == logged_user + + +@pytest.fixture +def transaction_json(membership_item): + return { + 'object': 'transaction', 'status': 'authorized', 'refuse_reason': None, 'status_reason': 'antifraud', + 'acquirer_response_code': '0000', 'acquirer_name': 'pagarme', 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': '727706', 'soft_descriptor': None, 'tid': TRANSACTION_ID, 'nsu': TRANSACTION_ID, + 'date_created': '2020-01-21T01:10:13.015Z', 'date_updated': '2020-01-21T01:10:13.339Z', + 'amount': membership_item.price, + 'authorized_amount': membership_item.price, 'paid_amount': 0, 'refunded_amount': 0, 'installments': 1, + 'id': TRANSACTION_ID, 'cost': 70, + 'card_holder_name': 'Bar Baz', 'card_last_digits': '1111', 'card_first_digits': '411111', 'card_brand': 'visa', + 'card_pin_mode': None, 'card_magstripe_fallback': False, 'cvm_pin': False, 'postback_url': None, + 'payment_method': 'credit_card', 'capture_method': 'ecommerce', 'antifraud_score': None, 'boleto_url': None, + 'boleto_barcode': None, 'boleto_expiration_date': None, 'referer': 'encryption_key', 'ip': '177.27.238.139', + 'items': [{ + 'object': 'item', + 'id': f'{membership_item.slug}', + 'title': f'{membership_item.name}', + 'unit_price': membership_item.price, + 'quantity': 1, 'category': None, 'tangible': False, 'venue': None, 'date': None + }], 'card': { + 'object': 'card', 'id': 'card_ck5n7vtbi010or36dojq96sb1', 'date_created': '2020-01-21T01:45:57.294Z', + 'date_updated': '2020-01-21T01:45:57.789Z', 'brand': 'visa', 'holder_name': 'agora captura', + 'first_digits': '411111', 'last_digits': '1111', 'country': 'UNITED STATES', + 'fingerprint': 'cj5bw4cio00000j23jx5l60cq', 'valid': True, 'expiration_date': '1227' + } + } + + +@pytest.fixture +def captura_json(membership_item): + return { + 'object': 'transaction', 'status': 'paid', 'refuse_reason': None, 'status_reason': 'acquirer', + 'acquirer_response_code': '0000', 'acquirer_name': 'pagarme', 'acquirer_id': '5cdec7071458b442125d940b', + 'authorization_code': '408324', 'soft_descriptor': None, 'tid': TRANSACTION_ID, 'nsu': TRANSACTION_ID, + 'date_created': '2020-01-21T01:45:57.309Z', 'date_updated': '2020-01-21T01:47:27.105Z', 'amount': 8000, + 'authorized_amount': membership_item.price, + 'paid_amount': membership_item.price, 'refunded_amount': 0, + 'installments': 1, + 'id': TRANSACTION_ID, + 'cost': 100, + 'card_holder_name': 'agora captura', 'card_last_digits': '1111', 'card_first_digits': '411111', + 'card_brand': 'visa', 'card_pin_mode': None, 'card_magstripe_fallback': False, 'cvm_pin': False, + 'postback_url': None, + 'payment_method': 'credit_card', 'capture_method': 'ecommerce', 'antifraud_score': None, + 'boleto_url': None, 'boleto_barcode': None, 'boleto_expiration_date': None, 'referer': 'encryption_key', + 'ip': '177.27.238.139', 'subscription_id': None, 'phone': None, 'address': None, + 'customer': { + 'object': 'customer', 'id': 2601905, 'external_id': 'captura@gmail.com', 'type': 'individual', + 'country': 'br', + 'document_number': None, 'document_type': 'cpf', 'name': 'Agora Captura', 'email': 'captura@gmail.com', + 'phone_numbers': ['+5512997411854'], 'born_at': None, 'birthday': None, 'gender': None, + 'date_created': '2020-01-21T01:45:57.228Z', 'documents': [ + {'object': 'document', 'id': 'doc_ck5n7vta0010nr36d01k1zzzw', 'type': 'cpf', 'number': '29770166863'}] + }, 'billing': { + 'object': 'billing', 'id': 1135539, 'name': 'Agora Captura', 'address': { + 'object': 'address', 'street': 'Rua Bahamas', 'complementary': 'Sem complemento', 'street_number': '56', + 'neighborhood': 'Cidade Vista Verde', 'city': 'São José dos Campos', 'state': 'SP', + 'zipcode': '12223770', + 'country': 'br', 'id': 2559019 + } + }, 'shipping': None, + 'items': [{ + 'object': 'item', + 'id': f'{membership_item.slug}', + 'title': f'{membership_item.name}', + 'unit_price': membership_item.price, + 'quantity': 1, 'category': None, 'tangible': False, 'venue': None, 'date': None + }], 'card': { + 'object': 'card', 'id': 'card_ck5n7vtbi010or36dojq96sb1', 'date_created': '2020-01-21T01:45:57.294Z', + 'date_updated': '2020-01-21T01:45:57.789Z', 'brand': 'visa', 'holder_name': 'agora captura', + 'first_digits': '411111', 'last_digits': '1111', 'country': 'UNITED STATES', + 'fingerprint': 'cj5bw4cio00000j23jx5l60cq', 'valid': True, 'expiration_date': '1227' + }, 'split_rules': None, 'metadata': {}, 'antifraud_metadata': {}, 'reference_key': None, 'device': None, + 'local_transaction_id': None, 'local_time': None, 'fraud_covered': False, 'fraud_reimbursed': None, + 'order_id': None, 'risk_level': 'very_low', 'receipt_url': None, 'payment': None, 'addition': None, + 'discount': None, 'private_label': None + } diff --git a/pythonpro/email_marketing/facade.py b/pythonpro/email_marketing/facade.py index a74d7ff4..760b21c2 100644 --- a/pythonpro/email_marketing/facade.py +++ b/pythonpro/email_marketing/facade.py @@ -110,6 +110,7 @@ def grant_role(email, id, role: str): _client.contacts.remove_tag(roles_to_remove_data) +@shared_task() def tag_as(email: str, id: int, *tags): if settings.ACTIVE_CAMPAIGN_TURNED_ON is False: return