Example #1
0
    def test_add_member_to_siae(self):
        invitation = SiaeSentInvitationFactory(email="*****@*****.**")
        user = UserFactory(email=invitation.email)
        siae_members = invitation.siae.members.count()
        invitation.add_invited_user_to_siae()
        siae_members_after = invitation.siae.members.count()
        self.assertEqual(siae_members + 1, siae_members_after)

        user.refresh_from_db()
Example #2
0
 def test_add_member_to_siae(self):
     invitation = SentSiaeStaffInvitationFactory(email="*****@*****.**")
     UserFactory(email=invitation.email)
     siae_members = invitation.siae.members.count()
     invitation.add_invited_user_to_siae()
     siae_members_after = invitation.siae.members.count()
     self.assertEqual(siae_members + 1, siae_members_after)
Example #3
0
 def test_add_member_to_organization(self):
     invitation = PrescriberWithOrgSentInvitationFactory(email="*****@*****.**")
     UserFactory(email=invitation.email)
     org_members = invitation.organization.members.count()
     invitation.add_invited_user_to_organization()
     org_members_after = invitation.organization.members.count()
     self.assertEqual(org_members + 1, org_members_after)
Example #4
0
    def test_accepted_notif_siae_members(self):
        user = UserFactory()
        invitation = SiaeSentInvitationFactory(email=user.email)
        invitation.siae.members.add(user)
        email = invitation.email_accepted_notif_siae_members

        # Subject
        self.assertIn(invitation.first_name, email.subject)
        self.assertIn(invitation.last_name, email.subject)

        # Body
        self.assertIn(invitation.first_name, email.body)
        self.assertIn(invitation.last_name, email.body)
        self.assertIn(invitation.email, email.body)
        self.assertIn(invitation.sender.first_name, email.body)
        self.assertIn(invitation.sender.last_name, email.body)
        self.assertIn(invitation.siae.display_name, email.body)

        # To
        members = invitation.siae.members.exclude(
            email__in=[invitation.sender.email, invitation.email])
        for member in members:
            self.assertIn(member.email, email.to)

        self.assertNotIn(invitation.sender.email, email.to)
        self.assertNotIn(invitation.email, email.to)
Example #5
0
    def test_send_invitation_user_already_exists(self):
        guest = UserFactory(
            first_name=self.guest_data["first_name"],
            last_name=self.guest_data["last_name"],
            email=self.guest_data["email"],
            is_siae_staff=True,
        )
        self.client.login(email=self.sender.email, password=DEFAULT_PASSWORD)
        response = self.client.post(INVITATION_URL,
                                    data=self.post_data,
                                    follow=True)
        self.assertEqual(response.status_code, 200)

        # The guest will be able to join the structure
        invitations = SiaeStaffInvitation.objects.all()
        self.assertEqual(len(invitations), 1)

        invitation = invitations[0]

        # At least one complete test of the invitation fields in our test suite
        self.assertFalse(invitation.accepted)
        self.assertTrue(invitation.sent_at < timezone.now())
        self.assertEqual(invitation.first_name, guest.first_name)
        self.assertEqual(invitation.last_name, guest.last_name)
        self.assertEqual(invitation.email, guest.email)
        self.assertEqual(invitation.sender, self.sender)
        self.assertEqual(invitation.siae, self.siae)
        self.assertEqual(invitation.SIGNIN_ACCOUNT_TYPE, "siae")
