Пример #1
0
    def find_job(self, job_title: str) -> Optional[job_pb2.Job]:
        """Find a job in Algolia index by its name."""

        result = self._index.search(job_title)
        hits = result['hits']
        job_group_ids = {job['jobGroupId'] for job in hits}

        # All job resuts are in the same job group.
        if len(job_group_ids) == 1:
            return job_pb2.Job(name=job_title,
                               job_group=job_pb2.JobGroup(
                                   rome_id=hits[0]['jobGroupId'],
                                   name=hits[0]['jobGroupName']))

        # The name matches exactly a job group.
        for job in hits:
            if job['jobGroupName'] == job_title:
                return job_pb2.Job(name=job_title,
                                   job_group=job_pb2.JobGroup(
                                       rome_id=job['jobGroupId'],
                                       name=job['jobGroupName']))

        logging.error('Could not find job "%s" in Algolia', job_title)

        self._missed.add(job_title)

        return None
Пример #2
0
    def test_only_two_projects(self) -> None:
        """The user only has two projects."""

        del self.persona.user.projects[:]
        self.persona.user.projects.extend([
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='B1234'))),
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='C1234'))),
        ])
        self._assert_fail_filter()
Пример #3
0
    def test_unclear_project(self) -> None:
        """Project is unclear."""

        self.persona.user.projects.extend([
            project_pb2.Project(target_job=job_pb2.Job(
                job_group=job_pb2.JobGroup(rome_id='A1234'))),
            project_pb2.Project(target_job=job_pb2.Job(
                job_group=job_pb2.JobGroup(rome_id='B1234'))),
            project_pb2.Project(target_job=job_pb2.Job(
                job_group=job_pb2.JobGroup(rome_id='C1234'))),
        ])
        self._assert_fail_filter()
Пример #4
0
    def test_too_many_projects(self) -> None:
        """The user has too many projects."""

        self.persona.user.projects.extend([
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='A1234'))),
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='B1234'))),
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='C1234'))),
        ])
        self._assert_pass_filter()
Пример #5
0
    def test_dynamic_sticky_steps(self):
        """Check that dynamic fields of sticky steps are populated."""
        new_action = action_pb2.Action()
        database = mongomock.MongoClient().test
        database.sticky_action_steps.insert_one({
            '_id': 'step1',
            'title': 'Trouver un job de %masculineJobName',
            'content': 'Regarder sur le [ROME](http://go/rome/%romeId).',
            'link': 'http://lbb.fr/city/%cityId/rome/%romeId',
            'linkName': 'Les bonnes boites de %cityName',
            'finishCheckboxCaption': "J'ai trouvé un job de %masculineJobName",
        })
        action.instantiate(
            new_action,
            user_pb2.User(),
            project_pb2.Project(
                mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                    city_id='45123',
                    name='Orléans',
                    departement_id='45',
                    region_id='84')),
                target_job=job_pb2.Job(
                    masculine_name='Pompier',
                    code_ogr='78910',
                    job_group=job_pb2.JobGroup(rome_id='A1101', name='Combattants')),
            ),
            action_pb2.ActionTemplate(
                action_template_id='my-sticky',
                step_ids=['step1']),
            set(), database, None)

        step = new_action.steps[0]
        self.assertEqual('http://lbb.fr/city/45123/rome/A1101', step.link)
        self.assertEqual('Regarder sur le [ROME](http://go/rome/A1101).', step.content)
Пример #6
0
    def test_advice_job_boards_extra_data(self):
        """Test that the advisor computes extra data for the "Find a Job Board" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(
                rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='14')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.jobboards.insert_one({
            'title': 'Indeed',
            'filters': ['for-departement(14)']
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'job-boards',
            'triggerScoringModel': 'advice-job-boards',
            'extraDataFieldName': 'job_boards_data',
            'isReadyForProd': True,
        })
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices
                      if a.advice_id == 'job-boards')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual('Indeed', advice.job_boards_data.job_board_title)
        self.assertFalse(advice.job_boards_data.is_specific_to_job_group)
        self.assertTrue(advice.job_boards_data.is_specific_to_region)
Пример #7
0
    def test_advice_other_work_env_extra_data(self):
        """Test that the advisor computes extra data for the work environment advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='A1234')),
        )
        self.user.features_enabled.alpha = True
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'workEnvironmentKeywords': {
                'structures': ['A', 'B'],
                'sectors': ['sector Toise', 'sector Gal'],
            },
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'other-work-env',
            'triggerScoringModel': 'advice-other-work-env',
            'extraDataFieldName': 'other_work_env_advice_data',
            'isReadyForProd': True,
        })

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'other-work-env')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual(
            ['A', 'B'], advice.other_work_env_advice_data.work_environment_keywords.structures)
        self.assertEqual(
            ['sector Toise', 'sector Gal'],
            advice.other_work_env_advice_data.work_environment_keywords.sectors)
