示例#1
0
def new_diagnostic_vars(user: user_pb2.User,
                        **unused_kwargs: Any) -> Dict[str, str]:
    """Compute vars for the "New Diagnostic"."""

    frustrations_set = set(user.profile.frustrations)
    frustrations_vars = {
        f'frustration_{name}':
        campaign.as_template_boolean(key in frustrations_set)
        for name, key in user_pb2.Frustration.items()
    }
    age = datetime.date.today().year - user.profile.year_of_birth
    has_children = user.profile.family_situation in {
        user_pb2.FAMILY_WITH_KIDS,
        user_pb2.SINGLE_PARENT_SITUATION,
    }
    survey_token = parse.quote(
        auth.create_token(user.user_id, role='employment-status'))
    auth_token = parse.quote(
        auth.create_token(user.user_id, is_using_timestamp=True))
    redirect_url = f'{campaign.BASE_URL}/statut/ne-recherche-plus'
    return dict(
        dict(frustrations_vars, **campaign.get_default_vars(user)), **{
            'mayHaveSeekingChildren':
            campaign.as_template_boolean(has_children and age >= 45),
            'loginUrl':
            f'{campaign.BASE_URL}?userId={user.user_id}&authToken={auth_token}',
            'stopSeekingUrl':
            f'{campaign.BASE_URL}/api/employment-status?user={user.user_id}&token={survey_token}&'
            f'seeking=STOP_SEEKING&redirect={parse.quote(redirect_url)}',
        })
示例#2
0
def employment_vars(user, unused_db=None):
    """Compute vars for a given user for the employment survey.

    Returns:
        a dict with all vars required for the template, or None if no email
        should be sent.
    """

    registered_months_ago = campaign.get_french_months_ago(
        user.registered_at.ToDatetime())
    if not registered_months_ago:
        logging.warning('User registered only recently (%s)',
                        user.registered_at)
        return None
    # If the users have already updated their employment status less than one month ago,
    # ignore them.
    for status in user.employment_status:
        if status.created_at.ToDatetime() > _ONE_MONTH_AGO:
            return None
    survey_token = parse.quote(
        auth.create_token(user.user_id, role='employment-status'))
    unsubscribe_token = parse.quote(
        auth.create_token(user.profile.email, role='unsubscribe'))
    return {
        'firstName':
        french.cleanup_firstname(user.profile.name),
        'registeredMonthsAgo':
        registered_months_ago,
        'seekingUrl':
        '{}/api/employment-status?user={}&token={}&seeking={}&redirect={}'.
        format(
            campaign.BASE_URL,
            user.user_id,
            survey_token,
            'STILL_SEEKING',
            parse.quote('{}/statut/en-recherche'.format(campaign.BASE_URL)),
        ),
        'stopSeekingUrl':
        '{}/api/employment-status?user={}&token={}&seeking={}&redirect={}'.
        format(
            campaign.BASE_URL,
            user.user_id,
            survey_token,
            'STOP_SEEKING',
            parse.quote('{}/statut/ne-recherche-plus'.format(
                campaign.BASE_URL)),
        ),
        'unsubscribeLink':
        '{}/unsubscribe.html?email={}&auth={}'.format(
            campaign.BASE_URL, parse.quote(user.profile.email),
            unsubscribe_token),
    }
示例#3
0
    def test_create_token(self) -> None:
        """Basic usage of create_token."""

        token_1 = auth.create_token('*****@*****.**', 'login')
        self.assertTrue(token_1)

        token_2 = auth.create_token('*****@*****.**', 'unsubscribe')
        self.assertTrue(token_2)
        self.assertNotEqual(token_1, token_2)

        token_3 = auth.create_token('*****@*****.**', 'login')
        self.assertTrue(token_3)
        self.assertNotEqual(token_1, token_3)
