class AdviceCreateYourCompanyTestCase(
        scoring_test.ScoringModelTestBase('advice-create-your-company')):
    """Unit tests for the "Create your company" scoring model."""
    def test_too_late(self):
        """Test the score after the date of all events."""

        persona = self._random_persona().clone()
        self.now = datetime.datetime(2018, 2, 25)
        score = self._score_persona(persona)
        self.assertEqual(0, score, msg='Fail for "{}"'.format(persona.name))

    def test_atypic_profile(self):
        """Test the scoring function before the events with an atypic profile."""

        persona = self._random_persona().clone()
        self.now = datetime.datetime(2018, 1, 25)
        persona.user_profile.frustrations.append(user_pb2.ATYPIC_PROFILE)
        score = self._score_persona(persona)
        self.assertEqual(2, score, msg='Fail for "{}"'.format(persona.name))

    def test_not_really_needed_yet(self):
        """Test the scoring function for someone that has just started their search."""

        persona = self._random_persona().clone()
        self.now = datetime.datetime(2018, 1, 25)
        del persona.user_profile.frustrations[:]
        persona.project.job_search_has_not_started = False
        persona.project.job_search_started_at.FromDatetime(
            datetime.datetime(2018, 12, 14))
        score = self._score_persona(persona)
        self.assertEqual(1, score, msg='Fail for "{}"'.format(persona.name))
Exemple #2
0
class AdviceCivicServiceTestCase(
        scoring_test.ScoringModelTestBase('advice-civic-service')):
    """Unit tests for the civic service advice scoring model."""
    def setUp(self):
        super(AdviceCivicServiceTestCase, self).setUp()
        self.now = datetime.datetime(2018, 2, 2)

    def test_is_young_with_handicap(self):
        """User already is young and has handicap."""

        persona = self._random_persona().clone()
        persona.user_profile.has_handicap = user_pb2.TRUE
        persona.user_profile.year_of_birth = 1989
        persona.project.seniority = project_pb2.INTERNSHIP
        score = self._score_persona(persona)

        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_is_young_without_handicap(self):
        """User is young and has no handicap."""

        persona = self._random_persona().clone()
        persona.user_profile.has_handicap = user_pb2.FALSE
        persona.user_profile.year_of_birth = 1995
        persona.project.seniority = project_pb2.INTERNSHIP
        score = self._score_persona(persona)

        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_is_too_old(self):
        """User is older than required age for civic service."""

        persona = self._random_persona().clone()
        persona.user_profile.has_handicap = user_pb2.FALSE
        persona.user_profile.year_of_birth = 1987
        persona.project.seniority = project_pb2.INTERNSHIP
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_is_too_young(self):
        """User is younger than required age for civic service."""

        persona = self._random_persona().clone()
        persona.user_profile.year_of_birth = 2007
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_has_experience(self):
        """User has too much experience."""

        persona = self._random_persona().clone()
        persona.project.seniority = project_pb2.JUNIOR
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))
Exemple #3
0
    class _TestCase(scoring_test.ScoringModelTestBase(model_id)):
        def setUp(self):
            super(_TestCase, self).setUp()
            self.persona = self._random_persona().clone()

        def _assert_pass_filter(self):
            score = self._score_persona(self.persona)
            self.assertGreater(score,
                               0,
                               msg='Failed for "{}"'.format(self.persona.name))

        def _assert_fail_filter(self):
            score = self._score_persona(self.persona)
            self.assertLessEqual(score,
                                 0,
                                 msg='Failed for "{}"'.format(
                                     self.persona.name))
class VolunteerAdviceTestCase(scoring_test.ScoringModelTestBase('advice-volunteer')):
    """Unit tests for the "Volunteer" advice."""

    def setUp(self):
        super(VolunteerAdviceTestCase, self).setUp()
        self.database.volunteering_missions.insert_one({
            '_id': '75',
            'missions': [{'title': 'Mission n°1'}],
        })

    def test_no_mission_data(self):
        """No volunteering missions data."""

        persona = self._random_persona().clone()
        persona.project.mobility.city.departement_id = '56'

        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_very_long_search(self):
        """Job seeker has been searching for a looong time."""

        persona = self._random_persona().clone()
        persona.project.mobility.city.departement_id = '75'
        persona.project.job_search_length_months = 20
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() - datetime.timedelta(days=610))

        score = self._score_persona(persona)

        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_just_started_searching(self):
        """Job seeker has just started searching."""

        persona = self._random_persona().clone()
        persona.project.mobility.city.departement_id = '75'
        persona.project.job_search_length_months = 1
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() - datetime.timedelta(days=30.5))

        score = self._score_persona(persona)

        self.assertEqual(score, 1, msg='Failed for "{}"'.format(persona.name))
class AdviceImproveInterviewTestCase(
        scoring_test.ScoringModelTestBase('advice-improve-interview')):
    """Unit tests for the "Improve Your Interview Skills" advice."""
    def test_not_enough_interviews(self):
        """Users does not get enough interviews."""

        persona = self._random_persona().clone()
        if persona.project.job_search_length_months < 3:
            persona.project.job_search_length_months = 3
        if persona.project.job_search_length_months > 6:
            persona.project.job_search_length_months = 6
        persona.project.total_interview_count = 1
        score = self._score_persona(persona)
        self.assertEqual(score, 0, msg='Failed for "{}":'.format(persona.name))

    def test_many_interviews(self):
        """Users has maximum interviews."""

        persona = self._random_persona().clone()
        persona.project.total_interview_count = 21
        persona.project.job_search_length_months = 2
        if persona.project.job_search_length_months > 6:
            persona.project.job_search_length_months = 6
        score = self._score_persona(persona)
        self.assertEqual(score, 3, msg='Failed for "{}":'.format(persona.name))

    def test_many_interviews_long_time(self):
        """Users has maximum interviews."""

        persona = self._random_persona().clone()
        persona.project.total_interview_count = 21
        if persona.project.job_search_length_months > 6:
            persona.project.job_search_length_months = 6
        score = self._score_persona(persona)
        self.assertGreaterEqual(score,
                                3,
                                msg='Failed for "{}":'.format(persona.name))
class DrivingLicenseWrittenScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-driving-license-written')):
    """Unit tests for the "Prepare your driving license written exam" advice."""
    def _create_scoreable_persona(self):
        """Assumes user does not have CAR driving license,
        is old enough and has been searching for some time.
        """

        self.now = datetime.datetime(2018, 2, 2)
        persona = self._random_persona().clone()
        persona.user_profile.year_of_birth = 2000
        persona.user_profile.has_car_driving_license = user_pb2.FALSE
        return persona

    def test_already_has_license(self):
        """User already has driving license."""

        persona = self._random_persona().clone()
        persona.user_profile.has_car_driving_license = user_pb2.TRUE
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_license_status_unknown(self):
        """We don't know whether user has driving license."""

        persona = self._random_persona().clone()
        persona.user_profile.ClearField('has_car_driving_license')
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_is_too_young(self):
        """User is younger than required age for 1 euro driving license program."""

        self.now = datetime.datetime(2018, 2, 2)
        persona = self._random_persona().clone()
        persona.user_profile.year_of_birth = 2004
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_big_city_not_required(self):
        """User lives in a large enough city, and job doesn't need a car."""

        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'requirements': {
                'drivingLicenses': [],
            },
        })
        persona = self._random_persona().clone()
        persona.project.mobility.city.urban_score = 7
        persona.project.mobility.city.public_transportation_score = 7
        persona.project.target_job.job_group.rome_id = 'A1234'
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_required_by_job(self):
        """Job group expects people to have a car."""

        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'requirements': {
                'drivingLicenses': [{
                    'drivingLicense': 'CAR',
                    'percentRequired': 50,
                }],
            },
        })
        persona = self._create_scoreable_persona()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.mobility.city.urban_score = 7
        score = self._score_persona(persona)

        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_small_city(self):
        """Small town people need cars more often."""

        persona = self._create_scoreable_persona()
        persona.project.mobility.city.urban_score = 5
        persona.project.mobility.city.public_transportation_score = 7
        score = self._score_persona(persona)

        self.assertGreaterEqual(score,
                                1,
                                msg='Failed for "{}"'.format(persona.name))

    def test_bad_transport_city(self):
        """City with bad public transportations forces people to use cars."""

        persona = self._create_scoreable_persona()
        persona.project.mobility.city.urban_score = 7
        persona.project.mobility.city.public_transportation_score = 3.2
        score = self._score_persona(persona)

        self.assertGreaterEqual(score,
                                1,
                                msg='Failed for "{}"'.format(persona.name))