Пример #8
0
    def test_advice_spontaneous_application_extra_data(self, mock_get_lbb_companies):
        """Test that the advisor computes extra data for the "Spontaneous Application" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(departement_id='14')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.local_diagnosis.insert_one({
            '_id': '14:A1234',
            'imt': {'applicationModes': {'Foo': {'first': 'SPONTANEOUS_APPLICATION'}}},
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'triggerScoringModel': 'chantier-spontaneous-application',
            'extraDataFieldName': 'spontaneous_application_data',
            'isReadyForProd': True,
        })
        mock_get_lbb_companies.return_value = iter([
            {'name': 'EX NIHILO'},
            {'name': 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'},
        ])
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual(
            ['EX NIHILO', 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'],
            [c.name for c in advice.spontaneous_application_data.companies])
Пример #9
0
def _get_best_departements_for_job_group(
        rome_id: str, database: pymongo.database.Database) -> List[str]:
    """Get departements with best market stress for a job group."""

    best_departements = (proto.fetch_from_mongo(database, job_pb2.JobGroup,
                                                'job_group_info', rome_id)
                         or job_pb2.JobGroup()).best_departements[:2]
    return [dep.departement_id for dep in best_departements]
Пример #10
0
 def test_unknown_field(self):
     """Unknown fields do not make the function choke."""
     job_group = job_pb2.JobGroup()
     self.assertTrue(
         proto.parse_from_mongo({
             'romeId': 'A123',
             'unknownField': 14
         }, job_group))
     self.assertEqual('A123', job_group.rome_id)
Пример #11
0
    def test_advice_spontaneous_application_extra_data(self,
                                                       mock_get_lbb_companies):
        """Test that the advisor computes extra data for the "Spontaneous Application" advice."""

        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(
                rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='14')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }, {
                        'percentage': 29.46,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }],
                }
            },
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'categories': ['first'],
            'triggerScoringModel': 'advice-spontaneous-application',
            'extraDataFieldName': 'spontaneous_application_data',
            'isReadyForProd': True,
        })
        mock_get_lbb_companies.return_value = iter([
            {
                'name': 'EX NIHILO'
            },
            {
                'name': 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'
            },
        ])
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual(
            ['EX NIHILO', 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'],
            [c.name for c in advice.spontaneous_application_data.companies])
Пример #12
0
    def job_group_info(self) -> job_pb2.JobGroup:
        """Get the info for job group info."""

        if self._job_group_info is not None:
            return self._job_group_info

        self._job_group_info = jobs.get_group_proto(
            self.database, self._rome_id(), self.user_profile.locale) or job_pb2.JobGroup()
        return self._job_group_info
Пример #13
0
    def test_advice_better_job_in_group_extra_data(self):
        """Test that the advisor computes extra data for the "Better Job in Group" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(
                code_ogr='1234', job_group=job_pb2.JobGroup(rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='14')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.job_group_info.insert_one({
            '_id':
            'A1234',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'Pilote'
                },
                {
                    'codeOgr': '5678',
                    'name': 'Pompier'
                },
                {
                    'codeOgr': '9012',
                    'name': 'Facteur'
                },
            ],
            'requirements': {
                'specificJobs': [
                    {
                        'codeOgr': '5678',
                        'percentSuggested': 55,
                    },
                    {
                        'codeOgr': '1234',
                        'percentSuggested': 45,
                    },
                ],
            },
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'triggerScoringModel': 'advice-better-job-in-group',
            'extraDataFieldName': 'better_job_in_group_data',
            'isReadyForProd': True,
        })
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual('Pompier',
                         advice.better_job_in_group_data.better_job.name)
        self.assertEqual(1, advice.better_job_in_group_data.num_better_jobs)
