def test_it_generates_the_next_profile_id(): def id_generator(): return '11111111' profiles = SQLAlchemyProfiles(db, id_generator) assert profiles.next_id() == '11111111'
def _update_email_addresses_from_orcid_record(profile: Profile, orcid_record: dict) -> None: orcid_email_dicts = extract_email_addresses(orcid_record) profiles = SQLAlchemyProfiles(db) for index, email_dict in enumerate(orcid_email_dicts): email = email_dict.get('email') try: email_profile = profiles.get_by_email_address(email) except ProfileNotFound: continue if email_profile.id != profile.id: message = ('Profile %s is trying to add email address %s but this ' 'email is associated with profile %s which violates ' 'unique constraint for email addresses' % (profile.id, email, email_profile.id)) LOGGER.error(message) del orcid_email_dicts[index] for email in profile.email_addresses: found = False for orcid_email in orcid_email_dicts: if orcid_email['email'] == email.email: found = True break if not found: profile.remove_email_address(email.email) for orcid_email in orcid_email_dicts: profile.add_email_address( orcid_email['email'], orcid_email['primary'], orcid_email['visibility'] != VISIBILITY_PUBLIC)
def test_it_lists_profiles_in_slices(): profiles = SQLAlchemyProfiles(db) profiles.add(Profile('11111111', Name('Name 1'))) profiles.add(Profile('11111112', Name('Name 2'))) profiles.add(Profile('11111113', Name('Name 3'))) profiles_list = profiles.list(limit=1) assert len(profiles_list) == 1 assert str(profiles_list[0].name) == 'Name 3' profiles_list = profiles.list(offset=1) assert len(profiles_list) == 2 assert str(profiles_list[0].name) == 'Name 2' assert str(profiles_list[1].name) == 'Name 1' profiles_list = profiles.list(limit=1, offset=1) assert len(profiles_list) == 1 assert str(profiles_list[0].name) == 'Name 2' profiles_list = profiles.list(offset=10) assert len(profiles_list) == 0
def test_it_limits_retrying_when_generating_the_next_profile_id(): def id_generator(): return '11111111' profiles = SQLAlchemyProfiles(db, id_generator) profiles.add(Profile('11111111', Name('name'))) with pytest.raises(RuntimeError): assert profiles.next_id()
def test_it_avoids_orcid_conflicts(): profiles = SQLAlchemyProfiles(db) profile1 = Profile('12345678', Name('name1'), '0000-0002-1825-0097') profile2 = Profile('12345679', Name('name2'), '0000-0002-1825-0097') profile1 = profiles.add(profile1) profile2 = profiles.add(profile2) assert profile1 == profile2 with pytest.raises(ProfileNotFound): profiles.get('12345679')
def test_it_retries_generating_the_next_profile_id(): counter = 0 def id_generator(): nonlocal counter counter = counter + 1 return str(11111110 + counter) profiles = SQLAlchemyProfiles(db, id_generator) profiles.add(Profile('11111111', Name('name'))) assert profiles.next_id() == '11111112'
def test_it_clears_profiles(): profiles = SQLAlchemyProfiles(db) profiles.add(Profile('11111111', Name('name'))) profiles.clear() with pytest.raises(ProfileNotFound): profiles.get('11111111')
def test_it_avoids_email_address_conflicts(): profiles = SQLAlchemyProfiles(db) profile1 = Profile('12345678', Name('name1')) profile1.add_email_address('*****@*****.**') profile2 = Profile('12345679', Name('name2')) profile2.add_email_address('*****@*****.**') profile1 = profiles.add(profile1) profile2 = profiles.add(profile2) assert profile1 == profile2 with pytest.raises(ProfileNotFound): profiles.get('12345679')
def test_can_run_command_multiple_times(profiles: SQLAlchemyProfiles) -> None: cmd = CreateProfileCommand(profiles=profiles) for _ in range(5): cmd.run('Test User', '*****@*****.**') assert len(profiles.list()) == 1
def create_app(config: Config, clients: Clients) -> Flask: app = Flask(__name__) app.TRAP_HTTP_EXCEPTIONS = True app.config.from_object(config) db.app = app db.init_app(app) Migrate(app, db) orcid_client = OrcidClient(config.orcid['api_uri']) app.orcid_client = orcid_client orcid_tokens = SQLAlchemyOrcidTokens(db) profiles = SQLAlchemyProfiles(db) uri_signer = URLSafeSerializer(config.orcid['webhook_key'], signer_kwargs={'key_derivation': 'hmac', 'digest_method': hashlib.sha512}) config_bus = dict(config.bus) config_bus['env'] = config.name publisher = get_publisher(config=config_bus) app.commands = [ ClearCommand(orcid_tokens, profiles), CreateProfileCommand(profiles), ReadConfiguration(config), SetOrcidWebhooksCommand(profiles, config.orcid, orcid_client, uri_signer) ] app.register_blueprint(api.create_blueprint(profiles)) app.register_blueprint(oauth2.create_blueprint(config.orcid, clients, profiles, orcid_client, orcid_tokens), url_prefix='/oauth2') app.register_blueprint(ping.create_blueprint()) app.register_blueprint(webhook.create_blueprint(profiles, config.orcid, orcid_client, orcid_tokens, uri_signer)) from werkzeug.exceptions import default_exceptions for code in default_exceptions: app.errorhandler(code)(errors.http_error_handler) app.register_error_handler(Exception, errors.error_handler) app.register_error_handler(ClientError, errors.client_error_handler) app.register_error_handler(OAuth2Error, errors.oauth2_error_handler) models_committed.connect(maintain_orcid_webhook(config.orcid, orcid_client, uri_signer), weak=False) models_committed.connect(send_update_events(publisher=publisher), weak=False) return app
def test_it_gets_profiles_by_their_orcid(): profiles = SQLAlchemyProfiles(db) profile1 = Profile('12345678', Name('name1'), '0000-0002-1825-0097') profile2 = Profile('12345679', Name('name2')) profiles.add(profile1) profiles.add(profile2) assert profiles.get_by_orcid('0000-0002-1825-0097') == profile1 with pytest.raises(ProfileNotFound): profiles.get_by_orcid('0000-0002-1825-0098')
def test_it_lists_profiles(): profiles = SQLAlchemyProfiles(db) profiles.add(Profile('11111111', Name('Name 1'))) profiles.add(Profile('11111112', Name('Name 2'))) profiles.add(Profile('11111113', Name('Name 3'))) profiles_list = profiles.list() assert len(profiles_list) == 3 assert str(profiles_list[0].name) == 'Name 3' assert str(profiles_list[1].name) == 'Name 2' assert str(profiles_list[2].name) == 'Name 1' profiles_list = profiles.list(desc=False) assert len(profiles_list) == 3 assert str(profiles_list[0].name) == 'Name 1' assert str(profiles_list[1].name) == 'Name 2' assert str(profiles_list[2].name) == 'Name 3'
def test_it_contains_profiles(): profiles = SQLAlchemyProfiles(db) profile1 = Profile('12345678', Name('name1'), '0000-0002-1825-0097') profile2 = Profile('12345679', Name('name2')) profile1 = profiles.add(profile1) profile2 = profiles.add(profile2) assert profiles.get('12345678') == profile1 assert profiles.get('12345679') == profile2 with pytest.raises(ProfileNotFound): profiles.get('12345670')
def test_it_gets_profiles_by_their_email_address(): profiles = SQLAlchemyProfiles(db) profile1 = Profile('12345678', Name('name1')) profile1.add_email_address('*****@*****.**') profile1.add_email_address('*****@*****.**') profile2 = Profile('12345679', Name('name2')) profile2.add_email_address('*****@*****.**') profiles.add(profile1) profiles.add(profile2) assert profiles.get_by_email_address('*****@*****.**') == profile1 assert profiles.get_by_email_address('*****@*****.**') == profile1 assert profiles.get_by_email_address('*****@*****.**', '*****@*****.**') == profile1 assert profiles.get_by_email_address('*****@*****.**', '*****@*****.**') == profile1 assert profiles.get_by_email_address('*****@*****.**') == profile2 with pytest.raises(ProfileNotFound): profiles.get_by_email_address() with pytest.raises(ProfileNotFound): profiles.get_by_email_address('*****@*****.**') with pytest.raises(ProfileNotFound): profiles.get_by_email_address('*****@*****.**', '*****@*****.**')
def profiles() -> SQLAlchemyProfiles: return SQLAlchemyProfiles(db)
def test_can_create_profile_via_command(profiles: SQLAlchemyProfiles) -> None: cmd = CreateProfileCommand(profiles=profiles) cmd.run('Test User', '*****@*****.**') assert profiles.get_by_email_address('*****@*****.**')