Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove flask upper pin #411

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions invenio_vocabularies/datastreams/writers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2021-2024 CERN.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand Down Expand Up @@ -96,12 +97,13 @@ def write(self, stream_entry, *args, **kwargs):

try:
if self._insert:
try:
return StreamEntry(self._service.create(self._identity, entry))
except PIDAlreadyExists:
if not self._update:
raise WriterError([f"Vocabulary entry already exists: {entry}"])
return self._do_update(entry)
ret = StreamEntry(self._service.create(self._identity, entry))

# with that state management it is avoidable to check if pid
# exists and run into possible rollback problems
if self._update:
self._insert = False
return ret
elif self._update:
try:
return self._do_update(entry)
Expand All @@ -112,6 +114,8 @@ def write(self, stream_entry, *args, **kwargs):
["Writer wrongly configured to not insert and to not update"]
)

except PIDAlreadyExists:
raise WriterError([f"Vocabulary entry already exists: {entry}"])
except ValidationError as err:
raise WriterError([{"ValidationError": err.messages}])
except InvalidRelationValue as err:
Expand Down
5 changes: 4 additions & 1 deletion invenio_vocabularies/records/systemfields/pid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# Copyright (C) 2020-2021 CERN.
# Copyright (C) 2020 Northwestern University.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Records-Resources is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand Down Expand Up @@ -100,7 +101,9 @@ def resolve(self, pid_value):
def get_pid_type(self, type_id):
"""Get the PID type for a vocabulary type."""
# Get type based on name.
vocab_type = VocabularyType.query.filter_by(id=type_id).one_or_none()
vocab_type = (
db.session.query(VocabularyType).filter_by(id=type_id).one_or_none()
)
if vocab_type is None:
raise PIDDoesNotExistError(None, None)
return vocab_type.pid_type
Expand Down
7 changes: 6 additions & 1 deletion invenio_vocabularies/services/components.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020-2021 CERN.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
# details.

"""Vocabulary components."""

from invenio_db import db
from invenio_i18n import lazy_gettext as _
from invenio_records_resources.services.records.components import ServiceComponent
from marshmallow import ValidationError
Expand All @@ -23,7 +25,10 @@ def _set_type(self, data, record):
type_id = data.pop("type", None)
if type_id:
try:
record.type = VocabularyType.query.filter_by(id=type_id["id"]).one()