示例#4
0
def _get_improve_cv_vars(
        user: user_pb2.User, now: datetime.datetime,
        **unused_kwargs: Any) -> Optional[Dict[str, Any]]:
    """Compute vars for the "Improve your CV" email."""

    if user_pb2.RESUME not in user.profile.frustrations:
        logging.info('User is not frustrated by its CV')
        return None

    project = user.projects[0]
    if project.kind == project_pb2.FIND_A_FIRST_JOB:
        has_experience = 'False'
    elif project.kind in (project_pb2.FIND_A_NEW_JOB, project_pb2.FIND_ANOTHER_JOB):
        has_experience = 'True'
    else:
        has_experience = ''

    deep_link_advice_url = \
        campaign.get_deep_link_advice(user.user_id, project, 'improve-resume') or \
        campaign.get_deep_link_advice(user.user_id, project, 'fresh-resume')

    auth_token = parse.quote(auth.create_token(user.user_id, is_using_timestamp=True))
    return dict(campaign.get_default_coaching_email_vars(user), **{
        'deepLinkAdviceUrl': deep_link_advice_url,
        'hasExperience': has_experience,
        'isSeptember': campaign.as_template_boolean(now.month == 9),
        'loginUrl': f'{campaign.BASE_URL}?userId={user.user_id}&authToken={auth_token}',
    })
示例#5
0
    def test_auth_user_id_token(self, mock_time: mock.MagicMock) -> None:
        """Authenticate using the user ID and a token."""

        now = time.time()
        mock_time.time.return_value = now

        # Create password.
        user_id = self.authenticate_new_user(email='*****@*****.**',
                                             password='******',
                                             first_name='Pascal',
                                             last_name='Corpet')

        timed_token = auth.create_token(user_id, is_using_timestamp=True)

        # 2 days later…
        mock_time.time.return_value = now + 86400 * 2

        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "{user_id}", "authToken": "{timed_token}"}}',
            content_type='application/json')

        auth_response = self.json_from_response(response)
        self.assertEqual(
            'Pascal',
            auth_response.get('authenticatedUser', {}).get('profile',
                                                           {}).get('name'))
        self.assertTrue(auth_response.get('lastAccessAt'))
示例#6
0
    def test_update_create_new_employment_status(self, mock_now):
        """Create a new employment status when update is a day later."""

        mock_now.return_value = datetime.datetime.now()
        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'seeking': 'STOP_SEEKING',
            'redirect': 'http://www.tutut.org',
        })
        # Waiting 36 hours before updating the status: we then create a new one.
        mock_now.return_value = datetime.datetime.now() + datetime.timedelta(hours=36)
        response = self.app.post(
            '/api/employment-status/{}'.format(user_id),
            data='{"seeking": "STILL_SEEKING", "bobHasHelped": "YES_A_LOT"}',
            headers={'Authorization': 'Bearer ' + survey_token},
            content_type='application/json')
        self.assertEqual(200, response.status_code)

        user = self.get_user_info(user_id, auth_token)
        self.assertEqual(
            ['STOP_SEEKING', 'STILL_SEEKING'],
            [s.get('seeking') for s in user.get('employmentStatus', [])])
示例#7
0
def _employment_vars(
        user: user_pb2.User, now: datetime.datetime, **unused_kwargs: Any) \
        -> Optional[Dict[str, str]]:
    """Compute vars for a given user for the employment survey.

    Returns:
        a dict with all vars required for the template, or None if no email
        should be sent.
    """

    registered_months_ago = campaign.get_french_months_ago(
        user.registered_at.ToDatetime(), now=now)
    if not registered_months_ago:
        logging.warning('User registered only recently (%s)',
                        user.registered_at)
        return None
    # If the users have already updated their employment status less than one month ago,
    # ignore them.
    for status in user.employment_status:
        if status.created_at.ToDatetime() > _ONE_MONTH_AGO:
            return None
    survey_token = parse.quote(
        auth.create_token(user.user_id, role='employment-status'))
    redirect_url = parse.quote(f'{campaign.BASE_URL}/statut/en-recherche')
    return dict(
        campaign.get_default_vars(user), **{
            'registeredMonthsAgo':
            registered_months_ago,
            'seekingUrl':
            f'{campaign.BASE_URL}/api/employment-status?user={user.user_id}&token={survey_token}&'
            f'seeking=STILL_SEEKING&redirect={redirect_url}',
            'stopSeekingUrl':
            f'{campaign.BASE_URL}/api/employment-status?user={user.user_id}&token={survey_token}&'
            f'seeking=STOP_SEEKING&redirect={redirect_url}',
        })
