def test_unknown_user(self, mock_requests: requests_mock.Mocker) -> None: """Test update_users_client_metrics with an unknown user.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) mock_requests.get( 'https://amplitude.com/api/2/usersearch?user=7ed900dbfbebdee97f9e2332', json={'matches': []}) sync_amplitude.main([ '--registered-from', '2017-11-14', '--registered-to', '2017-11-18', '--disable-sentry', '--no-dry-run' ]) user = user_pb2.User() proto.parse_from_mongo(mock_db.user.find_one({}), user) self.assertEqual('Not Found', user.client_metrics.amplitude_id)
def test_missing_sentry(self, unused_mock_requests: requests_mock.Mocker, mock_logging: mock.MagicMock) -> None: """Missing sentry env var.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) sync_amplitude.main([ '--registered-from', '2017-11-14', '--registered-to', '2017-11-18', '--no-dry-run' ]) user = user_pb2.User() proto.parse_from_mongo(mock_db.user.find_one({}), user) self.assertFalse(user.client_metrics.amplitude_id) mock_logging.assert_called_once()
def fetch_use_case_pools() -> use_case_pb2.UseCasePools: """Retrieve a list of the available pools of anonymized user examples.""" use_case_pools = use_case_pb2.UseCasePools() use_case_pool_dicts = flask.current_app.config[ 'EVAL_DATABASE'].use_case.aggregate([ { '$group': { '_id': '$poolName', 'useCaseCount': { '$sum': 1 }, 'evaluatedUseCaseCount': { '$sum': { '$cond': [{ '$gt': ['$evaluation', None] }, 1, 0] } }, 'lastUserRegisteredAt': { '$max': '$userData.registeredAt' }, } }, { '$sort': { 'lastUserRegisteredAt': -1 } }, ]) for use_case_pool_dict in use_case_pool_dicts: use_case_pool_proto = use_case_pools.use_case_pools.add() proto.parse_from_mongo(use_case_pool_dict, use_case_pool_proto, 'name') return use_case_pools
def test_main(self, mock_post: mock.MagicMock) -> None: """Overall test.""" _db = pymongo.MongoClient('mongodb://my-db/db').db _db.user.drop() _db.user.insert_one({ '_id': mongomock.ObjectId('5daf2298484ae6c93351b822'), 'profile': { 'name': 'Pascal', 'lastName': 'Corpet', 'email': '*****@*****.**', 'locale': 'en', }, 'registeredAt': datetime.datetime(2018, 1, 22, 10, 0, 0).isoformat() + 'Z', 'projects': [{ 'title': 'Project Title', }], }) mail_nps.main(self._now, '1') sent_messages = mailjetmock.get_all_sent_messages() self.assertEqual(['*****@*****.**'], [m.recipient['Email'] for m in sent_messages]) self.assertEqual(100819, sent_messages[0].properties['TemplateID']) template_vars = sent_messages[0].properties['Variables'] nps_form_urlstring = template_vars.pop('npsFormUrl') self.assertEqual( { 'baseUrl': 'http://localhost:3000', 'firstName': 'Pascal', }, template_vars) nps_form_url = parse.urlparse(nps_form_urlstring) self.assertEqual( 'http://localhost:3000/api/nps', parse.urlunparse(nps_form_url[:4] + ('', ) + nps_form_url[5:])) nps_form_args = parse.parse_qs(nps_form_url.query) self.assertEqual({'user', 'token', 'redirect'}, nps_form_args.keys()) self.assertEqual(['5daf2298484ae6c93351b822'], nps_form_args['user']) auth.check_token('5daf2298484ae6c93351b822', nps_form_args['token'][0], role='nps') self.assertEqual(['http://localhost:3000/retours?hl=en'], nps_form_args['redirect']) mock_post.assert_called_once_with( 'https://slack.example.com/webhook', json={ 'text': "Report for NPS blast: I've sent 1 emails (with 0 errors)." }, ) modified_user = user_pb2.User() proto.parse_from_mongo(_db.user.find_one(), modified_user) self.assertEqual( [sent_messages[0].message_id], [m.mailjet_message_id for m in modified_user.emails_sent]) self.assertEqual('nps', modified_user.emails_sent[0].campaign_id)
def volunteering_missions(self, project: scoring_base.ScoringProject) \ -> association_pb2.VolunteeringMissions: """Return a list of volunteering mission close to the project.""" departement_id = project.details.city.departement_id # Get data from MongoDB. volunteering_missions_dict: dict[str, association_pb2.VolunteeringMissions] = \ collections.defaultdict(association_pb2.VolunteeringMissions) collection = project.database.volunteering_missions for record in collection.find({'_id': {'$in': [departement_id, '']}}): record_id = record.pop('_id') proto.parse_from_mongo(record, volunteering_missions_dict[record_id]) # TODO(pascal): First get missions from target city if any. # Merge data. project_missions = association_pb2.VolunteeringMissions() for scope in [departement_id, '']: for mission in volunteering_missions_dict[scope].missions: mission.is_available_everywhere = not scope project_missions.missions.add().CopyFrom(mission) return project_missions
def test_registered_from_days_ago( self, mock_requests: requests_mock.Mocker) -> None: """Test update_users_client_metrics.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_many([ { '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }, # User registered just "today" (the day the script is run). { '_id': mongomock.ObjectId('7ed900dbfbebd00000000004'), 'registeredAt': '2017-11-19T10:57:12Z', }, ]) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) mock_requests.get( 'https://amplitude.com/api/2/usersearch?user=7ed900dbfbebdee97f9e2332', json={'matches': [{ 'amplitude_id': 42 }]}) mock_requests.get( 'https://amplitude.com/api/2/useractivity?user=42', json={ 'events': [ { 'event_time': '2017-10-24 10:41:00.412000', 'event_properties': { 'Mobile Version': True, }, }, # Last event of the session: 25 min, 5.1 sec later. { 'event_time': '2017-10-24 11:06:05.512000' }, ] }) sync_amplitude.main([ '--registered-from', '2017-11-14', '--disable-sentry', '--no-dry-run' ]) user = user_pb2.User() proto.parse_from_mongo( mock_db.user.find_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), }), user) self.assertEqual('42', user.client_metrics.amplitude_id) self.assertEqual(25 * 60 + 5, user.client_metrics.first_session_duration_seconds) self.assertEqual(project_pb2.TRUE, user.client_metrics.is_first_session_mobile)
def test_long_continuous_session( self, mock_requests: requests_mock.Mocker) -> None: """Test update_users_client_metrics with a user using Bob continuously for an hour.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) mock_requests.get( 'https://amplitude.com/api/2/usersearch?user=7ed900dbfbebdee97f9e2332', json={'matches': [{ 'amplitude_id': 42 }]}) mock_requests.get('https://amplitude.com/api/2/useractivity?user=42', json={ 'events': [ { 'event_time': '2017-10-24 10:40:00' }, { 'event_time': '2017-10-24 10:45:08' }, { 'event_time': '2017-10-24 11:06:05' }, { 'event_time': '2017-10-24 11:26:05' }, { 'event_time': '2017-10-24 11:46:05' }, { 'event_time': '2017-10-24 12:05:05' }, ] }) sync_amplitude.main([ '--registered-from', '2017-11-14', '--registered-to', '2017-11-18', '--disable-sentry', '--no-dry-run' ]) user = user_pb2.User() proto.parse_from_mongo(mock_db.user.find_one({}), user) self.assertEqual('42', user.client_metrics.amplitude_id) self.assertEqual(85 * 60 + 5, user.client_metrics.first_session_duration_seconds) self.assertEqual(project_pb2.FALSE, user.client_metrics.is_first_session_mobile)
def test_main(self, mock_mail, mock_report_mail): """Overall test.""" self._db.user.insert_one({ '_id': 'my-own-user-id', 'profile': { 'name': 'Pascal', 'lastName': 'Corpet', 'email': '*****@*****.**', }, 'registeredAt': datetime.datetime(2018, 1, 22, 10, 0, 0).isoformat() + 'Z', 'projects': [{ 'title': 'Project Title', }], }) mock_mail.send_template.return_value.status_code = 200 mock_mail.send_template.return_value.json.return_value = { 'Sent': [{ 'MessageID': 123456, }] } mock_report_mail.send_template_to_admins.return_value.status_code = 200 mail_nps.main(self._db.user, 'http://*****:*****@bayes.org', profile.email) nps_form_urlstring = template_vars.pop('npsFormUrl') self.assertEqual( { 'baseUrl': 'http://localhost:3000', 'firstName': 'Pascal', }, template_vars) nps_form_url = parse.urlparse(nps_form_urlstring) self.assertEqual( 'http://localhost:3000/api/nps', parse.urlunparse(nps_form_url[:4] + ('', ) + nps_form_url[5:])) nps_form_args = parse.parse_qs(nps_form_url.query) self.assertEqual({'user', 'token', 'redirect'}, nps_form_args.keys()) self.assertEqual(['my-own-user-id'], nps_form_args['user']) auth.check_token('my-own-user-id', nps_form_args['token'][0], role='nps') self.assertEqual(['http://localhost:3000/retours'], nps_form_args['redirect']) self.assertTrue(mock_report_mail.send_template_to_admins.called) modified_user = user_pb2.User() proto.parse_from_mongo(self._db.user.find_one(), modified_user) self.assertEqual(123456, modified_user.emails_sent[0].mailjet_message_id) self.assertEqual('nps', modified_user.emails_sent[0].campaign_id)
def fetch_use_cases(pool_name: str) -> use_case_pb2.UseCases: """Retrieve a list of anonymized user examples from one pool.""" use_cases = use_case_pb2.UseCases() use_case_dicts = _get_eval_db().use_case\ .find({'poolName': pool_name}).sort('indexInPool', 1) for use_case_dict in use_case_dicts: use_case_proto = use_cases.use_cases.add() proto.parse_from_mongo(use_case_dict, use_case_proto, 'use_case_id') return use_cases
def fetch_use_cases(pool_name: str) -> use_case_pb2.UseCases: """Retrieve a list of anonymized user examples from one pool.""" use_cases = use_case_pb2.UseCases() use_case_dicts = flask.current_app.config['EVAL_DATABASE'].use_case\ .find({'poolName': pool_name}).sort('indexInPool', 1) for use_case_dict in use_case_dicts: use_case_proto = use_cases.use_cases.add() proto.parse_from_mongo(use_case_dict, use_case_proto, 'use_case_id') return use_cases
def test_update_users_client_metrics( self, mock_requests: requests_mock.Mocker) -> None: """Test update_users_client_metrics.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) mock_requests.get( 'https://amplitude.com/api/2/usersearch?user=7ed900dbfbebdee97f9e2332', json={'matches': [{ 'amplitude_id': 42 }]}) mock_requests.get( 'https://amplitude.com/api/2/useractivity?user=42', json={ 'events': [ { 'event_time': '2017-10-24 10:41:08.396000' }, # Event out of order, this one is actually the first of the session. { 'event_time': '2017-10-24 10:41:00.412000' }, # Last event of the session: 25 min, 5.1 sec later. { 'event_time': '2017-10-24 11:06:05.512000' }, # Event really later: next session. { 'event_time': '2017-10-24 13:06:05' }, ] }) sync_amplitude.main([ '--registered-from', '2017-11-14', '--registered-to', '2017-11-18', '--disable-sentry', '--no-dry-run' ]) user = user_pb2.User() proto.parse_from_mongo(mock_db.user.find_one({}), user) self.assertEqual('42', user.client_metrics.amplitude_id) self.assertEqual(25 * 60 + 5, user.client_metrics.first_session_duration_seconds) self.assertEqual(project_pb2.FALSE, user.client_metrics.is_first_session_mobile)
def test_unknown_field_in_test_env(self) -> None: """Unknown fields make the function choke in a test environment.""" message = test_pb2.Simple() with mock.patch(proto.__name__ + '._IS_TEST_ENV', new=True): with self.assertRaises(json_format.ParseError) as error_context: proto.parse_from_mongo({ 'name': 'A123', 'unknownField': 14 }, message) self.assertIn('no field named "unknownField"', str(error_context.exception))
def _google_authenticate( self, auth_request: auth_pb2.AuthRequest) -> auth_pb2.AuthResponse: try: id_info = token.decode_google_id_token( auth_request.google_token_id) except i18n.TranslatableException as error: flask.abort(401, error.flask_translate()) response = auth_pb2.AuthResponse() user_dict = self._user_collection.find_one( {'googleId': id_info['sub']}) if proto.parse_from_mongo(user_dict, response.authenticated_user, 'user_id'): self._handle_returning_user(response) else: is_existing_user = self._load_user_from_token_or_email( auth_request, response.authenticated_user, id_info['email']) response.authenticated_user.profile.picture_url = id_info.get( 'picture', '') response.authenticated_user.google_id = id_info['sub'] response.is_new_user = not response.authenticated_user.has_account response.authenticated_user.has_account = True if is_existing_user: self._handle_returning_user(response, force_update=True) else: self.save_new_user(response.authenticated_user, auth_request.user_data) response.auth_token = token.create_token( response.authenticated_user.user_id, 'auth') return response
def test_timestamp(self): """Parse correctly Python timestamps.""" action = action_pb2.Action() now = datetime.datetime.now() self.assertTrue(proto.parse_from_mongo({'createdAt': now}, action)) self.assertEqual(now, action.created_at.ToDatetime())
def test_dry_run(self, mock_requests: requests_mock.Mocker, mock_logging: mock.MagicMock) -> None: """Test update_users_client_metrics.""" mock_db = mongomock.MongoClient().test mock_db.user.insert_one({ '_id': mongomock.ObjectId('7ed900dbfbebdee97f9e2332'), 'registeredAt': '2017-11-17T10:57:12Z', }) patcher = mock.patch(sync_amplitude.__name__ + '._DB', new=mock_db) patcher.start() self.addCleanup(patcher.stop) mock_requests.get( 'https://amplitude.com/api/2/usersearch?user=7ed900dbfbebdee97f9e2332', json={'matches': [{ 'amplitude_id': 42 }]}) mock_requests.get('https://amplitude.com/api/2/useractivity?user=42', json={ 'events': [ { 'event_time': '2017-10-24 10:41:00.412000' }, { 'event_time': '2017-10-24 11:06:05.512000' }, ] }) sync_amplitude.main([ '--registered-from', '2017-11-14', '--registered-to', '2017-11-18', '--disable-sentry' ]) user = user_pb2.User() proto.parse_from_mongo(mock_db.user.find_one({}), user) self.assertFalse(user.client_metrics.amplitude_id) self.assertFalse(user.client_metrics.first_session_duration_seconds) self.assertFalse(user.client_metrics.is_first_session_mobile) mock_logging.assert_called_once()
def _pe_connect_authenticate( self, auth_request: auth_pb2.AuthRequest) -> auth_pb2.AuthResponse: token_data = _get_oauth2_access_token( 'https://authentification-candidat.pole-emploi.fr/connexion/oauth2/access_token?' 'realm=/individu', code=auth_request.pe_connect_code, client_id=_EMPLOI_STORE_CLIENT_ID or '', client_secret=_EMPLOI_STORE_CLIENT_SECRET or '', auth_name='PE Connect', ) if token_data.get('nonce') != auth_request.pe_connect_nonce: flask.abort(403, i18n.flask_translate('Mauvais paramètre nonce')) bearer = token_data.get('token_type', 'Bearer') access_token = token_data.get('access_token', '') authorization_header = f'{bearer} {access_token}' user_info_response = requests.get( 'https://api.emploi-store.fr/partenaire/peconnect-individu/v1/userinfo', headers={'Authorization': authorization_header}) if user_info_response.status_code < 200 or user_info_response.status_code >= 400: logging.warning('PE Connect fails (%d): "%s"', user_info_response.status_code, user_info_response.text) flask.abort(403, user_info_response.text) user_info = typing.cast(dict[str, str], user_info_response.json()) response = auth_pb2.AuthResponse() user_dict = self._user_collection.find_one( {'peConnectId': user_info['sub']}) if proto.parse_from_mongo(user_dict, response.authenticated_user, 'user_id'): self._handle_returning_user(response) else: user = response.authenticated_user is_existing_user = self._load_user_from_token_or_email( auth_request, user, user_info.get('email')) user.pe_connect_id = user_info['sub'] response.is_new_user = force_update = not user.has_account user.has_account = True if is_existing_user: self._handle_returning_user(response, force_update=force_update) else: # TODO(pascal): Handle the case where one of the name is missing. user.profile.name = french.cleanup_firstname( user_info.get('given_name', '')) user.profile.last_name = french.cleanup_firstname( user_info.get('family_name', '')) user.profile.gender = _PE_CONNECT_GENDER.get( user_info.get('gender', ''), user_profile_pb2.UNKNOWN_GENDER) self.save_new_user(user, auth_request.user_data) response.auth_token = token.create_token( response.authenticated_user.user_id, 'auth') return response
def _parse_user_from_mongo(user_dict: dict[str, Any], user: user_pb2.User) -> None: if not proto.parse_from_mongo(user_dict, user, 'user_id'): flask.abort( 500, i18n.flask_translate( 'Les données utilisateur sont corrompues dans la base de données.' ))
def test_id_field(self) -> None: """if an id_field is specified, its value is filled with _id from mongo.""" message = test_pb2.Simple() self.assertTrue( proto.parse_from_mongo({ '_id': 'Hello', 'multipleWords': '123' }, message, 'name')) self.assertEqual('Hello', message.name)
def test_unknown_field(self): """Unknown fields do not make the function choke.""" job_group = job_pb2.JobGroup() self.assertTrue( proto.parse_from_mongo({ 'romeId': 'A123', 'unknownField': 14 }, job_group)) self.assertEqual('A123', job_group.rome_id)
def test_unknown_field(self) -> None: """Unknown fields do not make the function choke.""" message = test_pb2.Simple() self.assertTrue( proto.parse_from_mongo({ 'name': 'A123', 'unknownField': 14 }, message)) self.assertEqual('A123', message.name)
def _load_user_from_token_or_email( self, auth_request: auth_pb2.AuthRequest, user: user_pb2.User, email: Optional[str]) -> Tuple[bool, bool]: is_existing_user = email and proto.parse_from_mongo( self._user_collection.find_one({'hashedEmail': hash_user_email(email)}), user, 'user_id') or \ self._load_user_with_token(auth_request, user, is_timestamp_required=False) had_email = bool(user.profile.email) if not had_email and email: user.profile.email = email return is_existing_user, had_email
def load_set(cls, filename: str) -> Dict[str, '_Persona']: """Load a set of personas from a JSON file.""" with open(filename) as personas_file: personas_json = pyjson5.load(personas_file) personas: Dict[str, _Persona] = {} for name, blob in personas_json.items(): user = user_pb2.User() assert proto.parse_from_mongo(blob['user'], user.profile) if 'featuresEnabled' in blob: assert proto.parse_from_mongo(blob['featuresEnabled'], user.features_enabled) if 'project' in blob: assert proto.parse_from_mongo(blob['project'], user.projects.add()) if 'projects' in blob: for project in blob['projects']: assert proto.parse_from_mongo(project, user.projects.add()) assert name not in personas personas[name] = cls(name, user) return personas
def load_set(cls, filename): """Load a set of personas from a JSON file.""" with open(filename) as personas_file: personas_json = json.load(personas_file) personas = {} for name, blob in personas_json.items(): user_profile = user_pb2.UserProfile() assert proto.parse_from_mongo(blob['user'], user_profile) features_enabled = user_pb2.Features() if 'featuresEnabled' in blob: assert proto.parse_from_mongo(blob['featuresEnabled'], features_enabled) project = project_pb2.Project() assert proto.parse_from_mongo(blob['project'], project) assert name not in personas personas[name] = cls(name, user_profile=user_profile, project=project, features_enabled=features_enabled) return personas
def main(): """Populate departement prefix for users that don't already have one.""" query = { 'projects': { '$elemMatch': { 'mobility.city.departementId': { '$exists': True }, 'mobility.city.departementPrefix': { '$exists': False }, } } } user_count = 0 for user_in_db in _USER_DB.user.find(query): user_id = user_in_db.pop('_id') user = user_pb2.User() if not proto.parse_from_mongo(user_in_db, user): logging.warning('Impossible to parse user %s', user_id) continue departement_ids = [ project.mobility.city.departement_id for project in user.projects ] try: departement_prefixes = [ _DEPARTEMENTS.get_collection(_DB)[dep_id].prefix for dep_id in departement_ids ] except KeyError: logging.warning( 'User %s has at least one invalid departement ID %s.', user_id, ', '.join(departement_ids)) continue modifs = { '$set': { 'projects.{}.mobility.city.departementPrefix'.format(i): dep_prefix for i, dep_prefix in enumerate(departement_prefixes) }, } if not DRY_RUN: _USER_DB.user.update_one({'_id': user_id}, modifs, upsert=False) else: logging.info('Prefix populated for user %s)', user_id) user_count += 1 logging.warning('User modified:\n%s', user_count)
def test_timestamp(self) -> None: """Parse correctly Python timestamps.""" message = test_pb2.Timely() now = datetime.datetime.now() self.assertTrue( proto.parse_from_mongo( { 'createdAt': now, 'modifiedAt': [now, now], }, message)) self.assertEqual(now, message.created_at.ToDatetime()) self.assertEqual(now, message.modified_at[0].ToDatetime())
def list_use_cases_from_filters(request: use_case_pb2.UseCaseFiltersRequest) \ -> use_case_pb2.UseCases: """Fetch a list of recent use cases satisfying a given list of filters.""" request.max_count = request.max_count or _MAX_MATCHING_USE_CASES request.max_search_count = request.max_search_count or _MAX_SEARCHED_USE_CASES use_cases = use_case_pb2.UseCases() use_case_iterator = _get_eval_db().use_case.find( {'_id': _AUTOMATIC_EVAL_USE_CASE_ID_REGEX} ).sort([('_id', -1)]).limit(request.max_search_count) for use_case_json in use_case_iterator: use_case = use_cases.use_cases.add() proto.parse_from_mongo(use_case_json, use_case, 'use_case_id') try: if not _match_filters_for_use_case(request.filters, use_case): del use_cases.use_cases[-1] except KeyError as err: flask.abort(404, str(err)) if len(use_cases.use_cases) >= request.max_count: break return use_cases
def user_to_use_case(user, pool_name, index_in_pool): """Extracts a use case from a real user.""" use_case = use_case_pb2.UseCase() if not proto.parse_from_mongo(user, use_case.user_data): return None use_case.title = next((p.title for p in use_case.user_data.projects), '') anonymize_proto(use_case.user_data, field_usages_to_clear={ options_pb2.PERSONAL_IDENTIFIER, options_pb2.APP_ONLY, options_pb2.ALGORITHM_RESULT, }) use_case.pool_name = pool_name use_case.index_in_pool = index_in_pool use_case.use_case_id = '{}_{:02x}'.format(pool_name, index_in_pool) return use_case
def test_weird_objects(self, mock_warning): """Raises a TypeError when an object is not of the right type.""" job_group = job_pb2.JobGroup() self.assertFalse(proto.parse_from_mongo({'romeId': 123}, job_group)) mock_warning.assert_called_once() self.assertEqual( 'Error %s while parsing a JSON dict for proto type %s:\n%s', mock_warning.call_args[0][0]) self.assertEqual( 'Failed to parse romeId field: expected string or bytes-like object.', str(mock_warning.call_args[0][1])) self.assertEqual('JobGroup', str(mock_warning.call_args[0][2])) self.assertEqual("{'romeId': 123}", str(mock_warning.call_args[0][3]))
def test_weird_objects(self, mock_warning: mock.MagicMock) -> None: """Raises a TypeError when an object is not of the right type.""" message = test_pb2.Simple() self.assertFalse(proto.parse_from_mongo({'name': 123}, message)) mock_warning.assert_called_once() self.assertEqual( 'Error %s while parsing a JSON dict for proto type %s:\n%s', mock_warning.call_args[0][0]) self.assertEqual( 'Failed to parse name field: expected string or bytes-like object.', str(mock_warning.call_args[0][1])) self.assertEqual('Simple', str(mock_warning.call_args[0][2])) self.assertEqual("{'name': 123}", str(mock_warning.call_args[0][3]))
def _linked_in_authenticate(self, code): token_data = _get_oauth2_access_token( 'https://www.linkedin.com/oauth/v2/accessToken', code=code, client_id=_LINKED_IN_CLIENT_ID, client_secret=_LINKED_IN_CLIENT_SECRET, auth_name='LinkedIn Auth', ) authorization_header = '{} {}'.format( token_data.get('token_type', 'Bearer'), token_data.get('access_token', '')) user_info_response = requests.get( 'https://api.linkedin.com/v1/people/~:' '(id,location,first-name,last-name,email-address)?format=json', headers={'Authorization': authorization_header}) if user_info_response.status_code < 200 or user_info_response.status_code >= 400: logging.warning('LinkedIn Auth fails (%d): "%s"', user_info_response.status_code, user_info_response.text) flask.abort(403, user_info_response.text) user_info = user_info_response.json() response = user_pb2.AuthResponse() # TODO(cyrille): Factorize with other 3rd party auth. user_dict = self._user_db.user.find_one( {'linkedInId': user_info['id']}) user_id = str(user_dict.pop('_id')) if user_dict else '' if proto.parse_from_mongo(user_dict, response.authenticated_user): response.authenticated_user.user_id = user_id self._handle_returning_user(response) else: email = user_info.get('emailAddress') if email: self._assert_user_not_existing(email) response.authenticated_user.profile.email = email user = response.authenticated_user user.linked_in_id = user_info['id'] # TODO(pascal): Handle the case where one of the name is missing. user.profile.name = user_info.get('firstName', '') user.profile.last_name = user_info.get('lastName', '') self._save_new_user(user) response.is_new_user = True response.auth_token = create_token(response.authenticated_user.user_id, 'auth') return response