Skip to content

Commit 5d53f14

Browse files
renzonrenzon
authored andcommitted
Solved anonymous access for credit card and LP
close #1316
1 parent e7f8fe2 commit 5d53f14

9 files changed

Lines changed: 114 additions & 18 deletions

File tree

‎pythonpro/core/forms.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Meta:
4545
help_text=_("Enter the same password as before, for verification."),
4646
)
4747

48-
def save(self, commit=True, source=None):
48+
def save(self, commit=True, source='unknown'):
4949
user = super().save(commit=False)
5050
user.set_password(User.objects.make_random_password(30))
5151
user.source = source

‎pythonpro/core/views.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from django.urls import reverse, reverse_lazy
88
from django.views.generic import TemplateView, UpdateView
99
from django_sitemaps import Sitemap
10+
from mailchimp3.mailchimpclient import MailChimpError
1011
from rolepermissions.checkers import has_role
1112
from rolepermissions.roles import assign_role
1213

@@ -126,11 +127,15 @@ def lead_form(request):
126127
form = UserSignupForm()
127128
return render(request, 'core/lead_form_errors.html', context={'form': form})
128129
form = UserSignupForm(request.POST)
130+
source = request.GET.get('utm_source', default='unknown')
129131
if form.is_valid():
130-
source = request.GET.get('utm_source', default='unknown')
132+
try:
133+
facade.create_or_update_lead(form.cleaned_data['first_name'], form.cleaned_data['email'])
134+
except MailChimpError:
135+
form.add_error('email', 'Email Inválido')
136+
return render(request, 'core/lead_form_errors.html', context={'form': form})
131137
user = form.save(source=source)
132138
assign_role(user, 'lead')
133-
facade.create_or_update_lead(user.first_name, user.email)
134139
login(request, user)
135140
return redirect(reverse('core:lead_change_password'))
136141
return render(request, 'core/lead_form_errors.html', context={'form': form})