class AdviceBetterJobInGroupTestCase(
        scoring_test.ScoringModelTestBase('advice-better-job-in-group')):
    """Unit tests for the "Find a better job in job group" advice."""
    def test_no_data(self):
        """No data for job group."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        self.database.job_group_info.insert_one({
            '_id':
            'A1234',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'foo'
                },
                {
                    'codeOgr': '5678',
                    'name': 'foo'
                },
            ],
        })
        score = self._score_persona(persona)
        self.assertLessEqual(score,
                             0,
                             msg='Failed for "{}"'.format(persona.name))

    def test_should_try_other_job(self):
        """There's a job with way more offers, and the user wants to reorient."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.target_job.code_ogr = '5678'
        persona.project.kind = project_pb2.REORIENTATION
        self.database.job_group_info.insert_one({
            '_id':
            'A1234',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'foo'
                },
                {
                    'codeOgr': '5678',
                    'name': 'foo'
                },
            ],
            'requirements': {
                'specificJobs': [{
                    'codeOgr': '1234',
                    'percentSuggested': 100,
                }],
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 3, msg='Failed for "{}"'.format(persona.name))

    def test_already_best_job(self):
        """User is targetting the best job in their group."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.target_job.code_ogr = '1234'
        self.database.job_group_info.insert_one({
            '_id':
            'A1234',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'foo'
                },
                {
                    'codeOgr': '5678',
                    'name': 'foo'
                },
            ],
            'requirements': {
                'specificJobs': [{
                    'codeOgr': '1234',
                    'percentSuggested': 100,
                }],
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_already_good_job(self):
        """User is targetting a correct job in their group, but not the best."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.target_job.code_ogr = '1234'
        persona.project.job_search_length_months = 2
        persona.project.kind = project_pb2.FIND_A_FIRST_JOB
        self.database.job_group_info.insert_one({
            '_id':
            'A1234',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'foo'
                },
                {
                    'codeOgr': '5678',
                    'name': 'foo'
                },
            ],
            'requirements': {
                'specificJobs': [
                    {
                        'codeOgr': '5678',
                        'percentSuggested': 50,
                    },
                    {
                        'codeOgr': '1234',
                        'percentSuggested': 45,
                    },
                ],
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_bad_job_group(self):
        """Never recommend a reconversion inside this job group, it's too diverse."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'K2401'
        persona.project.target_job.code_ogr = '5678'
        persona.project.kind = project_pb2.REORIENTATION
        self.database.job_group_info.insert_one({
            '_id':
            'K2401',
            'jobs': [
                {
                    'codeOgr': '1234',
                    'name': 'foo'
                },
                {
                    'codeOgr': '5678',
                    'name': 'foo'
                },
            ],
            'requirements': {
                'specificJobs': [{
                    'codeOgr': '1234',
                    'percentSuggested': 100,
                }],
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))
Exemple #8
0
class AdviceEventScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-event')):
    """Unit test for the "Event Advice" scoring model."""
    def setUp(self):
        super(AdviceEventScoringModelTestCase, self).setUp()
        self.persona = self._random_persona().clone()
        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',
            },
        ])

    def test_important_application(self):
        """Network is important for the user."""

        self.persona.project.target_job.job_group.rome_id = 'A1234'
        self.persona.project.mobility.city.departement_id = '69'
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 29.46,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }],
                }
            },
        })
        score = self._score_persona(self.persona)
        self.assertGreaterEqual(score,
                                2,
                                msg='Fail for "{}"'.format(self.persona.name))

    def test_unimportant_application(self):
        """Network is important for the user."""

        self.persona.project.target_job.job_group.rome_id = 'A1234'
        self.persona.project.mobility.city.departement_id = '69'
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }, {
                        'percentage': 29.46,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }],
                }
            },
        })
        score = self._score_persona(self.persona)
        self.assertLessEqual(score,
                             1,
                             msg='Fail for "{}"'.format(self.persona.name))
class ImproveYourNetworkScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-improve-network')):
    """Unit test for the "Improve your network" scoring model."""
    def setUp(self):  # pylint: disable=missing-docstring,invalid-name
        super(ImproveYourNetworkScoringModelTestCase, self).setUp()
        self.persona = self._random_persona().clone()

    def test_strong_network(self):
        """User already has a strong or good enough network."""

        if self.persona.project.network_estimate < 2:
            self.persona.project.network_estimate = 2
        score = self._score_persona(self.persona)
        self.assertLessEqual(score,
                             0,
                             msg='Fail for "{}"'.format(self.persona.name))

    def test_network_is_best_application_mode(self):
        """User is in a job that hires a lot through network."""

        self.persona = self._clone_persona('malek')
        self.persona.project.network_estimate = 1
        self.persona.project.target_job.job_group.rome_id = 'A1234'
        self.persona.project.mobility.city.departement_id = '69'
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 29.46,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }],
                }
            },
        })
        score = self._score_persona(self.persona)
        self.assertGreaterEqual(score,
                                3,
                                msg='Fail for "{}"'.format(self.persona.name))

    def test_network_is_not_the_best_application_mode(self):
        """User is in a job that does not use network a lot to hire."""

        self.persona.project.network_estimate = 1
        self.persona.project.target_job.job_group.rome_id = 'A1234'
        self.persona.project.mobility.city.departement_id = '69'
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }, {
                        'percentage': 29.46,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }],
                }
            },
        })
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         2,
                         msg='Fail for "{}"'.format(self.persona.name))

    def test_network_is_not_always_the_best_application_mode(self):
        """User is in a job that does not use only network to hire."""

        self.persona.project.network_estimate = 1
        self.persona.project.target_job.job_group.rome_id = 'A1234'
        self.persona.project.mobility.city.departement_id = '69'
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'Foo': {
                    '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'
                    }],
                },
                'Bar': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }, {
                        'percentage': 29.46,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }, {
                        'percentage': 18.38,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 15.78,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }],
                }
            },
        })
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         2,
                         msg='Fail for "{}"'.format(self.persona.name))

    def test_get_advice_override(self):
        """Override advice card text."""

        self.database.contact_lead.insert_one({
            'cardContent':
            'Contactez des amis qui ont un emploi %ofJobName %inCity.',
        })
        self.persona.user_profile.gender = user_pb2.FEMININE
        self.persona.project.target_job.feminine_name = 'Hôtesse'
        self.persona.project.mobility.city.name = 'Lyon'
        override = self.model.get_advice_override(
            self.persona.scoring_project(self.database), None)
        self.assertEqual(
            "Contactez des amis qui ont un emploi d'hôtesse à Lyon.",
            override.card_text)
class CommuteScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-commute')):
    """Unit test for the "Commute" scoring model."""

    # TODO(guillaume): Add more tests when the scoring model takes the city into account.

    def setUp(self):
        super(CommuteScoringModelTestCase, self).setUp()
        self.persona = self._random_persona().clone()
        self.database.cities.insert_one({
            '_id': '69123',
            'longitude': 4.6965532,
            'latitude': 45.7179675
        })

        self.database.hiring_cities.insert_one({
            '_id':
            'M1604',
            'hiringCities': [{
                'offers': 10,
                'city': {
                    'name': 'Brindas',
                    'longitude': 4.6965532,
                    'latitude': 45.7179675,
                    'population': 10000
                }
            }, {
                'offers': 40,
                'city': {
                    'name': 'Lyon',
                    'longitude': 4.8363116,
                    'latitude': 45.7640454,
                    'population': 400000
                }
            }, {
                'offers': 40,
                'city': {
                    'name': 'Saint-Priest',
                    'longitude': 4.9123846,
                    'latitude': 45.7013617,
                    'population': 20000
                }
            }, {
                'offers': 40,
                'city': {
                    'name': 'Vaulx-en-Velin',
                    'longitude': 4.8892431,
                    'latitude': 45.7775502,
                    'population': 10000
                }
            }]
        })

    def test_lyon(self):
        """Test that people in Lyon match."""

        self.persona.project.mobility.city.city_id = '69123'
        self.persona.project.target_job.job_group.rome_id = 'M1604'
        score = self._score_persona(self.persona)
        self.assertGreater(score,
                           1,
                           msg='Fail for "{}"'.format(self.persona.name))

    def test_non_valid(self):
        """Test that people with a non-valid INSEE code should not get any commute advice."""

        self.persona.project.mobility.city.city_id = '691234'
        self.persona.project.target_job.job_group.rome_id = 'M1604'
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Fail for "{}"'.format(self.persona.name))

    def test_super_commute(self):
        """Test that people that wants to move and with super commute cities have score 3."""

        self.persona.project.mobility.city.city_id = '69123'
        self.persona.project.target_job.job_group.rome_id = 'M1604'
        if self.persona.project.mobility.area_type <= geo_pb2.CITY:
            self.persona.project.mobility.area_type = geo_pb2.DEPARTEMENT
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         3,
                         msg='Fail for "{}"'.format(self.persona.name))

    def test_extra_data(self):
        """Compute extra data."""

        self.persona.project.mobility.city.city_id = '69123'
        self.persona.project.target_job.job_group.rome_id = 'M1604'
        project = self.persona.scoring_project(self.database)
        result = self.model.compute_extra_data(project)
        self.assertGreater(len(result.cities),
                           1,
                           msg='Failed for "{}"'.format(self.persona.name))
class SpontaneousApplicationScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-spontaneous-application')):
    """Unit tests for the "Send spontaneous applications" advice."""
    def test_best_channel(self):
        """User is in a market where spontaneous application is the best channel."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.mobility.city.departement_id = '69'
        persona.project.job_search_length_months = 2
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=61))
        persona.project.weekly_applications_estimate = project_pb2.LESS_THAN_2
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [
                        {
                            'percentage': 36.38,
                            'mode': 'SPONTANEOUS_APPLICATION'
                        },
                        {
                            'percentage': 29.46,
                            'mode': 'UNDEFINED_APPLICATION_MODE'
                        },
                        {
                            'percentage': 18.38,
                            'mode': 'PLACEMENT_AGENCY'
                        },
                        {
                            'percentage': 15.78,
                            'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                        },
                    ],
                },
            },
        })
        score = self._score_persona(persona)

        self.assertEqual(score, 3, msg='Failed for "{}"'.format(persona.name))

    def test_second_best_channel(self):
        """User is in a market where spontaneous application is the second best channel."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.mobility.city.departement_id = '69'
        persona.project.job_search_length_months = 2
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=61))
        persona.project.weekly_applications_estimate = project_pb2.LESS_THAN_2
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z91': {
                    'modes': [
                        {
                            'percentage': 100,
                            'mode': 'UNDEFINED_APPLICATION_MODE'
                        },
                    ],
                },
                'R4Z92': {
                    'modes': [
                        {
                            'percentage': 36.38,
                            'mode': 'UNDEFINED_APPLICATION_MODE'
                        },
                        {
                            'percentage': 29.46,
                            'mode': 'SPONTANEOUS_APPLICATION'
                        },
                        {
                            'percentage': 18.38,
                            'mode': 'PLACEMENT_AGENCY'
                        },
                        {
                            'percentage': 15.78,
                            'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                        },
                    ],
                },
            },
        })
        score = self._score_persona(persona)

        self.assertEqual(score, 2, msg='Failed for "{}"'.format(persona.name))

    def test_not_best_channel(self):
        """User is in a market where spontaneous application is not the best channel."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.mobility.city.departement_id = '69'
        persona.project.job_search_length_months = 2
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=61))
        persona.project.weekly_applications_estimate = project_pb2.LESS_THAN_2
        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'applicationModes': {
                'R4Z92': {
                    'modes': [{
                        'percentage': 36.38,
                        'mode': 'UNDEFINED_APPLICATION_MODE'
                    }, {
                        'percentage': 29.46,
                        'mode': 'PLACEMENT_AGENCY'
                    }, {
                        'percentage': 18.38,
                        'mode': 'SPONTANEOUS_APPLICATION'
                    }, {
                        'percentage': 15.78,
                        'mode': 'PERSONAL_OR_PROFESSIONAL_CONTACTS'
                    }],
                }
            },
        })
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))
class AdviceImproveResumeTestCase(
        scoring_test.ScoringModelTestBase('advice-improve-resume')):
    """Unit tests for the "Improve Your Resume" advice."""
    def test_not_enough_interviews(self):
        """Users does not get enough interviews."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'I1202'
        persona.project.mobility.city.departement_id = '14'
        if persona.project.job_search_length_months < 3:
            persona.project.job_search_length_months = 3
        if persona.project.job_search_length_months > 6:
            persona.project.job_search_length_months = 6
        if persona.project.weekly_applications_estimate < project_pb2.DECENT_AMOUNT:
            persona.project.weekly_applications_estimate = project_pb2.DECENT_AMOUNT
        persona.project.total_interview_count = 1
        self.database.local_diagnosis.insert_one({
            '_id': '14:I1202',
            'imt': {
                'yearlyAvgOffersDenominator': 10,
                'yearlyAvgOffersPer10Candidates': 2,
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 3, msg='Failed for "{}":'.format(persona.name))

    def test_many_interviews(self):
        """Users has maximum interviews."""

        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'I1202'
        persona.project.mobility.city.departement_id = '14'
        persona.project.weekly_applications_estimate = project_pb2.DECENT_AMOUNT
        persona.project.total_interview_count = 21
        self.database.local_diagnosis.insert_one({
            '_id': '14:I1202',
            'imt': {
                'yearlyAvgOffersDenominator': 10,
                'yearlyAvgOffersPer10Candidates': 2,
            },
        })
        score = self._score_persona(persona)
        self.assertEqual(score, 0, msg='Failed for "{}":'.format(persona.name))

    def test_no_applications(self):
        """Users has never sent an application."""

        persona = self._random_persona().clone()
        persona.project.total_interview_count = -1
        persona.project.weekly_applications_estimate = project_pb2.LESS_THAN_2
        score = self._score_persona(persona)
        self.assertEqual(score, 0, msg='Failed for "{}":'.format(persona.name))

    def test_imt_data_missing(self):
        """Users does not get enough interview although IMT is missing."""

        persona = self._random_persona().clone()
        if persona.project.job_search_length_months < 3:
            persona.project.job_search_length_months = 3
        if persona.project.job_search_length_months > 6:
            persona.project.job_search_length_months = 6
        if persona.project.weekly_applications_estimate < project_pb2.DECENT_AMOUNT:
            persona.project.weekly_applications_estimate = project_pb2.DECENT_AMOUNT
        persona.project.total_interview_count = 1
        score = self._score_persona(persona)
        self.assertEqual(score, 3, msg='Failed for "{}":'.format(persona.name))
Exemple #13
0
class AdviceAssociationHelpTestCase(
        scoring_test.ScoringModelTestBase('advice-association-help')):
    """Unit tests for the "Find an association to help you" advice."""
    def test_no_data(self):
        """No associations data."""

        persona = self._random_persona().clone()
        score = self._score_persona(persona)
        self.assertLessEqual(score,
                             0,
                             msg='Failed for "{}"'.format(persona.name))

    def test_motivated(self):
        """User is motivated."""

        persona = self._random_persona().clone()
        scoring_project = persona.scoring_project(self.database)
        self.database.associations.insert_one({'name': 'SNC'})
        del persona.user_profile.frustrations[:]
        if persona.project.job_search_length_months >= 12:
            persona.project.job_search_length_months = 11
        if scoring_project.get_search_length_at_creation() >= 12:
            persona.project.job_search_started_at.FromDatetime(
                persona.project.created_at.ToDatetime() -
                datetime.timedelta(days=336))
        score = self._score_persona(persona)
        self.assertEqual(2, score, msg='Failed for "{}"'.format(persona.name))

    def test_need_motivation(self):
        """User needs motivation."""

        persona = self._random_persona().clone()
        self.database.associations.insert_one({'name': 'SNC'})
        persona.user_profile.frustrations.append(user_pb2.MOTIVATION)
        score = self._score_persona(persona)
        self.assertEqual(3, score, msg='Failed for "{}"'.format(persona.name))

    def test_many_assos_and_long_search(self):
        """User searches for a long time and there are a lot of associations."""

        persona = self._random_persona().clone()
        self.database.associations.insert_many([{
            'name': 'SNC'
        }, {
            'name': 'SND'
        }, {
            'name': 'SNE'
        }, {
            'name': 'SNF'
        }])
        persona.project.job_search_length_months = 6
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=183))
        score = self._score_persona(persona)
        self.assertEqual(3, score, msg='Failed for "{}"'.format(persona.name))

    def test_very_long_search(self):
        """User searches for a very long time."""

        persona = self._random_persona().clone()
        self.database.associations.insert_one({'name': 'SNC'})
        persona.project.job_search_length_months = 12
        persona.project.job_search_started_at.FromDatetime(
            persona.project.created_at.ToDatetime() -
            datetime.timedelta(days=366))
        score = self._score_persona(persona)
        self.assertEqual(3, score, msg='Failed for "{}"'.format(persona.name))
class AdviceReorientCloseTestCase(
        scoring_test.ScoringModelTestBase('advice-reorient-to-close-job')):
    """Unit tests for the "reorient-jobbing" advice."""

    def setUp(self):  # pylint: disable=missing-docstring,invalid-name
        super(AdviceReorientCloseTestCase, self).setUp()
        self.persona = self._random_persona().clone()
        self.persona.project.mobility.city.departement_id = '09'
        self.persona.project.target_job.job_group.rome_id = 'M1601'
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'imt':
                {
                    'yearlyAvgOffersPer10Candidates': 4,
                },
            'lessStressfulJobGroups': [
                {
                    'localStats': {'imt': {'yearlyAvgOffersPer10Candidates': 12}},
                    'jobGroup': {'romeId': 'A1413', 'name': 'Aide caviste'},
                    'mobilityType': job_pb2.CLOSE,
                },
                {
                    'localStats': {'imt': {'yearlyAvgOffersPer10Candidates': 6}},
                    'jobGroup': {'romeId': 'A1401', 'name': 'Aide arboricole'},
                    'mobilityType': job_pb2.CLOSE,
                }],
        })

    def test_search_for_very_long_time(self):
        """User searching for 13 months should have a high score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=397))
        project = self.persona.scoring_project(self.database, now=self.now)
        score, explanations = self.model.score_and_explain(project)
        self.assertEqual(score, 3, msg='Failed for "{}"'.format(self.persona.name))
        self.assertEqual(['vous cherchez depuis 13 mois'], explanations)

    def test_search_for_long_time(self):
        """User searching for 11 months should have a medium score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=335))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(self.persona.name))

    def test_search_for_quite_long_time(self):
        """User searching for 7 months should have a low score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=214))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_search_just_started(self):
        """User searching for 15 days should have a medium score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        if self.persona.project.passionate_level >= project_pb2.PASSIONATING_JOB:
            self.persona.project.passionate_level = project_pb2.ALIMENTARY_JOB
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=15))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(self.persona.name))

    def test_passionate_search_just_started(self):
        """User passionate about their job and searching for 15 days should have a low score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=15))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_search_reasonable_time(self):
        """User searching for 4 months should have a 0 score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=124))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_search_not_started(self):
        """User has not started their research should have a medium score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        if self.persona.project.passionate_level >= project_pb2.PASSIONATING_JOB:
            self.persona.project.passionate_level = project_pb2.ALIMENTARY_JOB
        self.persona.project.job_search_has_not_started = True
        score = self._score_persona(self.persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(self.persona.name))

    def test_passionate_search_not_started(self):
        """User passionate about their job that has not started their research
        should have a low score."""

        if self.persona.user_profile.year_of_birth < datetime.date.today().year - 45:
            self.persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.project.job_search_has_not_started = True
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_user_old(self):
        """Users older than 44 y.o should have a zero score."""

        self.persona.user_profile.year_of_birth = datetime.date.today().year - 50
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_not_enough_offers(self):
        """Users with job with more offers than recommended jobs don't trigger the
        advice."""

        self.database.local_diagnosis.drop()
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'imt':
                {
                    'yearlyAvgOffersPer10Candidates': 40,
                }
        })
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_not_enough_recommendations(self):
        """Users without enough recommended jobs don't trigger the advice."""

        self.database.local_diagnosis.drop()
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'imt':
                {
                    'yearlyAvgOffersPer10Candidates': 4,
                },
            'lessStressfulJobGroups': [
                {
                    'localStats': {'imt': {'yearlyAvgOffersPer10Candidates': 12}},
                    'jobGroup': {'romeId': 'A1413', 'name': 'Aide caviste'},
                    'mobilityType': job_pb2.CLOSE,
                }],
        })
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_recommendations_in_both_categories(self):
        """Users with a total of two recommended jobs should have a high score."""

        self.database.local_diagnosis.drop()
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'imt':
                {
                    'yearlyAvgOffersPer10Candidates': 4,
                },
            'lessStressfulJobGroups': [
                {
                    'localStats': {'imt': {'yearlyAvgOffersPer10Candidates': 12}},
                    'jobGroup': {'romeId': 'A1413', 'name': 'Aide caviste'},
                    'mobilityType': job_pb2.CLOSE,
                },
                {
                    'localStats': {'imt': {'yearlyAvgOffersPer10Candidates': 6}},
                    'jobGroup': {'romeId': 'A1401', 'name': 'Aide arboricole'},
                    'mobilityType': job_pb2.EVOLUTION,
                }],
        })
        self. persona.user_profile.year_of_birth = datetime.date.today().year - 40
        self.persona.project.job_search_has_not_started = False
        self.persona.project.job_search_started_at.FromDatetime(
            now.get() - datetime.timedelta(days=397))
        score = self._score_persona(self.persona)
        self.assertEqual(score, 3, msg='Failed for "{}"'.format(self.persona.name))