Пример #14
0
 def get_jobs(
         self, *, allowed_job_ids: Set[str], **unused_kwargs: Any) -> Optional[_ComputedSection]:
     seed = _create_random_seed()
     randomizer = random.Random(seed)
     num_jobs = min(self._num_jobs_for_first_batch, len(allowed_job_ids))
     return _ComputedSection(
         [
             upskilling_pb2.Job(job_group=job_pb2.JobGroup(rome_id=rome_id))
             for rome_id in randomizer.sample(allowed_job_ids, num_jobs)
         ],
         state=seed)
Пример #15
0
def get_job_group_jobs(rome_id):
    """Retrieve information about jobs whithin a job group."""
    job_group = _job_groups_info().get(rome_id)
    if not job_group:
        flask.abort(404, 'Groupe de métiers "%s" inconnu.' % rome_id)

    result = job_pb2.JobGroup()
    result.jobs.extend(job_group.jobs)
    result.requirements.specific_jobs.extend(
        job_group.requirements.specific_jobs)
    return result
Пример #16
0
    def test_advice_specific_to_job_override(self) -> None:
        """Test that the advisor overrides some advice data with the "Specific to Job" module."""

        project = project_pb2.Project(target_job=job_pb2.Job(
            job_group=job_pb2.JobGroup(rome_id='D1102')), )
        self.database.advice_modules.insert_one({
            'adviceId': 'custom-advice-id',
            'categories': ['first'],
            'triggerScoringModel': 'advice-specific-to-job',
            'isReadyForProd': True,
        })
        self.database.specific_to_job_advice.insert_one({
            'title':
            'Présentez-vous au chef boulanger dès son arrivée tôt le matin',
            'shortTitle':
            'Astuces de boulanger',
            'goal':
            'impressionner le patron',
            'diagnosticTopics': [
                diagnostic_pb2.MARKET_DIAGNOSTIC,
                diagnostic_pb2.PROJECT_DIAGNOSTIC
            ],
            'filters': ['for-job-group(D1102)', 'not-for-job(12006)'],
            'cardText':
            'Allez à la boulangerie la veille pour savoir à quelle '
            'heure arrive le chef boulanger.',
            'expandedCardHeader':
            "Voilà ce qu'il faut faire",
            'expandedCardItems': [
                'Se présenter aux boulangers entre 4h et 7h du matin.',
                'Demander au vendeur / à la vendeuse à quelle heure arrive le chef le matin',
                'Contacter les fournisseurs de farine locaux : ils connaissent '
                'tous les boulangers du coin et sauront où il y a des '
                'embauches.',
            ],
        })

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices
                      if a.advice_id == 'custom-advice-id')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual(
            'Présentez-vous au chef boulanger dès son arrivée tôt le matin',
            advice.title)
        self.assertEqual("Voilà ce qu'il faut faire",
                         advice.expanded_card_header)
        self.assertTrue(advice.card_text)
        self.assertTrue(advice.expanded_card_items)
        self.assertEqual('Astuces de boulanger', advice.short_title)
        self.assertEqual([
            diagnostic_pb2.MARKET_DIAGNOSTIC, diagnostic_pb2.PROJECT_DIAGNOSTIC
        ], advice.diagnostic_topics)
        self.assertEqual('impressionner le patron', advice.goal)
Пример #17
0
    def get_more_jobs(
            self, *, scoring_project: scoring.ScoringProject, section_id: str,  # pylint: disable=unused-argument
            state: str) -> upskilling_pb2.Section:
        """Generate more jobs for a given section."""

        randomizer = random.Random(state)
        good_jobs = jobs.get_all_good_job_group_ids(scoring_project.database)
        num_jobs = len(good_jobs) if self.max_jobs is None else min(self.max_jobs, len(good_jobs))
        return upskilling_pb2.Section(jobs=[
            upskilling_pb2.Job(job_group=job_pb2.JobGroup(rome_id=rome_id))
            for rome_id in randomizer.sample(good_jobs, num_jobs)[self._num_jobs_for_first_batch:]
        ])
