diff --git a/jobs/tests/test_views.py b/jobs/tests/test_views.py index e0a5eab4..1b68977e 100644 --- a/jobs/tests/test_views.py +++ b/jobs/tests/test_views.py @@ -17,7 +17,7 @@ def setUp(self): def test_jobs_view_list(self): job = JobFactory(owner=self.user) - company = CompanyFactory(owner=self.user, rank=3) + company = CompanyFactory(rank=3) sponsored_job = JobFactory(owner=self.user, company=company) sponsored_job2 = JobFactory(owner=self.user, company=company) @@ -42,11 +42,11 @@ def test_jobs_view_list_with_tags(self): self.assertEqual(len(response.context["job_list"]), 1) def test_jobs_view_list_regular_and_sponsored(self): - sponsored_company = CompanyFactory(name='Name', owner=self.user, rank=3) + sponsored_company = CompanyFactory(name='Name', rank=3) sponsored_job = JobFactory(owner=self.user, company=sponsored_company) sponsored_job_2 = JobFactory(owner=self.user, company=sponsored_company) - company = CompanyFactory(name='Other name', owner=self.user, rank=0) + company = CompanyFactory(name='Other name', rank=0) job = JobFactory(owner=self.user, company=company) job_2 = JobFactory(owner=self.user, company=company) diff --git a/pycompanies/migrations/0004_remove_company_owner.py b/pycompanies/migrations/0004_remove_company_owner.py new file mode 100644 index 00000000..00b89478 --- /dev/null +++ b/pycompanies/migrations/0004_remove_company_owner.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.13 on 2022-07-07 21:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('pycompanies', '0003_usercompanyprofile'), + ] + + operations = [ + migrations.RemoveField( + model_name='company', + name='owner', + ), + ] diff --git a/pycompanies/models.py b/pycompanies/models.py index e0aae213..b4f20d00 100644 --- a/pycompanies/models.py +++ b/pycompanies/models.py @@ -10,10 +10,6 @@ class Company(TimeStampedModel): """A PyAr Company that use Python.""" - - owner = models.ForeignKey(settings.AUTH_USER_MODEL, - related_name='companies', - on_delete=models.CASCADE) name = models.CharField('Nombre', max_length=255, unique=True) description = models.TextField('Descripción') photo = models.ImageField('Logo', upload_to='pycompanies/logos') diff --git a/pycompanies/tests/factories.py b/pycompanies/tests/factories.py index a74ed83c..a7d97f0d 100644 --- a/pycompanies/tests/factories.py +++ b/pycompanies/tests/factories.py @@ -1,4 +1,4 @@ -from factory import Sequence, SubFactory +from factory import Faker, Sequence, SubFactory from factory.django import DjangoModelFactory, ImageField from events.tests.factories import UserFactory @@ -10,8 +10,9 @@ class Meta: model = Company name = Sequence(lambda n: f'company-{n}') - owner = SubFactory(UserFactory) photo = ImageField(color='blue') + description = Faker('text') + link = Faker('url') rank = 1 diff --git a/pycompanies/tests/test_views.py b/pycompanies/tests/test_views.py index 4045c27f..fc2619e8 100644 --- a/pycompanies/tests/test_views.py +++ b/pycompanies/tests/test_views.py @@ -1,3 +1,4 @@ +import factory import pytest from unittest.mock import patch @@ -5,6 +6,7 @@ from django.contrib.messages import get_messages as contrib_get_messages from django.urls import reverse +from pycompanies.models import Company, UserCompanyProfile from pycompanies.views import get_user_display_name from pycompanies.tests.factories import CompanyFactory, UserCompanyProfileFactory, UserFactory from joboffers.tests.fixtures import create_admin_client, create_publisher_client # noqa @@ -16,8 +18,9 @@ ERROR_USER_DOES_NOT_EXIST = 'Le usuarie que ingresaste no existe.' USER_ASSOCIATED_CORRECTLY = 'Le usuarie fue asociade correctamente.' -ADMIN_URL = reverse('companies:admin') -COMPANY_LIST_URL = reverse('companies:company_list_all') +ADMIN_URL = 'companies:admin' +LIST_URL = 'companies:company_list_all' +CREATE_URL = 'companies:add' def get_plain_messages(request): @@ -39,8 +42,10 @@ def test_associate_nonexistent_user(logged_client): response = logged_client.post(ASSOCIATE_URL, data={'username': 'pepito'}) message = get_plain_messages(response)[0] + admin_url = reverse(ADMIN_URL) + assert 302 == response.status_code - assert ADMIN_URL == response.url + assert admin_url == response.url assert ERROR_USER_DOES_NOT_EXIST == message @@ -56,8 +61,10 @@ def test_associate_user_in_company(logged_client, user): response = logged_client.post(ASSOCIATE_URL, data={'username': user.username}) message = get_plain_messages(response)[0] + admin_url = reverse(ADMIN_URL) + assert 302 == response.status_code - assert ADMIN_URL == response.url + assert admin_url == response.url assert USER_ASSOCIATED_CORRECTLY == message @@ -78,7 +85,7 @@ def test_associate_user_already_in_company(logged_client, user): message = get_plain_messages(response)[0] assert 302 == response.status_code - assert ADMIN_URL == response.url + assert reverse(ADMIN_URL) == response.url assert ERROR_USER_ALREADY_IN_COMPANY == message @@ -99,7 +106,7 @@ def test_associate_user_in_other_company(logged_client, user): message = get_plain_messages(response)[0] assert 302 == response.status_code - assert ADMIN_URL == response.url + assert reverse(ADMIN_URL) == response.url assert message == ERROR_USER_IN_OTHER_COMPANY @@ -108,7 +115,7 @@ def test_company_admin_with_no_logged_user_should_redirect(client): """ Should redirect if the user is not logged """ - response = client.get(ADMIN_URL) + response = client.get(reverse(ADMIN_URL)) assert 302 == response.status_code @@ -118,7 +125,7 @@ def test_company_admin_with_no_company_logged_user_should_redirect(logged_client """ Should redirect if the user is logged but not associated to a company """ - response = logged_client.get(ADMIN_URL) + response = logged_client.get(reverse(ADMIN_URL)) assert 302 == response.status_code @@ -131,7 +138,7 @@ def test_company_admin_with_company_logged_user_should_not_redirect(logged_clien company = CompanyFactory.create(name='company') UserCompanyProfileFactory.create(company=company, user=user) - response = logged_client.get(ADMIN_URL) + response = logged_client.get(reverse(ADMIN_URL)) assert 200 == response.status_code @@ -227,13 +234,17 @@ def test_company_disassociate_one_user_from_company(logged_client, user): @pytest.mark.django_db -def test_company_detail_doesnt_show_analytics_button_for_normal_user(logged_client): +def test_company_detail_doesnt_show_analytics_button_for_normal_user(user, logged_client): """ Test that the company page doesn't show the analytics button for authenticated users that doesn't belong to the current company """ + logged_user = user client = logged_client company = CompanyFactory.create(name='company_1') + UserCompanyProfileFactory.create(company=company) + # Associate the logged user to another company to cover this also that case + UserCompanyProfileFactory.create(user=logged_user) target_url = reverse('companies:detail', kwargs={'pk': company.id}) @@ -338,6 +349,75 @@ def test_render_company_analytics_ok( assert table_views == expected_table_views +@pytest.mark.django_db +def test_company_create_view_GET_doesnt_allow_creation_of_company_for_logged_user_with_company( + user, logged_client +): + """ + Test that the company create GET doesn't allow creation of multiple companies for GET + """ + client = logged_client + UserCompanyProfileFactory.create(user=user) + + response = client.get(reverse(CREATE_URL)) + + assert response.status_code == 403 + + +@pytest.mark.django_db +def test_company_create_view_POST_doesnt_allow_creation_of_company_for_logged_user_with_company( + user, logged_client +): + """ + Test that the company create POST doesn't allow creation of multiple companies + """ + client = logged_client + UserCompanyProfileFactory.create(user=user) + + response = client.post(reverse(CREATE_URL)) + + assert response.status_code == 403 + + +@pytest.mark.django_db +def test_company_list_view_includes_own_company_for_logged_user_with_company( + user, logged_client +): + """ + Test that the company list view does not includes own_company for user with company created + (Doesn't allow creation of multiple companies) + """ + client = logged_client + UserCompanyProfileFactory.create(user=user) + + target_url = reverse(LIST_URL) + + response = client.get(target_url) + assert 'own_company' in response.context_data + + +@pytest.mark.django_db +def test_create_company_associates_the_user_to_a_company(user, logged_client): + """ + Test that company creation associates the logged user to that company + """ + client = logged_client + target_url = reverse(CREATE_URL) + + company_data = factory.build( + dict, + FACTORY_CLASS=CompanyFactory + ) + + assert Company.objects.count() == 0 + + response = client.post(target_url, company_data, format="multipart") + + assert response.status_code == 302 + assert Company.objects.count() == 1 + assert UserCompanyProfile.objects.for_user(user=user) + + def test_get_user_display_name_without_first_name_and_last_name(): """ Test return for an user without first_name and last_name @@ -385,7 +465,7 @@ def test_company_list_view_includes_user_and_own_company_for_publisher(publisher """ client = publisher_client - response = client.get(COMPANY_LIST_URL) + response = client.get(reverse(LIST_URL)) assert response.context_data['user'].is_authenticated assert 'own_company' in response.context_data @@ -399,7 +479,7 @@ def test_company_list_view_includes_user_and_own_company_for_user_without_compan """ client = logged_client - response = client.get(COMPANY_LIST_URL) + response = client.get(reverse(LIST_URL)) assert response.context_data['user'].is_authenticated assert 'own_company' not in response.context_data @@ -411,7 +491,7 @@ def test_company_list_view_includes_user_and_own_company_for_unlogged_user(clien Test that the company list view includes user and own_company for anonymous user """ - response = client.get(COMPANY_LIST_URL) + response = client.get(reverse(LIST_URL)) assert response.context_data['user'].is_anonymous assert 'own_company' not in response.context_data diff --git a/pycompanies/views.py b/pycompanies/views.py index e11954e6..69317f31 100644 --- a/pycompanies/views.py +++ b/pycompanies/views.py @@ -30,8 +30,9 @@ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = self.request.user + company = self.object - if UserCompanyProfile.objects.for_user(user=user) or user.is_superuser: + if UserCompanyProfile.objects.for_user(user=user, company=company) or user.is_superuser: context['can_view_analytics'] = True else: context['can_view_analytics'] = False @@ -52,7 +53,7 @@ def get_context_data(self, **kwargs): context['user'] = self.request.user user_company = UserCompanyProfile.objects.for_user(user=self.request.user) - if self.request.user.is_anonymous is False and user_company: + if user_company: context['own_company'] = user_company.company return context @@ -63,9 +64,22 @@ class CompanyCreateView(LoginRequiredMixin, CreateView): success_url = '/empresas/' template_name = 'companies/company_form.html' + def dispatch(self, request, *args, **kwargs): + user = self.request.user + company_profile = UserCompanyProfile.objects.for_user(user=user) + + if company_profile: + raise PermissionDenied + + return super().dispatch(request, *args, **kwargs) + def form_valid(self, form): - form.instance.owner = self.request.user - return super().form_valid(form) + response = super().form_valid(form) + company = form.instance + user = self.request.user + UserCompanyProfile.objects.create(user=user, company=company) + + return response class CompanyUpdateView(LoginRequiredMixin, OwnedObject, UpdateView):