Exemple #15
0
class AdviceJobBoardsTestCase(
        scoring_test.ScoringModelTestBase('advice-job-boards')):
    """Unit tests for the "Other Work Environments" advice."""
    def test_frustrated(self):
        """Frustrated by not enough offers."""

        persona = self._random_persona().clone()
        persona.user_profile.frustrations.append(user_pb2.NO_OFFERS)

        score = self._score_persona(persona)

        self.assertGreaterEqual(score,
                                2,
                                msg='Failed for "{}"'.format(persona.name))

    def test_lot_of_offers(self):
        """User has many offers already."""

        persona = self._random_persona().clone()
        del persona.user_profile.frustrations[:]
        persona.project.weekly_offers_estimate = project_pb2.A_LOT

        score = self._score_persona(persona)

        # We do want to show the chantier but not pre-select it.
        self.assertEqual(1, score, msg='Failed for "{}"'.format(persona.name))

    def test_extra_data(self):
        """Compute extra data."""

        persona = self._random_persona().clone()
        project = persona.scoring_project(self.database)
        self.database.jobboards.insert_one({'title': 'Remix Jobs'})
        result = self.model.compute_extra_data(project)
        self.assertTrue(result, msg='Failed for "{}"'.format(persona.name))
        self.assertEqual('Remix Jobs',
                         result.job_board_title,
                         msg='Failedfor "{}"'.format(persona.name))

    def test_filter_data(self):
        """Get the job board with the most filters."""

        persona = self._random_persona().clone()
        persona.project.mobility.city.departement_id = '69'
        project = persona.scoring_project(self.database)
        self.database.jobboards.insert_many([
            {
                'title': 'Remix Jobs'
            },
            {
                'title': 'Specialized for me',
                'filters': ['for-departement(69)']
            },
            {
                'title': 'Specialized NOT for me',
                'filters': ['for-departement(31)']
            },
        ])
        result = self.model.compute_extra_data(project)
        self.assertTrue(result)
        self.assertEqual('Specialized for me', result.job_board_title)

    def test_filter_pole_emploi(self):
        """Never show Pôle emploi,"""

        persona = self._random_persona().clone()
        persona.project.mobility.city.departement_id = '69'
        project = persona.scoring_project(self.database)
        self.database.jobboards.insert_many([
            {
                'title': 'Pôle emploi',
                'isWellKnown': True
            },
            {
                'title': 'Remix Jobs'
            },
        ])
        result = self.model.compute_extra_data(project)
        self.assertTrue(result)
        self.assertEqual('Remix Jobs', result.job_board_title)
