예제 #1
0
def test_it_generates_the_next_profile_id():
    def id_generator():
        return '11111111'

    profiles = SQLAlchemyProfiles(db, id_generator)

    assert profiles.next_id() == '11111111'
예제 #2
0
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)
예제 #3
0
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
예제 #4
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()
예제 #5
0
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')
예제 #6
0
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'
예제 #7
0
def test_it_clears_profiles():
    profiles = SQLAlchemyProfiles(db)
    profiles.add(Profile('11111111', Name('name')))
    profiles.clear()

    with pytest.raises(ProfileNotFound):
        profiles.get('11111111')
예제 #8
0
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
예제 #10
0
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
예제 #11
0
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')
예제 #12
0
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'
예제 #13
0
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')
예제 #14
0
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('*****@*****.**', '*****@*****.**')
예제 #15
0
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('*****@*****.**')