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
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()
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()
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()
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)
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)
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)
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])
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]
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)
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])
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
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)
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)
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
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)
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:] ])
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)
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
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]))
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)
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)
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)
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)
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)
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))
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)
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, )
(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',
def _func(): job = job_pb2.JobGroup() job.rome_id = 'A1234' return job