record.type = (
db.session.query(VocabularyType).filter_by(id=type_id["id"]).one()
)
except NoResultFound:
raise ValidationError(
_("The vocabulary type does not exists."),
Expand Down
11 changes: 7 additions & 4 deletions invenio_vocabularies/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright (C) 2024 CERN.
# Copyright (C) 2021 Northwestern University.
# Copyright (C) 2024 University of Münster.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand All @@ -12,6 +13,7 @@

import sqlalchemy as sa
from invenio_cache import current_cache
from invenio_db import db
from invenio_records_resources.services import LinksTemplate, RecordService
from invenio_records_resources.services.base.utils import map_search_params
from invenio_records_resources.services.records.schema import ServiceSchemaWrapper
Expand Down Expand Up @@ -42,7 +44,8 @@ def search(self, identity, params=None):
filters.extend([VocabularyType.id.ilike(f"%{query_param}%")])

vocabulary_types = (
VocabularyType.query.filter(sa.or_(*filters))
db.session.query(VocabularyType)
.filter(sa.or_(*filters))
.order_by(
search_params["sort_direction"](
sa.text(",".join(search_params["sort"]))
Expand Down Expand Up @@ -87,7 +90,7 @@ def search(
self.require_permission(identity, "search")

# If not found, NoResultFound is raised (caught by the resource).
vocabulary_type = VocabularyType.query.filter_by(id=type).one()
vocabulary_type = db.session.query(VocabularyType).filter_by(id=type).one()

# Prepare and execute the search
params = params or {}
Expand Down Expand Up @@ -123,7 +126,7 @@ def read_all(self, identity, fields, type, cache=True, extra_filter="", **kwargs

if not results:
# If not found, NoResultFound is raised (caught by the resource).
vocabulary_type = VocabularyType.query.filter_by(id=type).one()
vocabulary_type = db.session.query(VocabularyType).filter_by(id=type).one()
vocab_id_filter = dsl.Q("term", type__id=vocabulary_type.id)
if extra_filter:
vocab_id_filter = vocab_id_filter & extra_filter
Expand All @@ -150,7 +153,7 @@ def read_all(self, identity, fields, type, cache=True, extra_filter="", **kwargs
def read_many(self, identity, type, ids, fields=None, **kwargs):
"""Search for records matching the querystring filtered by ids."""
search_query = dsl.Q("match_all")
vocabulary_type = VocabularyType.query.filter_by(id=type).one()
vocabulary_type = db.session.query(VocabularyType).filter_by(id=type).one()
vocab_id_filter = dsl.Q("term", type__id=vocabulary_type.id)
filters = []

Expand Down
11 changes: 5 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright (C) 2020-2024 CERN.
# Copyright (C) 2021 TU Wien.
# Copyright (C) 2024 California Institute of Technology.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand Down Expand Up @@ -76,7 +77,7 @@ def extra_entry_points():
@pytest.fixture(scope="module")
def app_config(app_config):
"""Mimic an instance's configuration."""
app_config["JSONSCHEMAS_HOST"] = "localhost"
app_config["JSONSCHEMAS_HOST"] = "not-used"
app_config["BABEL_DEFAULT_LOCALE"] = "en"
app_config["I18N_LANGUAGES"] = [("da", "Danish")]
app_config["RECORDS_REFRESOLVER_CLS"] = (
Expand Down Expand Up @@ -119,11 +120,11 @@ def service(app):
return app.extensions["invenio-vocabularies"].vocabularies_service


@pytest.fixture()
@pytest.fixture(scope="function")
def lang_type(db):
"""Get a language vocabulary type."""
v = VocabularyType.create(id="languages", pid_type="lng")
db.session.commit()
db.session.add(v)
return v


Expand Down Expand Up @@ -158,7 +159,6 @@ def example_record(db, identity, service, example_data):
vocabulary_type_licenses = VocabularyType(name="licenses")
db.session.add(vocabulary_type_languages)
db.session.add(vocabulary_type_licenses)
db.session.commit()

record = service.create(
identity=identity,
Expand Down Expand Up @@ -192,7 +192,7 @@ def user(app, db):
password=hash_password("password"),
active=True,
)
db.session.commit()

return _user


Expand All @@ -203,7 +203,6 @@ def role(app, db):
datastore = app.extensions["security"].datastore
role = datastore.create_role(name="admin", description="admin role")

db.session.commit()
return role


Expand Down
15 changes: 13 additions & 2 deletions tests/contrib/affiliations/test_affiliations_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# This file is part of Invenio.
# Copyright (C) 2021-2024 CERN.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand Down Expand Up @@ -30,7 +31,6 @@ def example_affiliation(
"""Example affiliation."""
aff = service.create(identity, affiliation_full_data)
Affiliation.index.refresh() # Refresh the index

return aff


Expand All @@ -41,7 +41,7 @@ def test_affiliations_invalid(client, h, prefix):
assert res.status_code == 404


def test_affiliations_forbidden(
def test_affiliations_forbidden_a(
client, h, prefix, example_affiliation, affiliation_full_data
):
"""Test invalid type."""
Expand All @@ -53,11 +53,22 @@ def test_affiliations_forbidden(
)
assert res.status_code == 403


def test_affiliations_forbidden_b(
client, h, prefix, example_affiliation, affiliation_full_data
):
"""Test put."""
res = client.put(
f"{prefix}/01ggx4157", headers=h, data=json.dumps(affiliation_full_data)
)

assert res.status_code == 403


def test_affiliations_forbidden_c(
client, h, prefix, example_affiliation, affiliation_full_data
):
"""Test delete."""
res = client.delete(f"{prefix}/01ggx4157")
assert res.status_code == 403

Expand Down
78 changes: 68 additions & 10 deletions tests/contrib/awards/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2022 CERN.
# Copyright (C) 2024 Graz University of Technology.
#
# Invenio-Vocabularies is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see LICENSE file for more
Expand All @@ -13,12 +14,14 @@
"""

import pytest
from invenio_i18n import lazy_gettext as _
from invenio_indexer.proxies import current_indexer_registry
from invenio_records_resources.proxies import current_service_registry
from sqlalchemy.orm.exc import ObjectDeletedError

from invenio_vocabularies.contrib.awards.api import Award
from invenio_vocabularies.contrib.awards.models import AwardsMetadata
from invenio_vocabularies.contrib.funders.api import Funder
from invenio_vocabularies.contrib.funders.models import FundersMetadata


#
Expand All @@ -38,10 +41,27 @@ def example_funder(db, identity, funders_service, funder_indexer):
}
funder = funders_service.create(identity, funder_data)
Funder.index.refresh() # Refresh the index

funder_id = funder._record.id
index = type("index", (), {"_name": funder._record.index._name})
funder_dict = type(
"",
(),
{
"index": index(),
"id": funder._record.id,
"revision_id": funder._record.revision_id,
},
)

yield funder
funder._record.delete(force=True)
funder_indexer.delete(funder._record, refresh=True)
db.session.commit()

db.session.query(FundersMetadata).filter(FundersMetadata.id == funder_id).delete()

try:
funder_indexer.delete(funder._record, refresh=True)
except ObjectDeletedError:
funder_indexer.delete(funder_dict(), refresh=True)


@pytest.fixture(scope="function")
Expand All @@ -55,10 +75,27 @@ def example_funder_ec(db, identity, funders_service, funder_indexer):
}
funder = funders_service.create(identity, funder_data)
Funder.index.refresh() # Refresh the index

funder_id = funder._record.id
index = type("index", (), {"_name": funder._record.index._name})
funder_dict = type(
"",
(),
{
"index": index(),
"id": funder._record.id,
"revision_id": funder._record.revision_id,
},
)

yield funder
funder._record.delete(force=True)
funder_indexer.delete(funder._record, refresh=True)
db.session.commit()

db.session.query(FundersMetadata).filter(FundersMetadata.id == funder_id).delete()

try:
funder_indexer.delete(funder._record, refresh=True)
except ObjectDeletedError:
funder_indexer.delete(funder_dict(), refresh=True)


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -125,10 +162,31 @@ def example_award(db, example_funder_ec, award_full_data, identity, indexer, ser
"""Creates and hard deletes an award."""
award = service.create(identity, award_full_data)
Award.index.refresh() # Refresh the index

# necessary step for the clean up part after yield
# award._record could be gone if there was a intended rollback
# in one of the test functions
award_id = award._record.id
index = type("index", (), {"_name": award._record.index._name})
award_dict = type(
"",
(),
{
"index": index(),
"id": award._record.id,
"revision_id": award._record.revision_id,
},
)

yield award
award._record.delete(force=True)
indexer.delete(award._record, refresh=True)
db.session.commit()

# to clean up
db.session.query(AwardsMetadata).filter(AwardsMetadata.id == award_id).delete()

try:
indexer.delete(award._record, refresh=True)
except ObjectDeletedError:
indexer.delete(award_dict(), refresh=True)


@pytest.fixture(scope="module")
Expand Down
Loading