示例#8
0
    def test_auth_user_id_token_corrupted_data(
            self, mock_warning: mock.MagicMock) -> None:
        """Authenticate using the user ID and a token but data is corrupted."""

        # Create password.
        user_id = self.authenticate_new_user(email='*****@*****.**',
                                             password='******',
                                             first_name='Pascal',
                                             last_name='Corpet')
        timed_token = auth.create_token(user_id, is_using_timestamp=True)

        # Screw the data in Mongo.
        self._user_db.user.update_one({}, {'$set': {'revision': {'hack': 1}}})

        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "{user_id}", "authToken": "{timed_token}"}}',
            content_type='application/json')
        self.assertEqual(500, response.status_code)
        self.assertIn('Les données utilisateur sont corrompues',
                      response.get_data(as_text=True))
        mock_warning.assert_called_once()
        self.assertIn(
            'Failed to parse revision',
            mock_warning.call_args[0][0] % mock_warning.call_args[0][1:])
示例#9
0
    def test_employment_status_invalid_id(self):
        """EmploymentSurvey endpoint should not save anything if called with an invalid ID."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'seeking': '1',
            'redirect': 'http://www.tutut.org'
        })
        self.assertEqual(302, response.status_code)
        user = self.get_user_info(user_id, auth_token)
        redirect_args = dict(parse.parse_qsl(parse.urlparse(response.location).query))
        self.assertIn('id', redirect_args)
        self.assertEqual(survey_token, redirect_args['token'])
        self.assertEqual(user_id, redirect_args['user'])
        self.assertEqual(redirect_args['id'], '0')
        self.assertEqual(user['employmentStatus'][0]['seeking'], 'STILL_SEEKING')
        survey_response = {
            'situation': 'lalala',
            'bobHasHelped': 'bidulechose'
        }
        response2 = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'id': int(redirect_args['id']) + 3,
            **survey_response
        })
        self.assertEqual(422, response2.status_code)
        for key in survey_response:
            self.assertNotIn(key, user['employmentStatus'][0])
示例#10
0
    def test_auth_user_id_token_outdated(self,
                                         mock_time: mock.MagicMock) -> None:
        """Authenticate using the user ID and a very old token."""

        now = time.time()
        mock_time.time.return_value = now

        # Create password.
        user_id = self.authenticate_new_user(email='*****@*****.**',
                                             password='******',
                                             first_name='Pascal',
                                             last_name='Corpet')

        timed_token = auth.create_token(user_id, is_using_timestamp=True)

        # 10 days later…
        mock_time.time.return_value = now + 86400 * 10

        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "{user_id}", "authToken": "{timed_token}"}}',
            content_type='application/json')
        self.assertEqual(498, response.status_code)
        self.assertIn("Token d'authentification périmé",
                      response.get_data(as_text=True))
示例#11
0
def _send_activation_email(user: user_pb2.User, project: project_pb2.Project,
                           database: pymongo_database.Database,
                           base_url: str) -> None:
    """Send an email to the user just after we have defined their diagnosis."""

    if '@' not in user.profile.email:
        return

    # Set locale.
    locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')

    scoring_project = scoring.ScoringProject(project,
                                             user,
                                             database,
                                             now=now.get())
    auth_token = parse.quote(
        auth.create_token(user.user_id, is_using_timestamp=True))
    settings_token = parse.quote(
        auth.create_token(user.user_id, role='settings'))
    coaching_email_frequency_name = \
        user_pb2.EmailFrequency.Name(user.profile.coaching_email_frequency)
    data = {
        'changeEmailSettingsUrl':
        f'{base_url}/unsubscribe.html?user={user.user_id}&auth={settings_token}&'
        f'coachingEmailFrequency={coaching_email_frequency_name}&'
        f'hl={parse.quote(user.profile.locale)}',
        'date':
        now.get().strftime('%d %B %Y'),
        'firstName':
        user.profile.name,
        'gender':
        user_pb2.Gender.Name(user.profile.gender),
        'isCoachingEnabled':
        'True' if user.profile.coaching_email_frequency
        and user.profile.coaching_email_frequency != user_pb2.EMAIL_NONE else
        '',
        'loginUrl':
        f'{base_url}?userId={user.user_id}&authToken={auth_token}',
        'ofJob':
        scoring_project.populate_template('%ofJobName',
                                          raise_on_missing_var=True),
    }
    # https://app.mailjet.com/template/636862/build
    response = mail.send_template('636862', user.profile, data)
    if response.status_code != 200:
        logging.warning('Error while sending diagnostic email: %s\n%s',
                        response.status_code, response.text)
示例#12
0
def get_status_update_link(user_id: str, profile: user_pb2.UserProfile) -> str:
    """Make link with token from user ID for RER status update."""

    survey_token = parse.quote(auth.create_token(user_id, role='employment-status'))
    # TODO(pascal): Drop can_tutoie when the RER page uses i18n.
    return f'{BASE_URL}/statut/mise-a-jour?user={user_id}&token={survey_token}&' \
        f'gender={user_pb2.Gender.Name(profile.gender)}' + \
        ('&can_tutoie=true' if profile.can_tutoie else '') + \
        f'&hl={parse.quote(profile.locale)}'
示例#13
0
def new_diagnostic_vars(user, unused_db=None):
    """Compute vars for the "New Diagnostic"."""

    unsubscribe_token = parse.quote(
        auth.create_token(user.profile.email, role='unsubscribe'))
    frustrations_vars = {
        'frustration_{}'.format(user_pb2.Frustration.Name(f)): 'True'
        for f in user.profile.frustrations
    }
    age = datetime.date.today().year - user.profile.year_of_birth
    has_children = user.profile.family_situation in {
        user_pb2.FAMILY_WITH_KIDS,
        user_pb2.SINGLE_PARENT_SITUATION,
    }
    survey_token = parse.quote(
        auth.create_token(user.user_id, role='employment-status'))
    auth_token = parse.quote(
        auth.create_token(user.user_id, is_using_timestamp=True))
    return dict(
        frustrations_vars, **{
            'firstName':
            french.cleanup_firstname(user.profile.name),
            'gender':
            user_pb2.Gender.Name(user.profile.gender),
            'mayHaveSeekingChildren':
            campaign.as_template_boolean(has_children and age >= 45),
            'loginUrl':
            '{}?userId={}&authToken={}'.format(campaign.BASE_URL, user.user_id,
                                               auth_token),
            'stopSeekingUrl':
            '{}/api/employment-status?user={}&token={}&seeking={}&redirect={}'.
            format(
                campaign.BASE_URL,
                user.user_id,
                survey_token,
                'STOP_SEEKING',
                parse.quote('{}/statut/ne-recherche-plus'.format(
                    campaign.BASE_URL)),
            ),
            'unsubscribeLink':
            '{}/unsubscribe.html?email={}&auth={}'.format(
                campaign.BASE_URL, parse.quote(user.profile.email),
                unsubscribe_token),
        })
示例#14
0
    def test_employment_status_invalid_token(self):
        """EmploymentSurvey endpoint should fail if called with an invalid token."""

        user_id = self.create_user(email='*****@*****.**')
        auth_token = auth.create_token(user_id, role='invalid-role')
        response = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': auth_token,
            'seeking': '1',
        })
        self.assertEqual(403, response.status_code)
示例#15
0
def get_default_vars(user: user_pb2.User, **unused_kwargs: Any) -> Dict[str, str]:
    """Compute default variables used in all emails: firstName, gender and unsubscribeLink."""

    unsubscribe_token = parse.quote(auth.create_token(user.profile.email, role='unsubscribe'))
    return {
        'firstName': french.cleanup_firstname(user.profile.name),
        'gender': user_pb2.Gender.Name(user.profile.gender),
        'unsubscribeLink':
        f'{BASE_URL}/unsubscribe.html?user={parse.quote(user.user_id)}&'
        f'auth={unsubscribe_token}&hl={parse.quote(user.profile.locale)}',
    }
示例#16
0
    def test_auth_user_id_token_unknown_user(self) -> None:
        """Authenticate using a token but the user ID does not correspond to anything."""

        user_id = str(objectid.ObjectId())
        timed_token = auth.create_token(user_id, is_using_timestamp=True)

        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "{user_id}", "authToken": "{timed_token}"}}',
            content_type='application/json')
        self.assertEqual(404, response.status_code)
        self.assertIn('Utilisateur inconnu', response.get_data(as_text=True))
示例#17
0
    def test_employment_status_seeking_wrong_string(self):
        """Test passing seeking parameter as string."""

        user_id = self.create_user(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'seeking': 'ERRONEOUS',
            'redirect': 'http://www.tutut.org',
        })
        self.assertEqual(422, response.status_code)
示例#18
0
    def test_employment_status_seeking_string(self):
        """Test passing seeking parameter as string."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'seeking': 'STOP_SEEKING',
            'redirect': 'http://www.tutut.org',
        })
        self.assertEqual(302, response.status_code)
        user = self.get_user_info(user_id, auth_token)
        self.assertEqual(user['employmentStatus'][0]['seeking'], 'STOP_SEEKING')