Example #6
0
    def test_download_approval_missing_diagnosis_ai(self, *args, **kwargs):
        """
        Given an existing job application with an approval delivered by Itou
        when importing AI employees, when an AI tries to download it as PDF, it works.
        """

        # On November 30th, 2021, AI were delivered approvals without a diagnosis.
        # See itou.users.management.commands.import_ai_employees.
        approval_created_at = settings.AI_EMPLOYEES_STOCK_IMPORT_DATE
        approval_created_by = UserFactory(email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        job_application = JobApplicationWithApprovalFactory(
            eligibility_diagnosis=None,
            approval__created_at=approval_created_at,
            approval__created_by=approval_created_by,
        )

        siae_member = job_application.to_siae.members.first()
        self.client.login(username=siae_member.email, password=DEFAULT_PASSWORD)

        response = self.client.get(
            reverse("approvals:approval_as_pdf", kwargs={"job_application_id": job_application.pk})
        )

        self.assertEqual(response.status_code, 200)
        self.assertIn("pdf", response.get("Content-Type"))
Example #7
0
 def test_accept_invitation_logged_in_user(self):
     # A logged in user should log out before accepting an invitation.
     logged_in_user = UserFactory()
     self.client.login(email=logged_in_user.email,
                       password=DEFAULT_PASSWORD)
     # Invitation for another user
     invitation = SentSiaeStaffInvitationFactory(email="*****@*****.**")
     response = self.client.get(invitation.acceptance_link, follow=True)
     self.assertRedirects(response, reverse("account_logout"))
Example #8
0
 def setUp(self):
     self.siae = SiaeWithMembershipFactory()
     # The sender is a member of the SIAE
     self.sender = self.siae.members.first()
     # Define instances not created in DB
     self.invited_user = UserFactory.build()
     self.second_invited_user = UserFactory.build()
     self.post_data = {
         "form-TOTAL_FORMS": "2",
         "form-INITIAL_FORMS": "0",
         "form-MIN_NUM_FORMS": "",
         "form-MAX_NUM_FORMS": "",
         "form-0-first_name": self.invited_user.first_name,
         "form-0-last_name": self.invited_user.last_name,
         "form-0-email": self.invited_user.email,
         "form-1-first_name": self.second_invited_user.first_name,
         "form-1-last_name": self.second_invited_user.last_name,
         "form-1-email": self.second_invited_user.email,
     }
Example #9
0
 def test_pe_organization_invitation_successful(self):
     guest = UserFactory.build(email=f"sabine.lagrange{settings.POLE_EMPLOI_EMAIL_SUFFIX}")
     post_data = POST_DATA | {
         "form-0-first_name": guest.first_name,
         "form-0-last_name": guest.last_name,
         "form-0-email": guest.email,
     }
     self.client.login(email=self.sender.email, password=DEFAULT_PASSWORD)
     response = self.client.post(INVITATION_URL, data=post_data, follow=True)
     self.assertRedirects(response, INVITATION_URL)
Example #10
0
    def test_find_or_create_job_seeker__find(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        CommuneFactory(code=getattr(CleanedAiCsvFileMock, CITY_INSEE_COL))
        command = self.command

        # Find existing user with NIR.
        nir = getattr(CleanedAiCsvFileMock(), NIR_COL)
        JobSeekerFactory(nir=nir)
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertFalse(created)
        self.assertTrue(job_seeker)
        self.assertEqual(job_seeker.nir, nir)
        self.assertEqual(User.objects.all().count(), 2)
        # Clean
        job_seeker.delete()

        # Find existing user with email address.
        email = getattr(CleanedAiCsvFileMock(), EMAIL_COL)
        JobSeekerFactory(nir="", email=email)
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertFalse(created)
        self.assertTrue(job_seeker)
        self.assertEqual(job_seeker.email, email)
        self.assertEqual(User.objects.all().count(), 2)
        # Clean
        job_seeker.delete()

        # Find existing user created previously by this script.
        base_data = CleanedAiCsvFileMock()
        first_name = getattr(base_data, FIRST_NAME_COL).title()
        last_name = getattr(base_data, LAST_NAME_COL).title()
        birthdate = getattr(base_data, BIRTHDATE_COL)
        nir = getattr(base_data, NIR_COL)
        JobSeekerFactory(
            first_name=first_name,
            last_name=last_name,
            birthdate=birthdate,
            nir=nir,
            created_by=developer,
            date_joined=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
        )
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertFalse(created)
        self.assertTrue(job_seeker)
        self.assertEqual(job_seeker.birthdate, birthdate.date())
        self.assertEqual(User.objects.all().count(), 2)
        # Clean
        job_seeker.delete()
Example #11
0
    def test_send_invitation_to_not_employer(self):
        UserFactory(
            first_name=self.guest_data["first_name"],
            last_name=self.guest_data["last_name"],
            email=self.guest_data["email"],
        )
        self.client.login(email=self.sender.email, password=DEFAULT_PASSWORD)
        response = self.client.post(INVITATION_URL, data=self.post_data)

        for error_dict in response.context["formset"].errors:
            for key, _errors in error_dict.items():
                self.assertEqual(key, "email")
                self.assertEqual(error_dict["email"][0],
                                 "Cet utilisateur n'est pas un employeur.")
Example #12
0
 def setUp(self):
     self.siae = SiaeWith2MembershipsFactory()
     self.sender = self.siae.members.first()
     self.guest = UserFactory.build(first_name="Léonie",
                                    last_name="Bathiat")
     self.post_data = {
         "form-TOTAL_FORMS": "1",
         "form-INITIAL_FORMS": "0",
         "form-MIN_NUM_FORMS": "",
         "form-MAX_NUM_FORMS": "",
         "form-0-first_name": self.guest.first_name,
         "form-0-last_name": self.guest.last_name,
         "form-0-email": self.guest.email,
     }
     self.invitations_model = SiaeStaffInvitation
     self.client.login(email=self.sender.email, password=DEFAULT_PASSWORD)
     self.send_invitation_url = reverse(
         "invitations_views:invite_siae_staff")
Example #13
0
 def test_send_approval_number_by_email_manually(self):
     staff_member = UserFactory(is_staff=True)
     job_seeker = JobSeekerFactory()
     approval = ApprovalFactory(user=job_seeker)
     job_application = JobApplicationSentByAuthorizedPrescriberOrganizationFactory(
         job_seeker=job_seeker,
         state=JobApplicationWorkflow.STATE_PROCESSING,
         approval=approval)
     job_application.accept(user=job_application.to_siae.members.first())
     mail.outbox = []  # Delete previous emails.
     job_application.send_approval_number_by_email_manually(
         deliverer=staff_member)
     self.assertTrue(job_application.approval_number_sent_by_email)
     self.assertIsNotNone(job_application.approval_number_sent_at)
     self.assertEqual(job_application.approval_delivery_mode,
                      job_application.APPROVAL_DELIVERY_MODE_MANUAL)
     self.assertEqual(job_application.approval_number_delivered_by,
                      staff_member)
     self.assertEqual(len(mail.outbox), 1)
Example #14
0
    def test_find_or_create_approval__find(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        command = self.command

        # Existing valid PASS IAE delivered after a job application has been accepted.
        approval_start_at = datetime.date(
            2021, 11, 10)  # Approval should start before November 30th.
        existing_approval = ApprovalFactory(user__nir=getattr(
            CleanedAiCsvFileMock(), NIR_COL),
                                            start_at=approval_start_at)
        created, expected_approval, _ = command.find_or_create_approval(
            job_seeker=existing_approval.user, created_by=developer)
        self.assertFalse(created)
        self.assertTrue(expected_approval.is_valid)
        # Make sure no update was made.
        self.assertEqual(existing_approval.pk, expected_approval.pk)
        self.assertEqual(existing_approval.start_at,
                         expected_approval.start_at)
        self.assertEqual(existing_approval.user.pk, expected_approval.user.pk)
        # Clean
        existing_approval.user.delete()

        # PASS IAE created previously by this script.
        existing_approval = ApprovalFactory(
            user__nir=getattr(CleanedAiCsvFileMock(), NIR_COL),
            start_at=datetime.date(2021, 12, 1),
            created_by=developer,
            created_at=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
        )
        created, expected_approval, _ = command.find_or_create_approval(
            job_seeker=existing_approval.user, created_by=developer)
        self.assertFalse(created)
        self.assertEqual(existing_approval.pk, expected_approval.pk)
        self.assertTrue(expected_approval.is_valid)
        # Clean
        existing_approval.user.delete()
Example #15
0
    def test_find_or_create_job_application__find(self):
        # Find job applications created previously by this script.
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        command = self.command

        # An approval is mandatory to test employee records creation (FS).
        approval = ApprovalFactory(
            user__nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        expected_job_app = JobApplicationSentBySiaeFactory(
            to_siae__kind=Siae.KIND_AI,
            state=JobApplicationWorkflow.STATE_ACCEPTED,  # Mandatory for FS.
            job_seeker=approval.user,
            approval=approval,
            approval_manually_delivered_by=developer,
            created_at=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
            hiring_start_at=getattr(CleanedAiCsvFileMock(),
                                    CONTRACT_STARTDATE_COL),
        )
        job_seeker = expected_job_app.job_seeker
        df = pandas.DataFrame([
            CleanedAiCsvFileMock(**{SIRET_COL: expected_job_app.to_siae.siret})
        ])
        created, found_job_application, _ = command.find_or_create_job_application(
            approval=expected_job_app.approval,
            job_seeker=job_seeker,
            row=df.iloc[0],
            approval_manually_delivered_by=developer,
        )
        self.assertFalse(created)
        self.assertEqual(expected_job_app.pk, found_job_application.pk)
        self.assertFalse(found_job_application.can_be_cancelled)
        # Assert job application has been updated to block employee records creation.
        self.assertNotIn(
            found_job_application,
            JobApplication.objects.eligible_as_employee_record(
                found_job_application.to_siae))
Example #16
0
    def test_import_data_into_itou(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        CommuneFactory(code=getattr(CleanedAiCsvFileMock, CITY_INSEE_COL))
        command = self.command
        base_data = CleanedAiCsvFileMock()
        siae = SiaeFactory(siret=getattr(base_data, SIRET_COL),
                           kind=Siae.KIND_AI)

        # User, approval and job application creation.
        input_df = pandas.DataFrame([base_data])
        output_df = command.import_data_into_itou(df=input_df,
                                                  to_be_imported_df=input_df)
        self.assertEqual(User.objects.count(), 2)
        self.assertEqual(Approval.objects.count(), 1)
        self.assertEqual(JobApplication.objects.count(), 1)
        job_seeker = User.objects.filter(is_job_seeker=True).get()
        self.assertEqual(job_seeker.job_applications.count(), 1)
        self.assertEqual(job_seeker.approvals.count(), 1)
        job_seeker.delete()

        # User, approval and job application retrieval.
        job_seeker = JobSeekerFactory(nir=getattr(base_data, NIR_COL))
        ApprovalFactory(user=job_seeker)
        JobApplicationFactory(
            sender_kind=JobApplication.SENDER_KIND_SIAE_STAFF,
            sender_siae=siae,
            to_siae=siae,
            created_at=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
            approval_manually_delivered_by=developer,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_MANUAL,
            job_seeker=job_seeker,
            hiring_start_at=getattr(base_data, CONTRACT_STARTDATE_COL),
        )
        input_df = pandas.DataFrame([CleanedAiCsvFileMock()])
        output_df = command.import_data_into_itou(df=input_df,
                                                  to_be_imported_df=input_df)
        self.assertEqual(User.objects.filter(is_job_seeker=True).count(), 1)
        self.assertEqual(Approval.objects.count(), 1)
        self.assertEqual(JobApplication.objects.count(), 1)
        job_seeker.delete()

        # Only values to be imported are imported but the whole input data frame
        # is updated for logging purposes.
        input_df = pandas.DataFrame([
            CleanedAiCsvFileMock(**{CONTRACT_ENDDATE_COL: "2020-05-11"
                                    }),  # Ended contracts are ignored.
            CleanedAiCsvFileMock(
                **{SIRET_COL: "598742121322354"}),  # Not existing SIAE.
            CleanedAiCsvFileMock(
                **{
                    NIR_COL: "141062a78200555",
                    EMAIL_COL: "*****@*****.**",
                    BIRTHDATE_COL: datetime.date(1997, 3, 12),
                }),
            # Different contract start date.
            CleanedAiCsvFileMock(
                **{CONTRACT_STARTDATE_COL: datetime.date(2020, 4, 12)}),
            CleanedAiCsvFileMock(),
        ])
        input_df = command.add_columns_for_asp(input_df)
        input_df, to_be_imported_df = command.remove_ignored_rows(input_df)
        output_df = command.import_data_into_itou(
            df=input_df, to_be_imported_df=to_be_imported_df)

        self.assertEqual(User.objects.count(), 3)
        self.assertEqual(Approval.objects.count(), 2)
        self.assertEqual(JobApplication.objects.count(), 3)

        job_seeker = User.objects.get(email=getattr(base_data, EMAIL_COL))
        self.assertEqual(job_seeker.job_applications.count(), 2)
        self.assertEqual(job_seeker.approvals.count(), 1)

        # Different contract start date.
        job_seeker = User.objects.get(email="*****@*****.**")
        self.assertEqual(job_seeker.job_applications.count(), 1)
        self.assertEqual(job_seeker.approvals.count(), 1)

        # Ignored rows.
        for _, row in output_df[:2].iterrows():
            self.assertTrue(row[COMMENTS_COL])
            self.assertFalse(row[PASS_IAE_NUMBER_COL])
            self.assertFalse(row[USER_PK_COL])

        for _, row in output_df[2:].iterrows():
            job_seeker = User.objects.get(nir=row[NIR_COL])
            approval = job_seeker.approvals.first()
            self.assertEqual(row[PASS_IAE_NUMBER_COL], approval.number)
            self.assertEqual(row[PASS_IAE_START_DATE_COL],
                             approval.start_at.strftime(DATE_FORMAT))
            self.assertEqual(row[PASS_IAE_END_DATE_COL],
                             approval.end_at.strftime(DATE_FORMAT))
            self.assertEqual(row[USER_PK_COL], job_seeker.jobseeker_hash_id)
            self.assertEqual(row[USER_ITOU_EMAIL_COL], job_seeker.email)

        # Clean
        job_seeker = User.objects.get(nir=getattr(base_data, NIR_COL))
        job_seeker.delete()
        job_seeker = User.objects.get(email="*****@*****.**")
        job_seeker.delete()

        # If transaction: raise and pass.
        job_seeker = JobSeekerFactory(
            nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        future_date = datetime.date.today() + relativedelta(months=2)
        ApprovalFactory(user=job_seeker, start_at=future_date)
        input_df = pandas.DataFrame([
            base_data,
            CleanedAiCsvFileMock(
                **{
                    NIR_COL: "141062a78200555",
                    EMAIL_COL: "*****@*****.**",
                    BIRTHDATE_COL: datetime.date(1997, 3, 12),
                }),
        ])

        output_df = None
        output_df = command.import_data_into_itou(df=input_df,
                                                  to_be_imported_df=input_df)
        self.assertEqual(len(output_df), 2)
Example #17
0
    def test_manually_add_approval(self):
        user = UserFactory()
        self.client.login(username=user.email, password=DEFAULT_PASSWORD)

        # When a Pôle emploi ID has been forgotten, an approval must be delivered
        # with a manual verification.
        job_seeker = JobSeekerFactory(
            pole_emploi_id="", lack_of_pole_emploi_id_reason=JobSeekerFactory._meta.model.REASON_FORGOTTEN
        )
        job_application = JobApplicationSentByJobSeekerFactory(
            job_seeker=job_seeker,
            state=JobApplicationWorkflow.STATE_PROCESSING,
            approval=None,
            approval_number_sent_by_email=False,
        )
        job_application.accept(user=job_application.to_siae.members.first())

        # Delete emails sent by previous transition.
        mail.outbox = []

        url = reverse("admin:approvals_approval_manually_add_approval", args=[job_application.pk])

        # Not enough perms.
        response = self.client.get(url)
        self.assertEqual(response.status_code, 302)

        user.is_staff = True
        user.save()
        content_type = ContentType.objects.get_for_model(Approval)
        permission = Permission.objects.get(content_type=content_type, codename="add_approval")
        user.user_permissions.add(permission)

        # With good perms.
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        # Create an approval.
        post_data = {
            "start_at": job_application.hiring_start_at.strftime("%d/%m/%Y"),
            "end_at": job_application.hiring_end_at.strftime("%d/%m/%Y"),
            "number": "400121910144",
            "user": job_application.job_seeker.pk,
            "created_by": user.pk,
        }
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302)

        # An approval should have been created, attached to the job
        # application, and sent by email.
        job_application = JobApplication.objects.get(pk=job_application.pk)
        self.assertTrue(job_application.approval_number_sent_by_email)
        self.assertIsNotNone(job_application.approval_number_sent_at)
        self.assertEqual(job_application.approval_number_delivered_by, user)
        self.assertEqual(job_application.approval_delivery_mode, job_application.APPROVAL_DELIVERY_MODE_MANUAL)

        approval = job_application.approval
        self.assertEqual(approval.created_by, user)
        self.assertEqual(approval.number, post_data["number"])
        self.assertEqual(approval.user, job_application.job_seeker)

        self.assertEqual(len(mail.outbox), 1)
        email = mail.outbox[0]
        self.assertIn(approval.number_with_spaces, email.body)
Example #18
0
    def test_find_or_create_job_seeker__create(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        commune = CommuneFactory(
            code=getattr(CleanedAiCsvFileMock, CITY_INSEE_COL))
        command = self.command

        # Job seeker not found: create user.
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertTrue(job_seeker)
        self.assertEqual(User.objects.all().count(), 2)
        # Clean
        job_seeker.delete()

        # # NIR is empty: create user with NIR None, even if another one exists.
        previous_job_seekers_pk = [
            JobSeekerFactory(nir="").pk,
            JobSeekerFactory(nir=None).pk
        ]
        df = pandas.DataFrame(
            [CleanedAiCsvFileMock(**{
                NIR_COL: "",
                "nir_is_valid": False
            })])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertTrue(job_seeker)
        self.assertEqual(User.objects.all().count(), 4)
        self.assertEqual(job_seeker.nir, None)
        # Clean
        job_seeker.delete()
        User.objects.filter(pk__in=previous_job_seekers_pk).delete()

        # # If found job_seeker is not a job seeker: create one with a fake email address.
        prescriber = PrescriberFactory(
            email=getattr(CleanedAiCsvFileMock(), EMAIL_COL))
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertTrue(job_seeker)
        self.assertEqual(User.objects.all().count(), 3)
        self.assertEqual(job_seeker.nir,
                         getattr(CleanedAiCsvFileMock(), NIR_COL))
        self.assertNotEqual(job_seeker.email, prescriber.email)
        # Clean
        job_seeker.delete()
        prescriber.delete()

        # Check expected attributes.
        # Perfect path: NIR, email, ...
        # Created by developer on XX date.
        base_data = CleanedAiCsvFileMock()
        df = pandas.DataFrame([base_data])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertEqual(job_seeker.created_by.pk, developer.pk)
        self.assertEqual(job_seeker.date_joined,
                         settings.AI_EMPLOYEES_STOCK_IMPORT_DATE)
        self.assertEqual(job_seeker.first_name,
                         getattr(base_data, FIRST_NAME_COL).title())
        self.assertEqual(job_seeker.last_name,
                         getattr(base_data, LAST_NAME_COL).title())
        self.assertEqual(job_seeker.birthdate, getattr(base_data,
                                                       BIRTHDATE_COL))
        self.assertEqual(job_seeker.email, getattr(base_data, EMAIL_COL))
        self.assertTrue(job_seeker.address_line_1)
        self.assertTrue(job_seeker.address_line_2)
        self.assertEqual(job_seeker.post_code, getattr(base_data,
                                                       POST_CODE_COL))
        self.assertEqual(job_seeker.city, commune.name.title())
        self.assertTrue(job_seeker.department)
        self.assertEqual(job_seeker.phone, getattr(base_data, PHONE_COL))
        self.assertEqual(job_seeker.nir, getattr(base_data, NIR_COL))
        # Clean
        job_seeker.delete()

        # If no email provided: fake email.
        df = pandas.DataFrame([CleanedAiCsvFileMock(**{EMAIL_COL: ""})])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertTrue(job_seeker.email.endswith("@email-temp.com"))
        job_seeker.delete()

        # A job seeker is found by email address but its NIR is different.
        # Create a new one.
        email = getattr(CleanedAiCsvFileMock(), EMAIL_COL)
        JobSeekerFactory(nir="141062a78200555", email=email)
        df = pandas.DataFrame([CleanedAiCsvFileMock()])
        created, job_seeker = command.find_or_create_job_seeker(
            row=df.iloc[0], created_by=developer)
        self.assertTrue(created)
        self.assertTrue(job_seeker.email.endswith("@email-temp.com"))
        job_seeker.delete()
Example #19
0
    def test_find_or_create_approval__create(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        command = self.command

        # No PASS IAE.
        job_seeker = JobSeekerFactory(
            nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        created, approval, _ = command.find_or_create_approval(
            job_seeker=job_seeker, created_by=developer)
        self.assertTrue(created)
        self.assertTrue(approval.is_valid)
        # Check attributes
        self.assertEqual(approval.user.pk, job_seeker.pk)
        self.assertEqual(approval.start_at, datetime.date(2021, 12, 1))
        self.assertEqual(approval.end_at, datetime.date(2023, 11, 30))
        self.assertEqual(approval.created_by.pk, developer.pk)
        self.assertEqual(approval.created_at,
                         settings.AI_EMPLOYEES_STOCK_IMPORT_DATE)
        self.assertTrue(approval.is_from_ai_stock)

        # Clean
        job_seeker.delete()

        # Expired PASS IAE.
        approval_start_at = datetime.date.today() - relativedelta(
            years=Approval.DEFAULT_APPROVAL_YEARS, days=2)
        expired_approval = ApprovalFactory(user__nir=getattr(
            CleanedAiCsvFileMock(), NIR_COL),
                                           start_at=approval_start_at)
        job_seeker = expired_approval.user
        created, approval, _ = command.find_or_create_approval(
            job_seeker=job_seeker, created_by=developer)
        self.assertTrue(created)
        self.assertEqual(approval.user.pk, job_seeker.pk)
        self.assertTrue(approval.is_valid)
        self.assertEqual(job_seeker.approvals.count(), 2)
        # Clean
        job_seeker.delete()

        # PASS created after November 30th with a job application:
        # the employer tried to get a PASS IAE quicker.
        siae = SiaeWithMembershipFactory()
        previous_approval = ApprovalFactory(
            user__nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        job_seeker = previous_approval.user
        job_application = JobApplicationSentBySiaeFactory(
            job_seeker=job_seeker,
            to_siae=siae,
            state=JobApplicationWorkflow.STATE_ACCEPTED,
            approval=previous_approval,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_AUTOMATIC,
        )
        created, _, redelivered_approval = command.find_or_create_approval(
            job_seeker=job_seeker, created_by=developer)

        # assert previous approval does not exist anymore.
        self.assertFalse(
            Approval.objects.filter(pk=previous_approval.pk).exists())
        # assert previous job application does not exist anymore.
        self.assertFalse(
            JobApplication.objects.filter(pk=job_application.pk).exists())
        # assert a new PASS IAE has been delivered.
        self.assertTrue(created)
        self.assertTrue(redelivered_approval)

        # Clean
        job_seeker.delete()

        # PASS created after November 30th with a job application but not sent by this employer.
        siae = SiaeWithMembershipFactory()
        previous_approval = ApprovalFactory(
            user__nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        job_seeker = previous_approval.user
        job_application = JobApplicationSentBySiaeFactory(
            job_seeker=job_seeker,
            state=JobApplicationWorkflow.STATE_ACCEPTED,
            approval=previous_approval,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_AUTOMATIC,
        )
        created, _, redelivered_approval = command.find_or_create_approval(
            job_seeker=job_seeker, created_by=developer)

        # assert previous approval does not exist anymore.
        self.assertFalse(
            Approval.objects.filter(pk=previous_approval.pk).exists())
        # assert previous job application does not exist anymore.
        self.assertFalse(
            JobApplication.objects.filter(pk=job_application.pk).exists())
        # assert a new PASS IAE has been delivered.
        self.assertTrue(created)
        self.assertTrue(redelivered_approval)

        # Clean
        job_seeker.delete()

        # Multiple accepted job applications linked to this approval. Raise an error if dry run is not set.
        siae = SiaeWithMembershipFactory()
        previous_approval = ApprovalFactory(
            user__nir=getattr(CleanedAiCsvFileMock(), NIR_COL))
        job_seeker = previous_approval.user
        job_application = JobApplicationSentBySiaeFactory(
            job_seeker=job_seeker,
            to_siae=siae,
            state=JobApplicationWorkflow.STATE_ACCEPTED,
            approval=previous_approval,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_AUTOMATIC,
        )
        JobApplicationSentBySiaeFactory(
            job_seeker=job_seeker,
            state=JobApplicationWorkflow.STATE_ACCEPTED,
            approval=previous_approval,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_AUTOMATIC,
        )

        created, approval, redelivered_approval = command.find_or_create_approval(
            job_seeker=job_seeker, created_by=developer)
        self.assertFalse(created)
        self.assertFalse(redelivered_approval)
        self.assertTrue(previous_approval.pk, approval.pk)
        job_seeker.delete()
Example #20
0
    def test_find_or_create_job_application__create(self):
        developer = UserFactory(
            email=settings.AI_EMPLOYEES_STOCK_DEVELOPER_EMAIL)
        command = self.command

        # Employers canceled the job application we created, hence removing the PASS IAE we delivered.
        # Remove those job applications and deliver a new PASS IAE.
        nir = getattr(CleanedAiCsvFileMock(), NIR_COL)
        siret = getattr(CleanedAiCsvFileMock(), SIRET_COL)
        approval = ApprovalFactory(user__nir=nir)
        df = pandas.DataFrame([CleanedAiCsvFileMock(**{SIRET_COL: siret})])
        job_application = JobApplicationSentBySiaeFactory(
            to_siae__kind=Siae.KIND_AI,
            to_siae__siret=siret,
            state=JobApplicationWorkflow.STATE_CANCELLED,
            job_seeker=approval.user,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_MANUAL,
            approval=None,
            approval_manually_delivered_by=developer,
            created_at=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
            hiring_start_at=df.iloc[0][CONTRACT_STARTDATE_COL],
        )
        created, new_job_application, cancelled_job_app_deleted = command.find_or_create_job_application(
            approval=approval,
            job_seeker=job_application.job_seeker,
            row=df.iloc[0],
            approval_manually_delivered_by=developer,
        )
        self.assertTrue(created)
        self.assertTrue(cancelled_job_app_deleted)
        # Assert employee records creation is blocked.
        self.assertNotIn(
            new_job_application,
            JobApplication.objects.eligible_as_employee_record(
                new_job_application.to_siae))
        self.assertEqual(new_job_application.approval.pk, approval.pk)
        self.assertFalse(
            JobApplication.objects.filter(pk=job_application.pk).exists())
        self.assertFalse(new_job_application.can_be_cancelled)
        self.assertTrue(new_job_application.is_from_ai_stock)
        self.assertEqual(JobApplication.objects.count(), 1)
        job_application.job_seeker.delete()

        # Different contract starting date.
        nir = getattr(CleanedAiCsvFileMock(), NIR_COL)
        approval = ApprovalFactory(user__nir=nir)
        siae = SiaeFactory(kind=Siae.KIND_AI)
        job_application = JobApplicationFactory(
            to_siae=siae,
            sender_siae=siae,
            job_seeker=approval.user,
            approval=approval,
            state=JobApplicationWorkflow.STATE_ACCEPTED,
            approval_delivery_mode=JobApplication.
            APPROVAL_DELIVERY_MODE_MANUAL,
            approval_manually_delivered_by=developer,
            created_at=settings.AI_EMPLOYEES_STOCK_IMPORT_DATE,
            hiring_start_at=datetime.date(2021, 1, 1),
        )
        df = pandas.DataFrame(
            [CleanedAiCsvFileMock(**{SIRET_COL: siae.siret})])
        created, new_job_application, cancelled_job_app_deleted = command.find_or_create_job_application(
            approval=job_application.approval,
            job_seeker=job_application.job_seeker,
            row=df.iloc[0],
            approval_manually_delivered_by=developer,
        )
        self.assertTrue(created)
        self.assertNotEqual(job_application.pk, new_job_application.pk)
        self.assertFalse(cancelled_job_app_deleted)
        job_application.job_seeker.delete()