Пример #18
0
    def test_advice_spontaneous_application_extra_data(
            self, mock_get_lbb_companies: mock.MagicMock) -> None:
        """Test that the advisor computes extra data for the "Spontaneous Application" advice."""

        persona = self._random_persona().clone()
        persona.project.CopyFrom(
            project_pb2.Project(
                target_job=job_pb2.Job(job_group=job_pb2.JobGroup(
                    rome_id='A1234')),
                weekly_applications_estimate=project_pb2.A_LOT,
                employment_types=[job_pb2.CDI],
                total_interview_count=1,
            ))
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=210))
        persona.project.city.departement_id = '14'

        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }, {
                        'percentage': 29.46,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }],
                }
            },
        })
        mock_get_lbb_companies.return_value = iter([
            {
                'name': 'EX NIHILO'
            },
            {
                'name': 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'
            },
        ])

        extra_data = typing.cast(project_pb2.SpontaneousApplicationData,
                                 self._compute_expanded_card_data(persona))
        self.assertEqual(['EX NIHILO', 'M.F.P MULTIMEDIA FRANCE PRODUCTIONS'],
                         [c.name for c in extra_data.companies])
        self.assertEqual(10, extra_data.max_distance_to_companies_km)
Пример #19
0
    def find_job(self, job_title: str) -> Optional[job_pb2.Job]:
        """Find a job in Algolia index by its name."""

        try:
            return job_pb2.Job(
                name=job_title,
                job_group=job_pb2.JobGroup(rome_id=self._mapping[job_title]))
        except KeyError:
            logging.exception('Could not find job "%s" in Excel file',
                              job_title)
            self._missed.add(job_title)

        return None
Пример #20
0
 def test_weird_objects(self, mock_warning):
     """Raises a TypeError when an object is not of the right type."""
     job_group = job_pb2.JobGroup()
     self.assertFalse(proto.parse_from_mongo({'romeId': 123}, job_group))
     mock_warning.assert_called_once()
     self.assertEqual(
         'Error %s while parsing a JSON dict for proto type %s:\n%s',
         mock_warning.call_args[0][0])
     self.assertEqual(
         'Failed to parse romeId field: expected string or bytes-like object.',
         str(mock_warning.call_args[0][1]))
     self.assertEqual('JobGroup', str(mock_warning.call_args[0][2]))
     self.assertEqual("{'romeId': 123}", str(mock_warning.call_args[0][3]))
Пример #21
0
 def get_jobs(
         self, *, scoring_project: scoring.ScoringProject, **unused_kwargs: Any,
 ) -> Optional[_ComputedSection]:
     seed = _create_random_seed()
     safe_jobs = jobs.get_all_good_job_group_ids(
         scoring_project.database, automation_risk_threshold=self.automation_risk_threshold,
         unknown_risk_value=50)
     randomizer = random.Random(seed)
     num_jobs = min(self._num_jobs_for_first_batch, len(safe_jobs))
     return _ComputedSection(
         [
             upskilling_pb2.Job(job_group=job_pb2.JobGroup(rome_id=rome_id))
             for rome_id in randomizer.sample(safe_jobs, num_jobs)
         ],
         state=seed)
