Skip to content

Commit

Permalink
Feature-authorized-scopes-updater (#560)
Browse files Browse the repository at this point in the history
* support Determinative type for transliteration

* Implemented API for updating authorized_scopes of the fragment

* Type check and reformatting

* Type check fixed

* Added test for authorized scopes

* Refactorring

* Adjusted tests

* Fixed type check

* Fixed Lint

* Authorized scopes are included in Fragment Schema

* Removed  excluding of authorizedScopes in Fragment Schema

* Reformatting

* Fix provenance resource (#562)

* adapt on_get to return provenance parents in square brackets

* reformatting

* Fixed test for provenance

* Exclude restricted fragments from the latest addition list (#563)

* Remove user scopes from latest addition aggregation
Only include "open for all" fragments

* add test_query_latest_skips_restricted_fragments

* Correct AfO Register query

* Correct format of AfO Register Query

* Add Chicago numbers to Fragment (#564)

* Add Aro Folios (#565)

* remove push to old registry (#566)

* genres add Qutāru (#567)

* Update Scope format (#570)

* update ScopeField

* update function call

* update test data

* update match_user_scopes

* Reformatting

* add connection limit

* Switch to ruff (#571)

* install ruff

* reformat files

* fix mocking calls to user profile

* suppress "Unable to concatenate tuple [60]" error

* fix formatting error

* refactor

* update tasks

* use ruff for linting and formatting

* remove old config file

* bugfix

* add ruff

* replace tuple() with ()

* remove C408 from ignored rules

* replace `tuple()` with literal `()` and reformat

* Adapted tests

* Reformatting

---------

Co-authored-by: fsimonjetz <[email protected]>
Co-authored-by: Enrique Jiménez <[email protected]>
Co-authored-by: Enrique Jiménez <[email protected]>
Co-authored-by: zsomborfoldi <[email protected]>
Co-authored-by: fsimonjetz <[email protected]>
  • Loading branch information
6 people authored Aug 6, 2024
1 parent 759e74c commit b46c5ee
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 5 deletions.
3 changes: 0 additions & 3 deletions ebl/fragmentarium/application/fragment_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,4 @@ def make_fragment(self, data, **kwargs):

@post_dump
def filter_none(self, data, **kwargs) -> dict:
scope = data.get("authorizedScopes")
if scope is not None and len(scope) == 0:
data.pop("authorizedScopes")
return pydash.omit_by(data, pydash.is_none)
9 changes: 9 additions & 0 deletions ebl/fragmentarium/application/fragment_updater.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enum import Enum
from typing import Sequence, Tuple, Optional

from ebl.bibliography.application.bibliography import Bibliography
Expand Down Expand Up @@ -117,6 +118,14 @@ def update_genres(

return self._create_result(updated_fragment)

def update_scopes(
self, number: MuseumNumber, scopes: Sequence[Enum]
) -> Tuple[Fragment, bool]:
fragment = self._repository.query_by_museum_number(number)
updated_fragment = fragment.set_scopes(scopes)
self._repository.update_field("authorized_scopes", updated_fragment)
return self._create_result(updated_fragment)

def update_lemmatization(
self, number: MuseumNumber, lemmatization: Lemmatization, user: User
) -> Tuple[Fragment, bool]:
Expand Down
4 changes: 4 additions & 0 deletions ebl/fragmentarium/domain/fragment.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enum import Enum
from itertools import groupby
from typing import Optional, Sequence, Tuple

Expand Down Expand Up @@ -209,6 +210,9 @@ def update_transliteration(
def set_genres(self, genres_new: Sequence[Genre]) -> "Fragment":
return attr.evolve(self, genres=tuple(genres_new))

def set_scopes(self, scopes_new: Sequence[Enum]) -> "Fragment":
return attr.evolve(self, authorized_scopes=list(scopes_new))

def set_date(self, date_new: Optional[Date]) -> "Fragment":
return attr.evolve(self, date=date_new)

Expand Down
3 changes: 3 additions & 0 deletions ebl/fragmentarium/infrastructure/mongo_fragment_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def update_field(self, field, fragment):
"date": ("date",),
"dates_in_text": ("dates_in_text",),
"colophon": ("colophon",),
"authorized_scopes": [
"authorized_scopes",
],
}

if field not in fields_to_update:
Expand Down
5 changes: 5 additions & 0 deletions ebl/fragmentarium/web/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from ebl.fragmentarium.web.fragment_pager import make_fragment_pager_resource
from ebl.fragmentarium.web.fragment_search import FragmentSearch
from ebl.fragmentarium.web.fragments import (
FragmentAuthorizedScopesResource,
FragmentsQueryResource,
FragmentsResource,
FragmentsListResource,
Expand Down Expand Up @@ -112,6 +113,9 @@ def create_fragmentarium_routes(api: falcon.App, context: Context):
transliteration = TransliterationResource(
updater, context.get_transliteration_update_factory()
)
scopes = FragmentAuthorizedScopesResource(
context.fragment_repository, finder, updater
)
introduction = IntroductionResource(updater)
archaeology = ArchaeologyResource(updater)
colophon = ColophonResource(updater)
Expand Down Expand Up @@ -164,6 +168,7 @@ def create_fragmentarium_routes(api: falcon.App, context: Context):
("/fragments/all-signs", all_signs),
("/fragments/colophon-names", colophon_names),
("/findspots", findspots),
("/fragments/{number}/scopes", scopes),
]

for uri, resource in routes:
Expand Down
30 changes: 30 additions & 0 deletions ebl/fragmentarium/web/fragments.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
from ebl.files.application.file_repository import FileRepository
from ebl.fragmentarium.application.fragment_finder import FragmentFinder
from ebl.fragmentarium.application.fragment_repository import FragmentRepository
from ebl.fragmentarium.application.fragment_updater import FragmentUpdater
from ebl.fragmentarium.web.dtos import create_response_dto, parse_museum_number
from ebl.schemas import ScopeField
from ebl.transliteration.application.museum_number_schema import MuseumNumberSchema
from ebl.transliteration.application.text_schema import TextSchema
from ebl.transliteration.application.transliteration_query_factory import (
Expand Down Expand Up @@ -107,6 +109,34 @@ def on_get(self, req: Request, resp: Response):
)


class FragmentAuthorizedScopesResource:
def __init__(
self,
repository: FragmentRepository,
finder: FragmentFinder,
updater: FragmentUpdater,
):
self._repository = repository
self._finder = finder
self._updater = updater

@falcon.before(require_fragment_read_scope)
def on_post(self, req: Request, resp: Response, number: str) -> None:
try:
user = req.context.user
updated_fragment, has_photo = self._updater.update_scopes(
parse_museum_number(number),
[
ScopeField()._deserialize_enum(scope)
for scope in req.media["authorized_scopes"]
],
)
resp.status = falcon.HTTP_200
resp.media = create_response_dto(updated_fragment, user, has_photo)
except ValueError as error:
raise DataError(error)


class FragmentsListResource:
def __init__(
self,
Expand Down
1 change: 1 addition & 0 deletions ebl/tests/fragmentarium/test_dtos.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def expected_dto(lemmatized_fragment, has_photo):
"projects": [ResearchProject["CAIC"].abbreviation],
"archaeology": ArchaeologySchema().dump(lemmatized_fragment.archaeology),
"colophon": ColophonSchema().dump(lemmatized_fragment.colophon),
"authorizedScopes": [],
},
pydash.is_none,
)
Expand Down
12 changes: 12 additions & 0 deletions ebl/tests/fragmentarium/test_fragment_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,18 @@ def test_update_genres(fragment_repository):
assert result == updated_fragment


def test_update_scopes(
fragment_repository,
):
fragment = FragmentFactory.build(authorized_scopes=[])
fragment_repository.create(fragment)
scopes = [Scope.READ_CAIC_FRAGMENTS]
updated_fragment = fragment.set_scopes(scopes)
fragment_repository.update_field("authorized_scopes", updated_fragment)
result = fragment_repository.query_by_museum_number(fragment.number)
assert result == updated_fragment


def test_update_date(fragment_repository):
fragment = FragmentFactory.build(date=None)
fragment_repository.create(fragment)
Expand Down
57 changes: 57 additions & 0 deletions ebl/tests/fragmentarium/test_fragment_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import json

import falcon
import pytest

from ebl.common.domain.scopes import Scope
from ebl.schemas import ScopeField
from ebl.fragmentarium.web.dtos import create_response_dto
from ebl.tests.factories.fragment import FragmentFactory


@pytest.mark.parametrize(
"parameters",
[
{
"currentScopes": [],
"newScopes": [Scope.READ_CAIC_FRAGMENTS],
},
{
"currentScopes": [Scope.READ_CAIC_FRAGMENTS],
"newScopes": [
Scope.READ_ITALIANNINEVEH_FRAGMENTS,
Scope.READ_CAIC_FRAGMENTS,
],
},
{
"currentScopes": [Scope.READ_CAIC_FRAGMENTS],
"newScopes": [],
},
],
)
def test_update_scopes(client, fragmentarium, user, parameters):
fragment = FragmentFactory.build(authorized_scopes=parameters["currentScopes"])
fragment_number = fragmentarium.create(fragment)
updates = {"authorized_scopes": parameters["newScopes"]}
json_updates = {
"authorized_scopes": [
ScopeField()._serialize_enum(scope)
for scope in parameters["newScopes"]
if scope
]
}
post_result = client.simulate_post(
f"/fragments/{fragment_number}/scopes", body=json.dumps(json_updates)
)
expected_json = {
**create_response_dto(
fragment.set_scopes(updates["authorized_scopes"]),
user,
fragment.number == "K.1",
)
}
assert post_result.status == falcon.HTTP_OK
assert post_result.json == expected_json

get_result = client.simulate_get(f"/fragments/{fragment_number}")
assert get_result.json == expected_json
20 changes: 20 additions & 0 deletions ebl/tests/fragmentarium/test_fragment_updater.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from ebl.common.domain.scopes import Scope
from freezegun import freeze_time
import pytest

Expand Down Expand Up @@ -136,6 +137,25 @@ def test_update_genres(
assert result == (injected_fragment, False)


def test_update_scopes(
fragment_updater, fragment_repository, user, parallel_line_injector, when
):
fragment = FragmentFactory.build()
number = fragment.number
scopes = [Scope.READ_CAIC_FRAGMENTS]
updated_fragment = fragment.set_scopes(scopes)
injected_fragment = updated_fragment.set_text(
parallel_line_injector.inject_transliteration(updated_fragment.text)
)
when(fragment_repository).query_by_museum_number(number).thenReturn(fragment)
when(fragment_repository).update_field(
"authorized_scopes", updated_fragment
).thenReturn()
result = fragment_updater.update_scopes(number, scopes)

assert result == (injected_fragment, False)


def test_update_date(
fragment_updater, user, fragment_repository, parallel_line_injector, changelog, when
):
Expand Down
4 changes: 2 additions & 2 deletions ebl/tests/fragmentarium/test_fragments_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,5 @@ def test_fragments_retrieve_all(guest_client, fragmentarium):
fragmentarium.create(fragment)
result = guest_client.simulate_get("/fragments/retrieve-all?skip=0")
assert result.status == falcon.HTTP_OK
assert len(result.json["fragments"]) == 5
assert result.json["totalCount"] == 5
assert len(result.json["fragments"]) == 0
assert result.json["totalCount"] == 0

0 comments on commit b46c5ee

Please sign in to comment.