‎pythonpro/modules/tests/test_topics_view.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def resp_lead_accesing_client_content(client_with_lead, topic_client, django_use
202202

203203
def test_lead_hitting_client_landing_page(resp_lead_accesing_client_content):
204204
assert resp_lead_accesing_client_content.status_code == 302
205-
assert resp_lead_accesing_client_content.url == reverse('payments:client_landing_page')
205+
assert resp_lead_accesing_client_content.url == reverse('client_landing_page')
206206

207207

208208
@pytest.fixture

‎pythonpro/modules/topics_views.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
def content_landing_page(request, content: Content):
1212
if is_client_content(content):
13-
redirect_path = reverse('payments:client_landing_page')
13+
redirect_path = reverse('client_landing_page')
1414
else:
1515
redirect_path = reverse('payments:member_landing_page')
1616
return redirect(redirect_path, permanent=False)

‎pythonpro/payments/tests/test_landing_pages.py‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55
@pytest.fixture
66
def client_lp_resp(client_with_lead, mocker, logged_user):
77
tag_as = mocker.patch('pythonpro.payments.views.tag_as')
8-
yield client_with_lead.get(reverse('payments:client_landing_page'), secure=True)
8+
yield client_with_lead.get(reverse('client_landing_page'), secure=True)
99
tag_as.assert_called_once_with(logged_user.email, 'potential-client')
1010

1111

12-
def test_non_logged_status_code(client_lp_resp):
12+
@pytest.fixture
13+
def anonymous_client_lp_resp(client, mocker):
14+
tag_as = mocker.patch('pythonpro.payments.views.tag_as')
15+
yield client.get(reverse('client_landing_page'), secure=True)
16+
assert tag_as.call_count == 0
17+
18+
19+
def test_logged_status_code(client_lp_resp):
1320
assert client_lp_resp.status_code == 200
1421

1522

23+
def test_anonymous_access_status_code(anonymous_client_lp_resp):
24+
assert anonymous_client_lp_resp.status_code == 200
25+
26+
1627
@pytest.fixture
1728
def client_checkout_click_resp(client_with_lead, mocker, logged_user):
1829
tag_as = mocker.patch('pythonpro.payments.views.tag_as')

‎pythonpro/payments/tests/test_pagarme_credit_card.py‎

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
transaction_url = 'https://api.pagar.me/1/transactions/test_transaction_5ndnWcHEJQX1FPCbEpQpFng90gM5oM/capture'
77
transaction_data = {'amount': 9999, 'api_key': 'ak_test_6yd4kbaJrWzdn61m4De5yzn7jZuTt9'}
88

9+
CUSTOMER_EMAIL = 'renzon@gmail.com'
10+
CUSTOMER_FIRST_NAME = 'Renzo'
911
transaction_response = {
1012
'object': 'transaction',
1113
'status': 'paid',
@@ -48,13 +50,13 @@
4850
'customer': {
4951
'object': 'customer',
5052
'id': 2082255,
51-
'external_id': 'renzon@gmail.com',
53+
'external_id': CUSTOMER_EMAIL,
5254
'type': 'individual',
5355
'country': 'br',
5456
'document_number': None,
5557
'document_type': 'cpf',
56-
'name': 'Renzo dos Santos Nuccitelli',
57-
'email': 'renzon@gmail.com',
58+
'name': f'{CUSTOMER_FIRST_NAME} dos Santos Nuccitelli',
59+
'email': CUSTOMER_EMAIL,
5860
'phone_numbers': ['+5512997411854'],
5961
'born_at': None,
6062
'birthday': None,
@@ -138,17 +140,28 @@
138140

139141

140142
@pytest.fixture
141-
def create_or_update_client(client_with_lead, logged_user, mocker):
143+
def create_or_update_client(mocker):
142144
return mocker.patch('pythonpro.payments.views.mailchimp_facade.create_or_update_client')
143145

144146

147+
@pytest.fixture
148+
def create_or_update_lead(mocker):
149+
return mocker.patch('pythonpro.payments.views.mailchimp_facade.create_or_update_lead')
150+
151+
145152
@pytest.fixture
146153
def resps_success():
147154
with responses.RequestsMock(assert_all_requests_are_fired=False) as r:
148155
r.add(r.POST, transaction_url, json=transaction_response, status=200)
149156
yield r
150157

151158

159+
@pytest.fixture
160+
def resp_token_with_no_user(db, client, create_or_update_client, create_or_update_lead, resps_success):
161+
data = {'token': 'test_transaction_5ndnWcHEJQX1FPCbEpQpFng90gM5oM', 'payment_method': 'credit_card'}
162+
return client.post(reverse('payments:pytools_capture'), data, secure=True)
163+
164+
152165
@pytest.fixture
153166
def resp_token(client_with_lead, logged_user, create_or_update_client, resps_success):
154167
data = {'token': 'test_transaction_5ndnWcHEJQX1FPCbEpQpFng90gM5oM', 'payment_method': 'credit_card'}
@@ -170,3 +183,22 @@ def test_redirect_url(resp_token):
170183

171184
def test_ty_status_code(client):
172185
assert client.get(reverse('payments:pytools_thanks'), secure=True).status_code == 200
186+
187+
188+
def test_user_creation(resp_token_with_no_user, django_user_model):
189+
user = django_user_model.objects.get(email=CUSTOMER_EMAIL)
190+
assert has_role(user, 'client')
191+
assert not has_role(user, 'lead')
192+
193+
194+
def test_user_name(resp_token_with_no_user, django_user_model):
195+
user = django_user_model.objects.get(email=CUSTOMER_EMAIL)
196+
assert user.first_name == CUSTOMER_FIRST_NAME
197+
198+
199+
def test_client_update_on_mail_chimp(resp_token_with_no_user, django_user_model, create_or_update_client):
200+
create_or_update_client.assert_called_once_with(CUSTOMER_FIRST_NAME, CUSTOMER_EMAIL)
201+
202+
203+
def test_client_lead_not_created_on_mailchimp(resp_token_with_no_user, django_user_model, create_or_update_lead):
204+
assert create_or_update_lead.call_count == 0

‎pythonpro/payments/urls.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
path('pytools/obrigado/', views.pytools_thanks, name='pytools_thanks'),
1313
path('pytools/captura/', views.pytools_capture, name='pytools_capture'),
1414
path('pytools/boleto/', views.pytools_boleto, name='pytools_boleto'),
15-
path('curso-de-python-intermediario', views.client_landing_page, name='client_landing_page'),
1615
path('pargarme/notificacao/<int:user_id>', views.pagarme_notification, name='pagarme_notification'),
16+
path('pargarme/notificacao', views.pagarme_anonymous_notification, name='pagarme_anonymous_notification'),
1717
]

‎pythonpro/payments/views.py‎

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
from django.template.loader import render_to_string
1010
from django.urls import reverse
1111
from django.views.decorators.csrf import csrf_exempt
12+
from mailchimp3.mailchimpclient import MailChimpError
1213
from rolepermissions.roles import assign_role, remove_role
1314

15+
from pythonpro.core.forms import UserSignupForm
1416
from pythonpro.mailchimp import facade as mailchimp_facade
1517
from pythonpro.mailchimp.facade import tag_as
1618
from pythonpro.payments import facade as payment_facade
@@ -26,14 +28,26 @@ def thanks(request):
2628
return render(request, 'payments/thanks.html')
2729

2830

29-
@login_required
3031
@csrf_exempt
3132
def pytools_capture(request):
3233
if request.method != 'POST':
3334
return
3435
pagarme_resp = payment_facade.pytools_capture(request.POST['token'])
36+
user = request.user
37+
if not user.is_authenticated:
38+
customer = pagarme_resp['customer']
39+
first_name = customer['name'].split()[0]
40+
form = UserSignupForm({'first_name': first_name, 'email': customer['email']})
41+
source = request.GET.get('utm_source', default='unknown')
42+
user = form.save(source=source)
43+
if not pagarme_resp['payment_method'] == 'credit_card':
44+
assign_role(user, 'lead')
45+
try:
46+
mailchimp_facade.create_or_update_lead(form.first_name, form.email)
47+
except MailChimpError:
48+
pass
49+
3550
if pagarme_resp['payment_method'] == 'credit_card':
36-
user = request.user
3751
_promote_client(user)
3852
dct = {'redirect_url': reverse('payments:pytools_thanks')}
3953
elif pagarme_resp['payment_method'] == 'boleto':
@@ -60,7 +74,10 @@ def client_checkout(request):
6074
def _promote_client(user):
6175
remove_role(user, 'lead')
6276
assign_role(user, 'client')
63-
mailchimp_facade.create_or_update_client(user.first_name, user.email)
77+
try:
78+
mailchimp_facade.create_or_update_client(user.first_name, user.email)
79+
except MailChimpError:
80+
pass
6481

6582

6683
def pytools_thanks(request):
@@ -77,10 +94,13 @@ def _extract_boleto_params(dct):
7794
return {k: dct[k] for k in ['boleto_barcode', 'boleto_url']}
7895

7996

80-
@login_required
8197
def client_landing_page(request):
82-
tag_as(request.user.email, 'potential-client')
83-
notification_url = reverse('payments:pagarme_notification', kwargs={'user_id': request.user.id})
98+
user = request.user
99+
if user.is_authenticated:
100+
tag_as(user.email, 'potential-client')
101+
notification_url = reverse('payments:pagarme_notification', kwargs={'user_id': user.id})
102+
else:
103+
notification_url = reverse('payments:pagarme_anonymous_notification')
84104
return render(
85105
request,
86106
'payments/client_landing_page.html', {
@@ -129,3 +149,29 @@ def pagarme_notification(request, user_id: int):
129149
[user.email]
130150
)
131151
return HttpResponse('')
152+
153+
154+
@csrf_exempt
155+
def pagarme_anonymous_notification(request):
156+
if request.method != 'POST':
157+
return HttpResponseNotAllowed([request.method])
158+
user_id = 0
159+
paymento_ok = payment_facade.confirm_boleto_payment(
160+
user_id, request.POST, request.body.decode('utf8'), request.headers['X-Hub-Signature'])
161+
if paymento_ok:
162+
user = get_user_model().objects.get(id=user_id)
163+
_promote_client(user)
164+
msg = render_to_string(
165+
'payments/pytools_email.txt',
166+
{
167+
'user': user,
168+
'ty_url': request.build_absolute_uri(reverse('payments:pytools_thanks'))
169+
}
170+
)
171+
send_mail(
172+
'Inscrição no curso Pytool realizada! Confira o link com detalhes.',
173+
msg,
174+
settings.DEFAULT_FROM_EMAIL,
175+
[user.email]
176+
)
177+
return HttpResponse('')

‎pythonpro/urls.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
PasswordResetView
2323
)
2424
from django.urls import include, path
25+
from pythonpro.payments import views as payments_views
2526

2627
urlpatterns = [
2728
path('admin/', admin.site.urls),
@@ -42,6 +43,7 @@
4243
path('turmas/', include('pythonpro.cohorts.urls')),
4344
path('dashboard/', include('pythonpro.dashboard.urls')),
4445
path('', include('pythonpro.core.urls')),
46+
path('curso-de-python-intermediario', payments_views.client_landing_page, name='client_landing_page'),
4547

4648
]
4749

0 commit comments

Comments
 (0)