Пример #22
0
    def test_advice_improve_success_rate_extra_data(self):
        """Test that the advisor computes extra data for the "Improve Success Rate" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(
                rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='14')),
            job_search_length_months=6,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.local_diagnosis.insert_one({
            '_id': '14:A1234',
            'imt': {
                'yearlyAvgOffersDenominator': 10,
                'yearlyAvgOffersPer10Candidates': 2,
            },
        })
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'requirements': {
                'skills': [{
                    'name': 'Humour'
                }, {
                    'name': 'Empathie'
                }],
                'skillsShortText': '**Humour** et **empathie**',
            },
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'improve-success',
            'triggerScoringModel': 'advice-improve-resume',
            'extraDataFieldName': 'improve_success_rate_data',
            'isReadyForProd': True,
        })
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices
                      if a.advice_id == 'improve-success')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertGreater(
            advice.improve_success_rate_data.num_interviews_increase, 50)
        self.assertFalse(advice.improve_success_rate_data.requirements.skills)
        self.assertEqual(
            '**Humour** et **empathie**',
            advice.improve_success_rate_data.requirements.skills_short_text)
Пример #23
0
    def test_advice_events_extra_data(self, mock_now):
        """Test that the advisor computes extra data for the "Events" advice."""
        mock_now.return_value = datetime.datetime(2017, 8, 15)
        project = project_pb2.Project(
            target_job=job_pb2.Job(
                code_ogr='1234', job_group=job_pb2.JobGroup(rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='75')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'triggerScoringModel': 'advice-event',
            'extraDataFieldName': 'events_data',
            'isReadyForProd': True,
        })
        self.database.events.insert_many([
            {
                'title': 'AP HEROS CANDIDATS MADIRCOM - BORDEAUX',
                'link':
                'https://www.workuper.com/events/ap-heros-candidats-madircom-bordeaux',
                'organiser': 'MADIRCOM',
                'startDate': '2017-08-29',
            },
            {
                'title':
                'Le Salon du Travail et de la Mobilité Professionnelle',
                'link':
                'https://www.workuper.com/events/le-salon-du-travail-et-de-la-mobilite-'
                'professionnelle',
                'organiser':
                'Altice Media Events',
                'startDate':
                '2018-01-19',
            },
        ])
        advisor.clear_cache()
        self.user.features_enabled.alpha = True

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual('AP HEROS CANDIDATS MADIRCOM - BORDEAUX',
                         advice.events_data.event_name)
Пример #24
0
    def test_jobgroup_info_fr_locale(self) -> None:
        """A scoring project can be represented as a meaningful string."""

        user = user_pb2.User()
        user.profile.locale = ''
        database = mongomock.MongoClient().test
        database.job_group_info.insert_many([{
            '_id': 'A1234',
            'name': 'french'
        }, {
            '_id': 'nl:A1234',
            'name': 'dutch'
        }])
        project = project_pb2.Project(target_job=job_pb2.Job(
            job_group=job_pb2.JobGroup(rome_id='A1234')))
        scoring_project = scoring.ScoringProject(project, user, database)
        job_group_info = scoring_project.job_group_info()
        self.assertEqual('french', job_group_info.name)
Пример #25
0
    def test_advice_specific_to_job_override_i18n(self) -> None:
        """Test that the advisor translate overrides with the "Specific to Job" module."""

        self.user.profile.locale = 'en'
        self.database.translations.insert_many([
            {'string': 'specificToJobAdvice:baker:title', 'en': 'Get there early'},
            {'string': 'Astuces de boulanger', 'en': 'Baker tips'},
        ])
        project = project_pb2.Project(
            target_job=job_pb2.Job(job_group=job_pb2.JobGroup(rome_id='D1102')),
        )
        self.database.advice_modules.insert_one({
            'adviceId': 'custom-advice-id',
            'categories': ['first'],
            'triggerScoringModel': 'advice-specific-to-job',
            'isReadyForProd': True,
        })
        self.database.specific_to_job_advice.insert_one({
            'id': 'baker',
            'title': 'Présentez-vous au chef boulanger dès son arrivée tôt le matin',
            'shortTitle': 'Astuces de boulanger',
            'goal': 'impressionner le patron',
            'filters': ['for-job-group(D1102)', 'not-for-job(12006)'],
            'cardText':
            'Allez à la boulangerie la veille pour savoir à quelle '
            'heure arrive le chef boulanger.',
            'expandedCardHeader': "Voilà ce qu'il faut faire",
            'expandedCardItems': [
                'Se présenter aux boulangers entre 4h et 7h du matin.',
                'Demander au vendeur / à la vendeuse à quelle heure arrive le chef le matin',
                'Contacter les fournisseurs de farine locaux : ils connaissent '
                'tous les boulangers du coin et sauront où il y a des '
                'embauches.',
            ],
        })

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'custom-advice-id')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual('Get there early', advice.title)
        self.assertEqual('Baker tips', advice.short_title)
Пример #26
0
    def test_advice_volunteer_extra_data(self):
        """Test that the advisor computes extra data for the "Volunteer" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(
                code_ogr='1234', job_group=job_pb2.JobGroup(rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='75')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.volunteering_missions.insert_one({
            '_id':
            '75',
            'missions': [
                {
                    'associationName': 'BackUp Rural'
                },
                {
                    'associationName': 'Construisons Ensemble Comment Faire'
                },
            ],
        })
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'triggerScoringModel': 'advice-volunteer',
            'extraDataFieldName': 'volunteer_data',
            'isReadyForProd': True,
        })
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual(
            ['BackUp Rural', 'Construisons Ensemble Comment Faire'],
            sorted(advice.volunteer_data.association_names))