示例#19
0
    def test_update_employment_status(self):
        """Update the employment status through the POST endpoint."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.post(
            '/api/employment-status/{}'.format(user_id),
            data='{"seeking": "STILL_SEEKING", "bobHasHelped": "YES_A_LOT"}',
            headers={'Authorization': 'Bearer ' + survey_token},
            content_type='application/json')
        self.assertEqual(200, response.status_code)

        user = self.get_user_info(user_id, auth_token)
        self.assertEqual(['STILL_SEEKING'], [s.get('seeking') for s in user['employmentStatus']])
示例#20
0
def generate_auth_tokens(user_id):
    r"""Generates auth token for a given user.

    Note that this is safe to do as long as the user had a proper and complete
    auth token which is ensured by the @auth.require_user above.

    The "easiest" way to use it:
     - open a the Chrome Console on Bob
     - run the following js commands: ```
        (() => {const authToken = document.cookie.match(/(^|;\s*)authToken=(.*?)(\s*;|$)/)[2];
        const userId = document.cookie.match(/(^|;\s*)userId=(.*?)(\s*;|$)/)[2];
        fetch(`/api/user/${userId}/generate-auth-tokens`, {
            headers: {Authorization: `Bearer ${authToken}`},
         }).then(response => response.json()).then(console.log)})()
       ```
    """

    user_data = _USER_DB.user.find_one({'_id': _safe_object_id(user_id)}, {
        'profile.email': 1,
        '_id': 0
    })
    if not user_data:
        flask.abort(404, 'Utilisateur "{}" inconnu.'.format(user_id))
    email = user_data.get('profile', {}).get('email')
    # TODO(cyrille): Add user to simplify use in url.
    return json.dumps({
        'auth':
        auth.create_token(user_id, is_using_timestamp=True),
        'employment-status':
        auth.create_token(user_id, 'employment-status'),
        'nps':
        auth.create_token(user_id, 'nps'),
        'unsubscribe':
        auth.create_token(email, 'unsubscribe'),
        'user':
        user_id,
    })
示例#21
0
def body_language_vars(user, unused_db=None):
    """Compute vars for a given user for the body language email.

    Returns:
        a dict with all vars required for the template, or None if no email
        should be sent.
    """

    if not user.projects:
        logging.info('User has no project')
        return None

    registered_months_ago = campaign.get_french_months_ago(
        user.registered_at.ToDatetime())
    if not registered_months_ago:
        logging.info('User registered only recently (%s)', user.registered_at)
        return None

    has_read_last_focus_email = any(email.status in _READ_EMAIL_STATUSES
                                    for email in user.emails_sent
                                    if email.campaign_id.startswith('focus-'))

    worst_frustration = next(
        (user_pb2.Frustration.Name(frustration)
         for frustration in (user_pb2.SELF_CONFIDENCE, user_pb2.INTERVIEW,
                             user_pb2.ATYPIC_PROFILE)
         if frustration in user.profile.frustrations), '')
    if not worst_frustration:
        return None

    unsubscribe_token = parse.quote(
        auth.create_token(user.profile.email, role='unsubscribe'))

    return {
        'firstName':
        french.cleanup_firstname(user.profile.name),
        'gender':
        user_pb2.Gender.Name(user.profile.gender),
        'hasReadLastFocusEmail':
        campaign.as_template_boolean(has_read_last_focus_email),
        'registeredMonthsAgo':
        registered_months_ago,
        'unsubscribeLink':
        '{}/unsubscribe.html?email={}&auth={}'.format(
            campaign.BASE_URL, parse.quote(user.profile.email),
            unsubscribe_token),
        'worstFrustration':
        worst_frustration,
    }
示例#22
0
    def test_missing_parameters(self):
        """EmploymentSurvey endpoint expect user and token parameters"""

        user_id = self.create_user(email='*****@*****.**')
        auth_token = auth.create_token(user_id, role='employment-survey')
        response = self.app.get('/api/employment-status', query_string={
            'token': auth_token,
            'seeking': '1',
        })
        self.assertEqual(422, response.status_code)
        response = self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'seeking': '1',
        })
        self.assertEqual(422, response.status_code)
示例#23
0
def get_default_coaching_email_vars(user: user_pb2.User, **unused_kwargs: Any) -> Dict[str, str]:
    """Compute default variables used in all coaching emails."""

    settings_token = parse.quote(auth.create_token(user.user_id, role='settings'))
    return dict(get_default_vars(user), **{
        'changeEmailSettingsUrl':
        f'{BASE_URL}/unsubscribe.html?user={parse.quote(user.user_id)}&auth={settings_token}&'
        'coachingEmailFrequency=' +
        user_pb2.EmailFrequency.Name(user.profile.coaching_email_frequency) +
        f'&hl={parse.quote(user.profile.locale)}',
        'firstName': french.cleanup_firstname(user.profile.name),
        'gender': user_pb2.Gender.Name(user.profile.gender),
        # TODO(pascal): Harmonize use of URL suffix (instead of link).
        'statusUpdateUrl': get_status_update_link(user.user_id, user.profile),
    })
示例#24
0
    def test_employment_status_stop_seeking(self) -> None:
        """Test expected use case of employment-survey when user click on stop seeking."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.get('/api/employment-status',
                                query_string={
                                    'user': user_id,
                                    'token': survey_token,
                                    'seeking': '2',
                                    'redirect': 'http://www.tutut.org',
                                })
        self.assertEqual(302, response.status_code)
        user = self.get_user_info(user_id, auth_token)
        self.assertEqual(user['employmentStatus'][0]['seeking'],
                         'STOP_SEEKING')