class DrivingLicenseHelpScoringModelTestCase(
        scoring_test.ScoringModelTestBase('advice-driving-license-low-income')
):
    """Unit tests for the "Get help for getting your driving license" advice."""
    def _create_scoreable_persona(self, rome_id='A1234', departement='69'):
        """Assumes user does not have CAR driving license,
        is old enough and has been searching for some time.
        """

        self.now = datetime.datetime(2018, 2, 2)
        self.database.local_diagnosis.insert_one({
            '_id':
            '{}:{}'.format(departement, rome_id),
            'salary': {
                'medianSalary': 18000,
            },
        })
        persona = self._random_persona().clone()
        persona.user_profile.year_of_birth = 1990
        persona.project.ClearField('job_search_has_not_started')
        persona.project.target_job.job_group.rome_id = rome_id
        persona.project.mobility.city.departement_id = departement
        persona.project.job_search_started_at.FromDatetime(
            datetime.datetime(2017, 5, 1))
        persona.user_profile.has_car_driving_license = user_pb2.FALSE
        return persona

    def test_already_has_license(self):
        """User already has driving license."""

        persona = self._random_persona().clone()
        persona.user_profile.has_car_driving_license = user_pb2.TRUE
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_license_status_unknown(self):
        """We don't know whether user has driving license."""

        persona = self._random_persona().clone()
        persona.user_profile.ClearField('has_car_driving_license')
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_is_too_young(self):
        """User is younger than required age for driving license."""

        self.now = datetime.datetime(2018, 2, 2)
        persona = self._random_persona().clone()
        persona.user_profile.year_of_birth = 1995
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_not_searched_enough(self):
        """User hasn't been searching for long."""

        persona = self._random_persona().clone()
        persona.project.job_search_started_at.FromDatetime(
            datetime.datetime(2017, 11, 1))
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_too_rich(self):
        """User has probably too much in indemnities."""

        self.database.local_diagnosis.insert_one({
            '_id': '69:A1234',
            'salary': {
                'medianSalary': 25000,
            },
        })
        persona = self._random_persona().clone()
        persona.project.target_job.job_group.rome_id = 'A1234'
        persona.project.mobility.city.departement_id = '69'
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_big_city_not_required(self):
        """User lives in a large enough city with good public transportation,
        and job doesn't need a car."""

        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'requirements': {
                'drivingLicenses': [],
            },
        })
        persona = self._random_persona().clone()
        persona.project.mobility.city.urban_score = 7
        persona.project.mobility.city.public_transportation_score = 8
        persona.project.target_job.job_group.rome_id = 'A1234'
        score = self._score_persona(persona)

        self.assertEqual(score, 0, msg='Failed for "{}"'.format(persona.name))

    def test_required_by_job(self):
        """Job group expects people to have a car."""

        self.database.job_group_info.insert_one({
            '_id': 'A1234',
            'requirements': {
                'drivingLicenses': [{
                    'drivingLicense': 'CAR',
                    'percentRequired': 50,
                }],
            },
        })
        persona = self._create_scoreable_persona(rome_id='A1234')
        persona.project.mobility.city.urban_score = 7
        score = self._score_persona(persona)

        self.assertEqual(score, 3, msg='Failed for "{}"'.format(persona.name))

    def test_small_city(self):
        """Small town people need cars more often."""

        persona = self._create_scoreable_persona()
        persona.project.mobility.city.urban_score = 5
        persona.project.mobility.city.public_transportation_score = 7
        score = self._score_persona(persona)

        self.assertGreaterEqual(score,
                                1,
                                msg='Failed for "{}"'.format(persona.name))

    def test_bad_transport_city(self):
        """City with bad public transportations forces people to use cars."""

        persona = self._create_scoreable_persona()
        persona.project.mobility.city.urban_score = 7
        persona.project.mobility.city.public_transportation_score = 3.2
        score = self._score_persona(persona)

        self.assertGreaterEqual(score,
                                1,
                                msg='Failed for "{}"'.format(persona.name))

    def test_expanded_card_data(self):
        """city coordinates are given as expanded card data."""

        self.database.cities.insert_one({
            '_id': '69383',
            'latitude': 45.5,
            'longitude': 4.5,
        })

        persona = self._create_scoreable_persona()
        persona.project.mobility.city.city_id = '69383'

        project = persona.scoring_project(self.database)
        result = self.model.get_expanded_card_data(project)

        self.assertEqual(result.latitude,
                         45.5,
                         msg='Failed for "{}"'.format(persona.name))
        self.assertEqual(result.longitude,
                         4.5,
                         msg='Failed for "{}"'.format(persona.name))