Пример #27
0
    def test_advice_association_help_extra_data(self):
        """Test that the advisor computes extra data for the "Find an association" advice."""
        project = project_pb2.Project(
            target_job=job_pb2.Job(
                code_ogr='1234', job_group=job_pb2.JobGroup(rome_id='A1234')),
            mobility=geo_pb2.Location(city=geo_pb2.FrenchCity(
                departement_id='14')),
            job_search_length_months=7,
            weekly_applications_estimate=project_pb2.A_LOT,
            total_interview_count=1,
        )
        self.database.associations.insert_many([
            {
                'name': 'Pôle emploi'
            },
            {
                'name': 'SNC',
                'filters': ['for-departement(14,15,16)']
            },
            {
                'name': 'Ressort',
                'filters': ['for-departement(69)']
            },
        ])
        self.database.advice_modules.insert_one({
            'adviceId': 'my-advice',
            'triggerScoringModel': 'advice-association-help',
            'extraDataFieldName': 'associations_data',
            'isReadyForProd': True,
        })
        advisor.clear_cache()

        advisor.maybe_advise(self.user, project, self.database)

        advice = next(a for a in project.advices if a.advice_id == 'my-advice')
        self.assertEqual(project_pb2.ADVICE_RECOMMENDED, advice.status)
        self.assertEqual('SNC', advice.associations_data.association_name)
Пример #28
0
    def get_expanded_card_data(self, project: scoring_base.ScoringProject) \
            -> job_pb2.SafeJobGroups:
        """Retrieve data for the expanded card."""

        has_any_covid_risk_info = jobs.has_covid_risk_info(project.database)
        has_any_automation_risk_info = jobs.has_automation_risk_info(
            project.database)

        good_jobs = jobs.get_all_good_job_group_ids(
            project.database, automation_risk_threshold=30)
        return job_pb2.SafeJobGroups(
            job_groups=[
                job_pb2.JobGroup(
                    name=typing.cast(
                        job_pb2.JobGroup,
                        jobs.get_group_proto(project.database,
                                             job_group_id)).name,
                    rome_id=job_group_id,
                ) for job_group_id in random.sample(good_jobs,
                                                    min(20, len(good_jobs)))
            ],
            is_safe_from_automation=has_any_automation_risk_info,
            is_safe_from_covid=has_any_covid_risk_info,
        )
Пример #29
0
    (user_profile_pb2.UNKNOWN_JOB_SEARCH_FRUSTRATION, 'start-your-search'),
    'toughmkt':
    (user_profile_pb2.UNKNOWN_JOB_SEARCH_FRUSTRATION, 'stuck-market'),
    'training': (user_profile_pb2.UNKNOWN_JOB_SEARCH_FRUSTRATION,
                 'get-diploma'),
}

# A map of US states. Exported to be mocked in tests.
STATE_MAP: dict[str, str] = {}

_JOB_FINDERS: list[Callable[[str], Optional[job_pb2.Job]]] = []

_JOB_MAP = {
    'Computer Systems Engineers/Architects':
    job_pb2.JobGroup(
        name='Software Developers, Systems Software',
        rome_id='15-1133',
    ),
    'IT Security Analyst (Information Technology Security Analyst)':
    job_pb2.JobGroup(
        name='Information Security Analysts',
        rome_id='15-1122',
    ),
    'White Sugar Supervisor':
    job_pb2.JobGroup(
        name='First-Line Supervisors of Production and Operating Workers',
        rome_id='51-1011',
    ),
    'Informatics Nurse Specialists':
    job_pb2.JobGroup(
        name='Health Informatics Specialists',
        rome_id='15-1211',
Пример #30
0
 def _func():
     job = job_pb2.JobGroup()
     job.rome_id = 'A1234'
     return job