示例#25
0
    def test_auth_user_id_token_wrong_format_id(self) -> None:
        """Authenticate using a token but a wrongly formatted user ID."""

        # Create password.
        user_id = self.authenticate_new_user(email='*****@*****.**',
                                             password='******',
                                             first_name='Pascal',
                                             last_name='Corpet')

        timed_token = auth.create_token(user_id, is_using_timestamp=True)

        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "aaa", "authToken": "{timed_token}"}}',
            content_type='application/json')
        self.assertEqual(400, response.status_code)
        self.assertIn(
            "L'identifiant utilisateur "aaa" n'a pas le bon format",
            response.get_data(as_text=True))
示例#26
0
def send_email_to_user(user, user_id, base_url):
    """Sends an email to the user to measure the Net Promoter Score."""

    # Renew actions for the day if needed.
    mail_result = mail.send_template(
        _MAILJET_TEMPLATE_ID,
        user.profile,
        {
            'baseUrl': base_url,
            'firstName': french.cleanup_firstname(user.profile.name),
            'npsFormUrl': '{}/api/nps?user={}&token={}&redirect={}'.format(
                base_url, user_id, auth.create_token(user_id, 'nps'),
                parse.quote('{}/retours'.format(base_url)),
            ),
        },
        dry_run=DRY_RUN,
    )
    mail_result.raise_for_status()
    return mail_result