class AdviceSeasonalRelocateTestCase(
        scoring_test.ScoringModelTestBase('advice-seasonal-relocate')):
    """Unit tests for the "Advice Seasonal Relocate" advice."""
    def setUp(self):  # pylint: disable=missing-docstring,invalid-name
        super(AdviceSeasonalRelocateTestCase, self).setUp()
        self.persona = self._random_persona().clone()
        self.now = datetime.datetime(2016, 2, 27)
        self.database.departements.insert_many([
            {
                '_id': '2A',
                'name': 'Corse du Sud',
            },
            {
                '_id': '06',
                'name': 'Alpes de Haute-Provence',
            },
        ])
        self.database.seasonal_jobbing.insert_one({
            '_id':
            2,
            'departementStats': [
                {
                    'departementId':
                    '06',
                    'departementSeasonalOffers':
                    800,
                    'jobGroups': [
                        {
                            'romeId': 'I1202',
                            'name': 'Professeur de piano',
                            'offers': 123,
                        },
                        {
                            'romeId': 'I1203',
                            'name': 'Professeur de guitarre',
                            'offers': 120,
                        },
                    ],
                },
                {
                    'departementId':
                    '2A',
                    'departementSeasonalOffers':
                    800,
                    'jobGroups': [
                        {
                            'romeId': 'I1202',
                            'name': 'Professeur de piano',
                            'offers': 123,
                        },
                        {
                            'romeId': 'I1203',
                            'name': 'Professeur de guitarre',
                            'offers': 120,
                        },
                    ],
                },
            ],
        })

    def test_funky_departement(self):
        """Do not trigger if the departement is unknown."""

        self.persona.project.mobility.area_type = geo_pb2.COUNTRY
        if self.persona.user_profile.year_of_birth < datetime.date.today(
        ).year - 28:
            self.persona.user_profile.year_of_birth = datetime.date.today(
            ).year - 28
        if self.persona.user_profile.year_of_birth > datetime.date.today(
        ).year - 25:
            self.persona.user_profile.year_of_birth = datetime.date.today(
            ).year - 25
        if self.persona.user_profile.highest_degree > job_pb2.BAC_BACPRO:
            self.persona.user_profile.highest_degree = job_pb2.BAC_BACPRO
        self.persona.user_profile.family_situation = user_pb2.SINGLE
        if self.persona.project.employment_types == [job_pb2.CDI]:
            self.persona.project.employment_types.append(
                job_pb2.CDD_LESS_EQUAL_3_MONTHS)
        self.database.seasonal_jobbing.insert_one({
            '_id':
            3,
            'departementStats': [
                {
                    'departementId':
                    '31415926',
                    'departementSeasonalOffers':
                    800,
                    'jobGroups': [
                        {
                            'romeId': 'I1202',
                            'name': 'Professeur de piano',
                            'offers': 123,
                        },
                        {
                            'romeId': 'I1203',
                            'name': 'Professeur de guitarre',
                            'offers': 120,
                        },
                    ],
                },
                {
                    'departementId':
                    '2A',
                    'departementSeasonalOffers':
                    800,
                    'jobGroups': [
                        {
                            'romeId': 'I1202',
                            'name': 'Professeur de piano',
                            'offers': 123,
                        },
                        {
                            'romeId': 'I1203',
                            'name': 'Professeur de guitarre',
                            'offers': 120,
                        },
                    ],
                },
            ],
        })
        self.now = datetime.datetime(2016, 3, 27)
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Failed for "{}":'.format(self.persona.name))

    def test_older(self):
        """Do not trigger for older people."""

        if self.persona.user_profile.year_of_birth > datetime.date.today(
        ).year - 36:
            self.persona.user_profile.year_of_birth = datetime.date.today(
            ).year - 36
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Failed for "{}":'.format(self.persona.name))

    def test_region(self):
        """Do not trigger for people who's mobility is below "COUNTRY"."""

        self.persona = self._random_persona().clone()
        if self.persona.project.mobility.area_type >= geo_pb2.COUNTRY:
            self.persona.project.mobility.area_type = geo_pb2.REGION
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Failed for "{}":'.format(self.persona.name))

    def test_children(self):
        """Do not trigger for people who have children."""

        self.persona.user_profile.family_situation = user_pb2.FAMILY_WITH_KIDS
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Failed for "{}":'.format(self.persona.name))

    def test_diplomas(self):
        """Do not trigger for people who have diplomas."""

        if self.persona.user_profile.highest_degree <= job_pb2.BTS_DUT_DEUG:
            self.persona.user_profile.highest_degree = job_pb2.LICENCE_MAITRISE
        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         0,
                         msg='Failed for "{}":'.format(self.persona.name))

    def test_no_diploma(self):
        """Young mobile single people without advanced diplomas should trigger."""

        self.persona.project.mobility.area_type = geo_pb2.COUNTRY
        if self.persona.user_profile.year_of_birth < datetime.date.today(
        ).year - 28:
            self.persona.user_profile.year_of_birth = datetime.date.today(
            ).year - 28
        if self.persona.user_profile.highest_degree > job_pb2.BAC_BACPRO:
            self.persona.user_profile.highest_degree = job_pb2.BAC_BACPRO
        self.persona.user_profile.family_situation = user_pb2.SINGLE
        if self.persona.project.employment_types == [job_pb2.CDI]:
            self.persona.project.employment_types.append(
                job_pb2.CDD_LESS_EQUAL_3_MONTHS)

        score = self._score_persona(self.persona)
        self.assertEqual(score,
                         2,
                         msg='Failed for "{}":'.format(self.persona.name))
