diff --git a/pythonpro/cohorts/templates/cohorts/live_class_landing_page.html b/pythonpro/cohorts/templates/cohorts/live_class_landing_page.html deleted file mode 100644 index 25aa83c4..00000000 --- a/pythonpro/cohorts/templates/cohorts/live_class_landing_page.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Inscrição Curso Python Pro{% endblock %} - -{% block body %} -
-
-
-

Gravação de aula ao vivo Exclusivo para Membros

-

Explicar aqui

-
-
-
- -{% endblock body %} diff --git a/pythonpro/cohorts/templates/cohorts/webinar_landing_page.html b/pythonpro/cohorts/templates/cohorts/webinar_landing_page.html deleted file mode 100644 index 1eff7cd9..00000000 --- a/pythonpro/cohorts/templates/cohorts/webinar_landing_page.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Inscrição Curso Python Pro{% endblock %} - -{% block body %} -
-
-
-

Webinário Exclusivo para Membros

-

Explicar aqui

-
-
-
- -{% endblock body %} diff --git a/pythonpro/cohorts/tests/test_live_class_detail.py b/pythonpro/cohorts/tests/test_live_class_detail.py index 3864cf86..63cdfdfa 100644 --- a/pythonpro/cohorts/tests/test_live_class_detail.py +++ b/pythonpro/cohorts/tests/test_live_class_detail.py @@ -5,7 +5,7 @@ from model_mommy import mommy from pythonpro.cohorts.models import Cohort, LiveClass -from pythonpro.django_assertions import dj_assert_contains, dj_assert_template_used +from pythonpro.django_assertions import dj_assert_contains @pytest.fixture @@ -45,24 +45,22 @@ def test_cohort_title(cohort, resp): @pytest.fixture def resp_client(client_with_client, live_class: LiveClass, mocker, logged_user): - tag_as = mocker.patch('pythonpro.cohorts.views.tag_as') - yield client_with_client.get(reverse('cohorts:live_class', kwargs={'pk': live_class.id}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') + return client_with_client.get(reverse('cohorts:live_class', kwargs={'pk': live_class.id}), secure=True) def test_live_class_landing_for_client(cohort, resp_client): - dj_assert_template_used(resp_client, 'cohorts/live_class_landing_page.html') + assert resp_client.status_code == 302 + assert resp_client.url == reverse('payments:member_landing_page') @pytest.fixture def resp_lead(client_with_lead, live_class: LiveClass, mocker, logged_user): - tag_as = mocker.patch('pythonpro.cohorts.views.tag_as') - yield client_with_lead.get(reverse('cohorts:live_class', kwargs={'pk': live_class.id}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') + return client_with_lead.get(reverse('cohorts:live_class', kwargs={'pk': live_class.id}), secure=True) def test_live_class_landing_for_lead(cohort, resp_lead): - dj_assert_template_used(resp_lead, 'cohorts/live_class_landing_page.html') + assert resp_lead.status_code == 302 + assert resp_lead.url == reverse('payments:member_landing_page') def test_cohort_url(cohort: Cohort, resp): diff --git a/pythonpro/cohorts/tests/test_webinar_detail.py b/pythonpro/cohorts/tests/test_webinar_detail.py index fcccf4bc..170fdf31 100644 --- a/pythonpro/cohorts/tests/test_webinar_detail.py +++ b/pythonpro/cohorts/tests/test_webinar_detail.py @@ -5,7 +5,7 @@ from pythonpro.cohorts.models import Webinar from pythonpro.cohorts.tests.conftest import img_path -from pythonpro.django_assertions import dj_assert_contains, dj_assert_template_used +from pythonpro.django_assertions import dj_assert_contains @pytest.fixture @@ -36,21 +36,19 @@ def test_basic_contents(resp, webinar, property_name): @pytest.fixture def resp_client(client_with_client, webinar: Webinar, mocker, logged_user): - tag_as = mocker.patch('pythonpro.cohorts.views.tag_as') - yield client_with_client.get(reverse('cohorts:webinar', kwargs={'slug': webinar.slug}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') + return client_with_client.get(reverse('cohorts:webinar', kwargs={'slug': webinar.slug}), secure=True) def test_webinar_landing_for_client(cohort, resp_client): - dj_assert_template_used(resp_client, 'cohorts/webinar_landing_page.html') + assert resp_client.status_code == 302 + assert resp_client.url == reverse('payments:member_landing_page') @pytest.fixture def resp_lead(client_with_lead, webinar: Webinar, mocker, logged_user): - tag_as = mocker.patch('pythonpro.cohorts.views.tag_as') - yield client_with_lead.get(reverse('cohorts:webinar', kwargs={'slug': webinar.slug}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') + return client_with_lead.get(reverse('cohorts:webinar', kwargs={'slug': webinar.slug}), secure=True) def test_webinar_landing_for_lead(cohort, resp_lead): - dj_assert_template_used(resp_lead, 'cohorts/webinar_landing_page.html') + assert resp_lead.status_code == 302 + assert resp_lead.url == reverse('payments:member_landing_page') diff --git a/pythonpro/cohorts/views.py b/pythonpro/cohorts/views.py index 0bf7e8f2..b8d8d16b 100644 --- a/pythonpro/cohorts/views.py +++ b/pythonpro/cohorts/views.py @@ -1,10 +1,10 @@ from django.contrib.auth.decorators import login_required -from django.shortcuts import render +from django.shortcuts import redirect, render +from django.urls import reverse from rolepermissions.checkers import has_permission from pythonpro.cohorts import facade from pythonpro.core.roles import access_cohorts -from pythonpro.mailchimp.facade import tag_as @login_required @@ -20,14 +20,12 @@ def webinars(request): @login_required def webinar(request, slug): if not has_permission(request.user, access_cohorts): - tag_as(request.user.email, 'potencial-member') - return render(request, 'cohorts/webinar_landing_page.html') + return redirect(reverse('payments:member_landing_page'), permanent=False) return render(request, 'cohorts/webinar_detail.html', {'webinar': facade.find_webinar(slug=slug)}) @login_required def live_class(request, pk): if not has_permission(request.user, access_cohorts): - tag_as(request.user.email, 'potencial-member') - return render(request, 'cohorts/live_class_landing_page.html') + return redirect(reverse('payments:member_landing_page'), permanent=False) return render(request, 'cohorts/live_class_detail.html', {'live_class': facade.find_live_class(pk=pk)}) diff --git a/pythonpro/core/templates/core/lead_thanks.html b/pythonpro/core/templates/core/lead_thanks.html index 525587a0..f6e24d31 100644 --- a/pythonpro/core/templates/core/lead_thanks.html +++ b/pythonpro/core/templates/core/lead_thanks.html @@ -17,7 +17,7 @@

Cadastro realizado com Sucesso!

Será um prazer acompanhar você nessa incrível jornada. Muito obrigado pela confiança em nosso trabalho!

-

+

Luciano Ramalho e Renzo Nuccitelli

diff --git a/pythonpro/discourse/templates/discourse/landing_page.html b/pythonpro/discourse/templates/discourse/landing_page.html deleted file mode 100644 index 41e9dbc8..00000000 --- a/pythonpro/discourse/templates/discourse/landing_page.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Inscrição Curso Python Pro{% endblock %} - -{% block body %} -
-
-
-

Fórum Exclusivo para Membros

-

Explicar aqui

-
-
-
- -{% endblock body %} diff --git a/pythonpro/discourse/tests/test_sso.py b/pythonpro/discourse/tests/test_sso.py index 764080c5..7ea84cd9 100644 --- a/pythonpro/discourse/tests/test_sso.py +++ b/pythonpro/discourse/tests/test_sso.py @@ -11,7 +11,6 @@ from rolepermissions.roles import assign_role from pythonpro.discourse.views import _decode_payload -from pythonpro.django_assertions import dj_assert_template_used @pytest.fixture @@ -130,13 +129,12 @@ def test_user_not_logged(client): assert response.url == f'{login_path}?next={discourse_path}' -def test_lead_not_able_to_access_forum(client_with_lead, mocker, logged_user): - tag_as = mocker.patch('pythonpro.discourse.views.tag_as') +def test_lead_not_able_to_access_forum(client_with_lead, logged_user): discourse_path = reverse('discourse:sso') response = client_with_lead.get(discourse_path, secure=True) - dj_assert_template_used(response, 'discourse/landing_page.html') - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') + assert response.status_code == 302 + assert response.url == reverse('payments:member_landing_page') def test_client_not_able_to_access_forum(client_with_client, mocker, logged_user): - test_lead_not_able_to_access_forum(client_with_client, mocker, logged_user) + test_lead_not_able_to_access_forum(client_with_client, logged_user) diff --git a/pythonpro/discourse/views.py b/pythonpro/discourse/views.py index b8e47e6d..9773d55a 100644 --- a/pythonpro/discourse/views.py +++ b/pythonpro/discourse/views.py @@ -8,12 +8,12 @@ from django.conf import settings from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect -from django.shortcuts import render +from django.shortcuts import redirect +from django.urls import reverse from django.views.defaults import bad_request from rolepermissions.checkers import has_permission from pythonpro.core.roles import access_forum -from pythonpro.mailchimp.facade import tag_as logger = Logger(__file__) @@ -33,8 +33,7 @@ def sso(request): Code based on https://meta.discourse.org/t/sso-example-for-django/14258 """ if not has_permission(request.user, access_forum): - tag_as(request.user.email, 'potencial-member') - return render(request, 'discourse/landing_page.html') + return redirect(reverse('payments:member_landing_page'), permanent=False) payload = request.GET.get('sso') signature = request.GET.get('sig') try: diff --git a/pythonpro/modules/templates/topics/content_member_landing_page.html b/pythonpro/modules/templates/topics/content_member_landing_page.html deleted file mode 100644 index 0bd0bb52..00000000 --- a/pythonpro/modules/templates/topics/content_member_landing_page.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Inscrição Curso Python Pro{% endblock %} - -{% block body %} -
-
-
-

Conteúdo Exclusivo de Membros

-

Explicar aqui

-
-
-
- -{% endblock body %} diff --git a/pythonpro/modules/tests/test_next_content.py b/pythonpro/modules/tests/test_next_content.py index bc391bd0..1d77998a 100644 --- a/pythonpro/modules/tests/test_next_content.py +++ b/pythonpro/modules/tests/test_next_content.py @@ -36,8 +36,7 @@ def resp(client_with_member, django_user_model, topics): @pytest.fixture -def resp_last_topic(client_with_member, topics, mocker, logged_user): - mocker.patch('pythonpro.modules.topics_views.tag_as') +def resp_last_topic(client_with_member, topics, logged_user): last_topic = topics[1] yield client_with_member.get( reverse( diff --git a/pythonpro/modules/tests/test_topics_view.py b/pythonpro/modules/tests/test_topics_view.py index 5070a453..ddf9f755 100644 --- a/pythonpro/modules/tests/test_topics_view.py +++ b/pythonpro/modules/tests/test_topics_view.py @@ -120,31 +120,29 @@ def topic_member(chapter_member): @pytest.fixture -def resp_lead_accessing_member_content(client_with_lead, topic_member, django_user_model, mocker, logged_user): - tag_as = mocker.patch('pythonpro.modules.topics_views.tag_as') - yield client_with_lead.get( +def resp_lead_accessing_member_content(client_with_lead, topic_member, django_user_model, logged_user): + return client_with_lead.get( reverse('modules:topic_detail', kwargs={'module_slug': topic_member.module_slug(), 'topic_slug': topic_member.slug}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') def test_lead_hitting_member_landing_page(resp_lead_accessing_member_content): - dj_assert_template_used(resp_lead_accessing_member_content, 'topics/content_member_landing_page.html') + assert resp_lead_accessing_member_content.status_code == 302 + assert resp_lead_accessing_member_content.url == reverse('payments:member_landing_page') @pytest.fixture def resp_client_accessing_member_content(client_with_client, topic_member, django_user_model, mocker, logged_user): - tag_as = mocker.patch('pythonpro.modules.topics_views.tag_as') - yield client_with_client.get( + return client_with_client.get( reverse('modules:topic_detail', kwargs={'module_slug': topic_member.module_slug(), 'topic_slug': topic_member.slug}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-member') def test_client_hitting_member_landing_page(resp_client_accessing_member_content): - dj_assert_template_used(resp_client_accessing_member_content, 'topics/content_member_landing_page.html') + assert resp_client_accessing_member_content.status_code == 302 + assert resp_client_accessing_member_content.url == reverse('payments:member_landing_page') @pytest.fixture @@ -196,12 +194,10 @@ def topic_client(chapter_client): @pytest.fixture def resp_lead_accesing_client_content(client_with_lead, topic_client, django_user_model, mocker, logged_user): - tag_as = mocker.patch('pythonpro.modules.topics_views.tag_as') - yield client_with_lead.get( + return client_with_lead.get( reverse('modules:topic_detail', kwargs={'module_slug': topic_client.module_slug(), 'topic_slug': topic_client.slug}), secure=True) - tag_as.assert_called_once_with(logged_user.email, 'potencial-client') def test_lead_hitting_client_landing_page(resp_lead_accesing_client_content): diff --git a/pythonpro/modules/topics_views.py b/pythonpro/modules/topics_views.py index 7fd57644..4114fda8 100644 --- a/pythonpro/modules/topics_views.py +++ b/pythonpro/modules/topics_views.py @@ -1,32 +1,19 @@ -from django.conf import settings from django.contrib.auth.decorators import login_required from django.shortcuts import redirect, render from django.urls import reverse from rolepermissions.checkers import has_object_permission -from pythonpro.mailchimp.facade import tag_as from pythonpro.modules import facade from pythonpro.modules.models import Content from pythonpro.modules.permissions import is_client_content -from pythonpro.payments.facade import PYTOOLS_PRICE def content_landing_page(request, content: Content): if is_client_content(content): - tag_as(request.user.email, 'potencial-client') - return redirect(reverse('payments:client_landing_page'), permanent=False) - template = 'topics/content_member_landing_page.html' - tag = 'potencial-member' - - tag_as(request.user.email, tag) - return render(request, template, { - 'content': content, - 'PAGARME_CRYPTO_KEY': settings.PAGARME_CRYPTO_KEY, - 'price': PYTOOLS_PRICE, - 'notification_url': request.build_absolute_uri( - reverse('payments:pagarme_notification', kwargs={'user_id': request.user.id}) - ) - }) + redirect_path = reverse('payments:client_landing_page') + else: + redirect_path = reverse('payments:member_landing_page') + return redirect(redirect_path, permanent=False) @login_required diff --git a/pythonpro/payments/templates/payments/member_landing_page.html b/pythonpro/payments/templates/payments/member_landing_page.html new file mode 100644 index 00000000..9a563972 --- /dev/null +++ b/pythonpro/payments/templates/payments/member_landing_page.html @@ -0,0 +1,115 @@ +{% extends 'core/base_without_nav.html' %} +{% load static %} +{% block title %}Curso de Python Completo!{% endblock %} +{% block description %}Curso Completo de Python voltado para quem quer entrar no mercado de + tecnologia!{% endblock %} +{% block body %} +
+
+
+
+

Conteúdo exclusivo para Membros! +

+

Esse conteúdo é exclusivo para membros, aqueles que escolhem entrar de cabeça para a área de + programação e faturar alto! +

+

Confira o vídeo abaixo para entender como o curso completo funciona: +

+
+ +
+

Além disso tudo, fazemos o evento "Testando o Mercado" ao fim de cada turma com + empresas de TI interessadas em contratar alunos do curso.

+ +
+
+

Confira os Bônus

+
    +
  1. Acesso ao Fórum exclusivo para retirada de dúvidas! +
  2. + +
  3. Gravações de Aulas de TODAS turmas anteriores. +
  4. +
  5. Acesso ao Grupo de Telegram exclusivo para retirada de dúvidas + pelo celular! +
  6. +
  7. Gravações de Webinários com PROFISSIONAIS. +
  8. +
  9. Módulo extra de preparação para Entrevistas Técnicas visando empresas gringas, para quem + ganhar em dólar ou euro. +
  10. +
  11. Participação garantida no evento "Testando o Mercado", onde você encontrará empresas que + querem contratar. +
  12. +
+

Só esses bônus custariam R$ 3000,00 por mês.

+

Lista de Espera

+

Ainda estamos planejando a abertura da próxima turma. +

+

Clique no botão abaixo para se inscrever na lista de espera.. +

+ SIM! Quero entrar + na Lista de Espera » + +

* Não enviamos SPAM, apenas abrimos matrícula primeiro nessa lista, com desconto.

+

Na última turma as vagas acabaram em uma semana. Todos que estavam na lista de espera + entraram!

+
+
+
+
+
+
+
+
+

Esse curso vai te ajudar a:

+
Se conectar com profissionaid de TI
+
Você conhecerá toda rede alunos, muitos já atuando no mercado, para te ajudar. +
+
Conhecer empresas de interessadas em contratar
+
Você vai participar do evento "Testando o Mercado" com empresas interessadas em contratar! Já + participaram Magazine Luiza, Geru, Necto e Brasil317! +
+
Produzir e Entregar um Aplicativo Web
+
Você aprender como fazer um sistema web com todas boas práticas e publicá-lo em um servidor! +
+
Aprender a se inserir no mercado e negociar salário!
+
Além da tecnologia, você vai conferir téncnicas de negociação salarial e de precessos seletivos + para entrar no mercado e faturar alto! +
+
+
+
+
+
+ {% include 'core/instructors.html' %} +
+
+
+ {% include 'core/social_proof.html' %} +
+
+
+
+
+
+

Quer se transformar também?

+

Inscreva-se agora e dê mais um passo rumo à uma carreira de sucesso!

+ SIM! Quero entrar + na Lista de Espera » + + +
+
+
+
+ +{% endblock body %} \ No newline at end of file diff --git a/pythonpro/payments/templates/payments/waiting_list_ty.html b/pythonpro/payments/templates/payments/waiting_list_ty.html new file mode 100644 index 00000000..55bd39b2 --- /dev/null +++ b/pythonpro/payments/templates/payments/waiting_list_ty.html @@ -0,0 +1,26 @@ +{% extends 'core/base.html' %} +{% load static %} +{% block body %} +
+
+
+

Cadastro realizado com Sucesso!

+

Você agora será avisado com antecedência sobre a abertura da próxima tuma no email {{ email }}. +

+

Para você poder se programar, o custo da última turma foi de R$ 1500,00 no boleto à vista ou 10 vezes + de R$ 180,00 no cartão. +

+

Não garantimos o mesmo preço, mas também não costumamos aumentar significativamente o custo. +

+

Será um prazer conhecer você pessoalmente na próxima turma. +

+

+ Muito obrigado pela confiança em nosso trabalho! +

+

+ Luciano Ramalho e Renzo Nuccitelli +

+
+
+
+{% endblock body %} \ No newline at end of file diff --git a/pythonpro/payments/tests/test_landing_pages.py b/pythonpro/payments/tests/test_landing_pages.py index 8b95ac2b..79822c26 100644 --- a/pythonpro/payments/tests/test_landing_pages.py +++ b/pythonpro/payments/tests/test_landing_pages.py @@ -3,8 +3,10 @@ @pytest.fixture -def client_lp_resp(client_with_lead): - return client_with_lead.get(reverse('payments:client_landing_page'), secure=True) +def client_lp_resp(client_with_lead, mocker, logged_user): + tag_as = mocker.patch('pythonpro.payments.views.tag_as') + yield client_with_lead.get(reverse('payments:client_landing_page'), secure=True) + tag_as.assert_called_once_with(logged_user.email, 'potential-client') def test_non_logged_status_code(client_lp_resp): diff --git a/pythonpro/payments/tests/test_member_lp_subscription_closed.py b/pythonpro/payments/tests/test_member_lp_subscription_closed.py new file mode 100644 index 00000000..bfb84245 --- /dev/null +++ b/pythonpro/payments/tests/test_member_lp_subscription_closed.py @@ -0,0 +1,24 @@ +import pytest +from django.urls import reverse + +from pythonpro.django_assertions import dj_assert_contains + + +@pytest.fixture +def subscription_closed(settings): + settings.SUBSCRIPTIONS_OPEN = False + + +@pytest.fixture +def resp(subscription_closed, client_with_lead, mocker, logged_user): + tag_as = mocker.patch('pythonpro.payments.views.tag_as') + yield client_with_lead.get(reverse('payments:member_landing_page'), secure=True) + tag_as.assert_called_once_with(logged_user.email, 'potential-member') + + +def test_status_code(resp): + assert resp.status_code == 200 + + +def test_subscription_link_is_present(resp): + dj_assert_contains(resp, reverse('payments:waiting_list_ty')) diff --git a/pythonpro/payments/tests/test_waiting_list_ty.py b/pythonpro/payments/tests/test_waiting_list_ty.py new file mode 100644 index 00000000..6f2f4326 --- /dev/null +++ b/pythonpro/payments/tests/test_waiting_list_ty.py @@ -0,0 +1,18 @@ +import pytest +from django.urls import reverse + + +@pytest.fixture +def subscription_closed(settings): + settings.SUBSCRIPTIONS_OPEN = False + + +@pytest.fixture +def resp(subscription_closed, client_with_lead, logged_user, mocker): + tag_as = mocker.patch('pythonpro.payments.views.tag_as') + yield client_with_lead.get(reverse('payments:waiting_list_ty'), secure=True) + tag_as.assert_called_once_with(logged_user.email, 'lista-de-espera') + + +def test_status_code(resp): + assert resp.status_code == 200 diff --git a/pythonpro/payments/urls.py b/pythonpro/payments/urls.py index 362cf5a4..daaa6c25 100644 --- a/pythonpro/payments/urls.py +++ b/pythonpro/payments/urls.py @@ -6,6 +6,8 @@ urlpatterns = [ path('opcoes/', views.options, name='options'), path('obrigado/', views.thanks, name='thanks'), + path('curso-completo-de-python', views.member_landing_page, name='member_landing_page'), + path('lista-de-espera', views.waiting_list_ty, name='waiting_list_ty'), path('pytools/obrigado/', views.pytools_thanks, name='pytools_thanks'), path('pytools/captura/', views.pytools_capture, name='pytools_capture'), path('pytools/boleto/', views.pytools_boleto, name='pytools_boleto'), diff --git a/pythonpro/payments/views.py b/pythonpro/payments/views.py index 4f732c0f..ecef708a 100644 --- a/pythonpro/payments/views.py +++ b/pythonpro/payments/views.py @@ -12,6 +12,7 @@ from rolepermissions.roles import assign_role, remove_role from pythonpro.mailchimp import facade as mailchimp_facade +from pythonpro.mailchimp.facade import tag_as from pythonpro.payments import facade as payment_facade from pythonpro.payments.facade import PYTOOLS_PRICE @@ -64,6 +65,7 @@ def _extract_boleto_params(dct): @login_required def client_landing_page(request): + tag_as(request.user.email, 'potential-client') notification_url = reverse('payments:pagarme_notification', kwargs={'user_id': request.user.id}) return render( request, @@ -76,6 +78,19 @@ def client_landing_page(request): }) +@login_required +def member_landing_page(request): + tag_as(request.user.email, 'potential-member') + return render( + request, 'payments/member_landing_page.html', {}) + + +@login_required +def waiting_list_ty(request): + tag_as(request.user.email, 'lista-de-espera') + return render(request, 'payments/waiting_list_ty.html', {'email': request.user.email}) + + @csrf_exempt def pagarme_notification(request, user_id: int): if request.method != 'POST':