示例#27
0
    def test_employment_status(self) -> None:
        """Test expected use case of employment-survey endpoints."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        response = self.app.get('/api/employment-status',
                                query_string={
                                    'user': user_id,
                                    'token': survey_token,
                                    'seeking': '1',
                                    'redirect': 'http://www.tutut.org',
                                })
        self.assertEqual(302, response.status_code)
        user = self.get_user_info(user_id, auth_token)
        assert response.location
        redirect_args = dict(
            parse.parse_qsl(parse.urlparse(response.location).query))
        self.assertIn('id', redirect_args)
        self.assertEqual(survey_token, redirect_args['token'])
        self.assertEqual(user_id, redirect_args['user'])
        self.assertEqual(user['employmentStatus'][0]['seeking'],
                         'STILL_SEEKING')

        survey_response = {
            'situation': 'lalala',
            'bobHasHelped': 'bidulechose'
        }
        response2 = self.app.post(
            f'/api/employment-status/{user_id}',
            data=json.dumps(survey_response),
            headers={'Authorization': 'Bearer ' + survey_token},
            content_type='application/json')
        self.assertEqual(200, response2.status_code)
        user = self.get_user_info(user_id, auth_token)
        self.assertTrue(len(user['employmentStatus']) == 1)
        status = user['employmentStatus'][0]
        for key, value in survey_response.items():
            self.assertEqual(status[key], value)
        # check other fields have not been lost.
        self.assertEqual(user['profile']['email'], '*****@*****.**')
示例#28
0
    def test_update_existing_employment_status(self):
        """Update an existing employment status through the POST endpoint."""

        user_id, auth_token = self.create_user_with_token(email='*****@*****.**')
        survey_token = auth.create_token(user_id, role='employment-status')
        self.app.get('/api/employment-status', query_string={
            'user': user_id,
            'token': survey_token,
            'seeking': 'STOP_SEEKING',
            'redirect': 'http://www.tutut.org',
        })
        response = self.app.post(
            '/api/employment-status/{}'.format(user_id),
            data='{"seeking": "STILL_SEEKING", "bobHasHelped": "YES_A_LOT"}',
            headers={'Authorization': 'Bearer ' + survey_token},
            content_type='application/json')
        self.assertEqual(200, response.status_code)

        user = self.get_user_info(user_id, auth_token)
        self.assertEqual(
            ['STILL_SEEKING'],
            [s.get('seeking') for s in user.get('employmentStatus', [])])
示例#29
0
    def test_check_token(self) -> None:
        """Basic usage of check_token (round trip with create_token)."""

        login_token = auth.create_token('*****@*****.**', 'login')
        auth.check_token('*****@*****.**', login_token, 'login')
示例#30
0
    def test_check_token_wrong_role(self) -> None:
        """check_token fails if wrong role."""

        login_token = auth.create_token('*****@*****.**', 'login')
        with self.assertRaises(ValueError):
            auth.check_token('*****@*****.**', login_token, 'unsubscribe')