class AdviceReorientJobbingTestCase(scoring_test.ScoringModelTestBase('advice-reorient-jobbing')):
    """Unit tests for the "reorient-jobbing" advice."""

    def setUp(self):  # pylint: disable=missing-docstring,invalid-name
        super(AdviceReorientJobbingTestCase, self).setUp()
        self.persona = self._random_persona().clone()
        self.persona.project.mobility.city.departement_id = '09'
        self.persona.project.target_job.job_group.rome_id = 'M1601'
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'numJobOffersLastYear': 20,
            'numJobOffersPreviousYear': 20,
        })
        self.database.reorient_jobbing.insert_one(
            {
                '_id': '09',
                'departementJobStats':
                    {
                        'jobs': [
                            {
                                'romeId': 'A1413',
                                'masculineName': 'Aide caviste',
                                'feminineName': 'Aide caviste',
                                'name': 'Aide caviste',
                                'offers': 123,
                            },
                            {
                                'romeId': 'A1401',
                                'feminineName': 'Aide arboricole',
                                'masculineName': 'Aide arboricole',
                                'name': 'Aide arboricole',
                                'offers': 60,
                            },
                        ],
                    },
            }
        )

    def test_license(self):
        """Users with a license should not be concerned by reorientation."""

        self.persona.user_profile.highest_degree = job_pb2.LICENCE_MAITRISE
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_bts(self):
        """Users with a degree equivalent to bac +2 should have reorientation
        advice with low priority."""

        self.persona.user_profile.highest_degree = job_pb2.BTS_DUT_DEUG
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_bac(self):
        """Users with a degree equivalent to baccalaureat should have reorientation
        with medium priority."""

        self.persona.user_profile.highest_degree = job_pb2.BAC_BACPRO
        if self.persona.project.passionate_level == project_pb2.LIFE_GOAL_JOB:
            self.persona.project.passionate_level = project_pb2.ALIMENTARY_JOB
        score = self._score_persona(self.persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(self.persona.name))

    def test_cap(self):
        """Users with CAP or BEP degree or equivalent should have reorientation
        with high priority."""

        self.persona.user_profile.highest_degree = job_pb2.CAP_BEP
        if self.persona.project.passionate_level == project_pb2.LIFE_GOAL_JOB:
            self.persona.project.passionate_level = project_pb2.ALIMENTARY_JOB
        score = self._score_persona(self.persona)
        self.assertEqual(score, 3, msg='Failed for "{}"'.format(self.persona.name))

    def test_not_enough_offers(self):
        """Users with job with more offers than recommended jobs don't trigger the
        advice."""

        self.database.local_diagnosis.drop()
        self.database.local_diagnosis.insert_one({
            '_id': '09:M1601',
            'numJobOffersLastYear': 200,
            'numJobOffersPreviousYear': 200,
        })
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))

    def test_cap_passionate_job(self):
        """Users with CAP/BEP degree with who is passionate about its job should
        have a low score."""

        self.database.job_group_info.insert_one({
            '_id': 'M1601',
            'growth20122022': .16,
        })
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.user_profile.highest_degree = job_pb2.CAP_BEP
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_bac_passionate_job(self):
        """Users with BAC degree with who is passionate about its job should
        have a low score."""

        self.database.job_group_info.insert_one({
            '_id': 'M1601',
            'growth20122022': .16,
        })
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.user_profile.highest_degree = job_pb2.BAC_BACPRO
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_cap_passionate_but_no_future_job(self):
        """Users with CAP/BEP degree who is passionate about its job but their job has no
        no future, should have a medium score."""

        self.database.job_group_info.insert_one({
            '_id': 'M1601',
            'growth20122022': -.16,
        })
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.user_profile.highest_degree = job_pb2.CAP_BEP
        score = self._score_persona(self.persona)
        self.assertEqual(score, 2, msg='Failed for "{}"'.format(self.persona.name))

    def test_bac_passionate_but_no_future_job(self):
        """Users with BAC degree who is passionate about its job but their job has no
        no future, should have a low score."""

        self.database.job_group_info.insert_one({
            '_id': 'M1601',
            'growth20122022': -.16,
        })
        self.persona.project.passionate_level = project_pb2.LIFE_GOAL_JOB
        self.persona.user_profile.highest_degree = job_pb2.BAC_BACPRO
        score = self._score_persona(self.persona)
        self.assertEqual(score, 1, msg='Failed for "{}"'.format(self.persona.name))

    def test_not_enough_recommendations(self):
        """Users with job with more offers than recommended jobs don't trigger the
        advice."""

        self.database.reorient_jobbing.drop()
        self.database.reorient_jobbing.insert_one(
            {
                '_id': '09',
                'departementJobStats':
                    {
                        'jobs': [
                            {
                                'romeId': 'A1413',
                                'masculineName': 'Aide caviste',
                                'feminineName': 'Aide caviste',
                                'name': 'Aide caviste',
                                'offers': 123,
                            },
                        ],
                    },
            }
        )
        score = self._score_persona(self.persona)
        self.assertEqual(score, 0, msg='Failed for "{}"'.format(self.persona.name))