diff --git a/.github/workflows/pr_checks.yaml b/.github/workflows/pr_checks.yaml index ad8b33f..c21b1c1 100644 --- a/.github/workflows/pr_checks.yaml +++ b/.github/workflows/pr_checks.yaml @@ -63,6 +63,7 @@ jobs: echo "CAPTURA_CONFIG_CLIENT=$docker_config_path" >> .env echo "CAPTURA_CONFIG_APP_TEST=$docker_config_path" >> .env echo "CAPTURA_CONFIG_APP=$docker_config_path" >> .env + echo "CAPTURA_CONFIG_DUMMY=$docker_config_path" >> .env echo "CAPTURA_FLAKEY=/home/captura/flakey.yaml" >> .env - name: Start Docker Compose Project. @@ -83,9 +84,12 @@ jobs: echo "MySQL Version: $version" >> $GITHUB_STEP_SUMMARY docker compose \ --file docker/compose.ci.yaml \ + --env-file .env \ exec server \ bash -c ' \ source ~/app/.venv/bin/activate \ + && echo $CAPTURA_CONFIG_DUMMY \ + && echo $CAPTURA_CONFIG_APP_TEST \ && poetry run simulatus initialize \ && poetry run simulatus apply' @@ -103,6 +107,7 @@ jobs: run: | docker compose \ --file docker/compose.ci.yaml \ + --env-file .env \ exec server \ bash -c ' \ source ~/app/.venv/bin/activate \ @@ -123,6 +128,7 @@ jobs: run: | docker compose \ --file docker/compose.ci.yaml \ + --env-file .env \ exec server \ bash -c ' \ source ~/app/.venv/bin/activate \ @@ -140,6 +146,7 @@ jobs: run: | docker compose \ --file docker/compose.ci.yaml \ + --env-file .env \ cp server:/home/captura/app/coverage-report ./coverage-report - name: Upload Coverage Report. diff --git a/src/captura/controllers/access.py b/src/captura/controllers/access.py index 1affab8..bbd4b34 100644 --- a/src/captura/controllers/access.py +++ b/src/captura/controllers/access.py @@ -488,7 +488,7 @@ def check_one(collection: Collection) -> Collection: match self.method: case H.GET if allow_public: - if not collection.public and collection.id_user != token_user.id: + if not collection.public and collection.uuid_user != token_user.uuid: raise ErrAccessCollection.httpexception( "_msg_private", 403, @@ -497,7 +497,7 @@ def check_one(collection: Collection) -> Collection: ) return collection case H.GET | H.POST | H.DELETE | H.PUT | H.PATCH: - if token_user.id != collection.id_user: + if token_user.uuid != collection.uuid_user: raise ErrAccessCollection.httpexception( "_msg_modify", 403, diff --git a/src/captura/controllers/create.py b/src/captura/controllers/create.py index 84c46fb..4cf3a69 100644 --- a/src/captura/controllers/create.py +++ b/src/captura/controllers/create.py @@ -332,14 +332,14 @@ def create_assignment( data: Data[ResolvedAssignmentDocument] | Data[ResolvedAssignmentCollection], target: Collection | Document, ) -> Assignment: - id_source_name = f"id_{data.data.kind_source.name}" - id_target_name = f"id_{data.data.kind_target.name}" - id_source_value = data.data.source.id # type: ignore + uuid_source_name = f"uuid_{data.data.kind_source.name}" + uuid_target_name = f"uuid_{data.data.kind_target.name}" + uuid_source_value = data.data.source.uuid # type: ignore kwargs = { "uuid": secrets.token_urlsafe(8), - id_source_name: id_source_value, - id_target_name: target.id, + uuid_source_name: uuid_source_value, + uuid_target_name: target.uuid, } return Assignment( **kwargs, @@ -414,17 +414,17 @@ def create_grant( case bad: raise ValueError(f"Invalid source `{bad}`.") - id_source_name = f"id_{data.data.kind_source.name}" - id_target_name = f"id_{data.data.kind_target.name}" - id_source_value = data.data.source.id # type: ignore + uuid_source_name = f"uuid_{data.data.kind_source.name}" + uuid_target_name = f"uuid_{data.data.kind_target.name}" + uuid_source_value = data.data.source.uuid # type: ignore kwargs = { "uuid": secrets.token_urlsafe(8), "uuid_parent": grant_parent_uuid, "pending_from": pending_from, "pending": True, - id_source_name: id_source_value, - id_target_name: target.id, + uuid_source_name: uuid_source_value, + uuid_target_name: target.uuid, } return Grant(**kwargs, **self.create_data.model_dump()) @@ -512,8 +512,8 @@ def document( data.data.token_user_grants = { user.uuid: ( Grant( - id_user=user.id, - id_document=document.id, + uuid_user=user.uuid, + uuid_document=document.uuid, level=Level.own, pending=False, pending_from=PendingFrom.created, @@ -748,7 +748,7 @@ def collection(self, data: Data[ResolvedCollection]) -> Data[ResolvedCollection] session, param.uuid_user, ) - collection.id_user = user.id + collection.uuid_user = user.uuid data.event.children.append( Event( **self.event_common, diff --git a/src/captura/controllers/delete.py b/src/captura/controllers/delete.py index e3e3622..f1b91aa 100644 --- a/src/captura/controllers/delete.py +++ b/src/captura/controllers/delete.py @@ -239,8 +239,8 @@ def split_assocs( model_assoc.uuid.in_(data.data.uuid_assoc), and_( model_target.uuid.in_(data.data.uuid_target), - getattr(model_assoc, "id_" + data.data.kind_source.name) - == data.data.source.id, + getattr(model_assoc, "uuid_" + data.data.kind_source.name) + == data.data.source.uuid, ), ) ) @@ -474,7 +474,7 @@ def _collection( .join(Document) .where( Document.uuid.in_(uuids(documents)), # type: ignore[type-var] - Assignment.id_collection == collection.id, + Assignment.uuid_collection == collection.uuid, ) ) assignments = { @@ -591,7 +591,7 @@ def _document( select(Assignment) .join(Collection) .where( - Assignment.id_document == document.id, + Assignment.uuid_document == document.uuid, Collection.uuid.in_(uuid_collections), ) ) diff --git a/src/captura/models.py b/src/captura/models.py index 4be8a90..301a9fb 100644 --- a/src/captura/models.py +++ b/src/captura/models.py @@ -109,8 +109,15 @@ index=True, unique=True, ) +_uuid_primary = mapped_column( + String(36), + default=lambda: str(uuid.uuid4()), + index=True, + primary_key=True, +) MappedColumnUUID = Annotated[str, _uuid] MappedColumnUUIDUnique = Annotated[str, _uuid_unique] +MappedColumnUUIDPrimary = Annotated[str, _uuid_primary] MappedColumnDeleted = Annotated[bool, mapped_column(default=False)] @@ -125,7 +132,7 @@ class KindSelect(str, enum.Enum): class Base(DeclarativeBase): - uuid: Mapped[MappedColumnUUIDUnique] + uuid: Mapped[MappedColumnUUIDPrimary] deleted: Mapped[MappedColumnDeleted] __kind__: ClassVar[KindObject] @@ -454,11 +461,10 @@ class Event(Base): __tablename__ = "events" __kind__ = KindObject.event - timestamp: Mapped[int] = mapped_column( + timestamp: Mapped[str] = mapped_column( default=(_now := lambda: datetime.timestamp(datetime.now())), ) - # id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) uuid: Mapped[MappedColumnUUIDUnique] = mapped_column(primary_key=True) uuid_parent: Mapped[str] = mapped_column( ForeignKey("events.uuid", ondelete="CASCADE"), @@ -700,42 +706,22 @@ class AssocCollectionDocument(Base): # NOTE: Since this object supports soft deletion (for the deletion grace # period that will later be implemented) deleted is included. # deleted: Mapped[MappedColumnDeleted] - id_document: Mapped[int] = mapped_column( + uuid_document: Mapped[str] = mapped_column( ForeignKey( - "documents.id", + "documents.uuid", ondelete="CASCADE", ), primary_key=True, ) - id_collection: Mapped[int] = mapped_column( + uuid_collection: Mapped[str] = mapped_column( ForeignKey( - "collections.id", + "collections.uuid", ondelete="CASCADE", ), primary_key=True, ) - @property - def uuid_document(self) -> str: - session = self.get_session() - res = session.execute( - select(Document.uuid).where(Document.id == self.id_document) - ).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res - - @property - def uuid_collection(self) -> str: - session = self.get_session() - res = session.execute( - select(Collection.uuid).where(Collection.id == self.id_collection) - ).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res - @classmethod def resolve_target_kind( cls, @@ -809,16 +795,16 @@ class AssocUserDocument(Base): cascade="all, delete", ) - id_user: Mapped[int] = mapped_column( + uuid_user: Mapped[str] = mapped_column( ForeignKey( - "users.id", + "users.uuid", ondelete="CASCADE", ), key="a", ) - id_document: Mapped[int] = mapped_column( + uuid_document: Mapped[str] = mapped_column( ForeignKey( - "documents.id", + "documents.uuid", ondelete="CASCADE", ), key="b", @@ -831,33 +817,6 @@ class AssocUserDocument(Base): __table_args__ = (UniqueConstraint("a", "b", name="_grant_vector"),) - @property - def uuid_document(self) -> str: - session = self.get_session() - res = session.execute( - select(Document.uuid).where(Document.id == self.id_document) - ).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res - - @property - def uuid_user(self) -> str: - session = self.get_session() - res = session.execute(select(User.uuid).where(User.id == self.id_user)).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res - - @property - def uuid_user_granter(self) -> str: - session = self.get_session() - res = session.execute( - select(User.uuid).where(User.id == self.id_user_granter) # type: ignore - ).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res @classmethod def resolve_from_target( @@ -912,11 +871,6 @@ class User(SearchableTableMixins, Base): __tablename__ = "users" __kind__ = KindObject.user - id: Mapped[int] = mapped_column( - primary_key=True, - autoincrement=True, - ) - # NOTE: subject should be a sha256 of a token subject. For test tokens, # the subject should be the sha sum of their uuid. subject: Mapped[str | None] = mapped_column(String(64), unique=True, nullable=True) @@ -936,7 +890,7 @@ class User(SearchableTableMixins, Base): collections: Mapped[List["Collection"]] = relationship( cascade="all, delete", back_populates="user", - primaryjoin="User.id==Collection.id_user", + primaryjoin="User.uuid==Collection.uuid_user", passive_deletes=True, ) @@ -988,16 +942,16 @@ def q_conds_grants( ): cond = list() if n_owners is None: - cond.append(AssocUserDocument.id_user == self.id) + cond.append(AssocUserDocument.uuid_user == self.uuid) if exclude_deleted: cond.append(Grant.deleted == false()) cond.append(Document.deleted == false()) if document_uuids is not None: - q_ids = select(Document.id) + q_ids = select(Document.uuid) q_ids = q_ids.where(Document.uuid.in_(document_uuids)) - cond.append(AssocUserDocument.id_document.in_(q_ids)) + cond.append(AssocUserDocument.uuid_document.in_(q_ids)) if level is not None: level = Level.resolve(level) @@ -1035,18 +989,6 @@ def q_select_grants( exclude_pending: bool = True, pending_from: PendingFrom | None = None, ) -> Select: - # NOTE: Attempting to make roughly the following query: - # - # .. code:: - # - # SELECT users.uuid, - # documents.uuid, - # _assocs_user_documents.level - # FROM users - # JOIN _assocs_user_documents - # ON _assocs_user_documents.id_user=users.id - # JOIN documents - # ON _assocs_user_documents.id_document = documents.id; q = select(Grant).select_from(User).join(AssocUserDocument).join(Document) conds = self.q_conds_grants( document_uuids, @@ -1101,16 +1043,16 @@ def q_select_documents( raise ValueError(msg.format(kind_select)) aq = aliased(selected, q.subquery()) - q = select(aq).join(Grant).where(Grant.id_user == self.id) + q = select(aq).join(Grant).where(Grant.uuid_user == self.uuid) - cond_count = func.count(Grant.id_user) + cond_count = func.count(Grant.uuid_user) cond_having: ColumnElement[bool] = ( (cond_count < n_owners) if not n_owners_levelsets else (cond_count == n_owners) ) - q = q.group_by(Document.id).having(cond_having) + q = q.group_by(Document.uuid).having(cond_having) return q @@ -1142,7 +1084,7 @@ def q_conds_collections( uuid_collection: Set[str] | None = None, exclude_deleted: bool = True, ): - conds = and_(Collection.id_user == User.id) + conds = and_(Collection.uuid_user == User.uuid) if uuid_collection is not None: conds = and_(conds, Collection.uuid.in_(uuid_collection)) if exclude_deleted: @@ -1278,11 +1220,10 @@ class Collection(SearchableTableMixins, Base): __tablename__ = "collections" __kind__ = KindObject.collection - id_user: Mapped[int] = mapped_column( - ForeignKey("users.id", ondelete="CASCADE"), + uuid_user: Mapped[str] = mapped_column( + ForeignKey("users.uuid", ondelete="CASCADE"), nullable=False, ) - id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(fields.LENGTH_NAME)) description: Mapped[str] = mapped_column( String(fields.LENGTH_DESCRIPTION), @@ -1293,7 +1234,7 @@ class Collection(SearchableTableMixins, Base): ) user: Mapped[User] = relationship( - primaryjoin="User.id==Collection.id_user", + primaryjoin="User.uuid==Collection.uuid_user", back_populates="collections", ) @@ -1305,15 +1246,6 @@ class Collection(SearchableTableMixins, Base): # cascade="all, delete", ) - @property - def uuid_user(self) -> str: - session = self.get_session() - q = select(User.uuid).where(User.id == self.id_user) - res = session.execute(q).scalar() - if res is None: - raise ValueError("Inconcievable!") - return res - def q_conds_assignment( self, document_uuids: Set[str] | None = None, @@ -1321,12 +1253,11 @@ def q_conds_assignment( ) -> ColumnElement[bool]: # NOTE: To add the conditions for document select (like level) use # `q_conds_assoc`. - cond = and_(AssocCollectionDocument.id_collection == self.id) + cond = and_(AssocCollectionDocument.uuid_collection == self.uuid) if exclude_deleted: cond = and_(cond, AssocCollectionDocument.deleted == false()) if document_uuids is not None: - document_ids = Document.q_select_ids(document_uuids) - cond = and_(cond, AssocCollectionDocument.id_document.in_(document_ids)) + cond = and_(cond, AssocCollectionDocument.uuid_document.in_(document_uuids)) # cond = and_(cond, self.q_conds(document_uuids, exclude_deleted)) return cond @@ -1380,7 +1311,6 @@ class Document(SearchableTableMixins, Base): __tablename__ = "documents" __kind__ = KindObject.document - id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(fields.LENGTH_NAME)) description: Mapped[str] = mapped_column( String(fields.LENGTH_DESCRIPTION), @@ -1421,7 +1351,7 @@ def q_conds_grants( :param exclude_pending: Specify if all grants should be returned regardless of their pending status. """ - cond = AssocUserDocument.id_document == self.id + cond = AssocUserDocument.uuid_document == self.uuid if exclude_deleted: cond = and_( cond, @@ -1431,8 +1361,8 @@ def q_conds_grants( if user_uuids is not None: cond = and_( cond, - AssocUserDocument.id_user.in_( - select(User.id).where(User.uuid.in_(user_uuids)) + AssocUserDocument.uuid_user.in_( + select(User.uuid).where(User.uuid.in_(user_uuids)) ), ) if level is not None: @@ -1515,15 +1445,14 @@ def q_conds_assignment( ) -> ColumnElement[bool]: # NOTE: To add the conditions for document select (like level) use # `q_conds_assoc`. - cond = and_(AssocCollectionDocument.id_document == self.id) + cond = and_(AssocCollectionDocument.uuid_document == self.uuid) if exclude_deleted: cond = and_( cond, AssocCollectionDocument.deleted == false(), ) if collection_uuids is not None: - collection_ids = Collection.q_select_ids(collection_uuids) - cond = and_(cond, AssocCollectionDocument.id_collection.in_(collection_ids)) + cond = and_(cond, AssocCollectionDocument.uuid_collection.in_(collection_uuids)) return cond diff --git a/src/captura/schemas.py b/src/captura/schemas.py index a15bae2..547ee99 100644 --- a/src/captura/schemas.py +++ b/src/captura/schemas.py @@ -201,7 +201,6 @@ class BaseSecondarySchema(BaseSchema): ... class BasePrimaryTableExtraSchema(BaseSchema): - id: fields.FieldID deleted: fields.FieldDeleted @@ -450,9 +449,6 @@ def enum_as_name(item: enum.Enum): # type: ignore # Metadata uuid_parent: Optional[fields.FieldUUID] = None - uuid_user_granter: Optional[fields.FieldUUID] = ( - None # should it reeally be optional - ) class GrantExtraSchema(GrantSchema): diff --git a/src/captura/util.py b/src/captura/util.py index 37e2231..246dc08 100644 --- a/src/captura/util.py +++ b/src/captura/util.py @@ -46,6 +46,11 @@ def tests(cls, v: str) -> str: def test_assets(cls, v: str) -> str: return path.join(PATH_TESTS_ASSETS, v) + @classmethod + def simulatus_assets(cls, v: str) -> str: + o = path.join(PATH_SIMULATUS_ASSETS, v) + return o + @classmethod def docker(cls, v: str) -> str: return path.join(PATH_DOCKER, v) @@ -60,8 +65,10 @@ def plugins(cls, v: str) -> str: PATH_BASE: str = path.realpath(path.join(path.dirname(__file__), "..", "..")) -PATH_APP: str = path.join(PATH_BASE, "src/app") -PATH_CLIENT: str = path.join(PATH_BASE, "src/client") +PATH_APP: str = path.join(PATH_BASE, "src/captura") +PATH_SIMULATUS = path.join(PATH_BASE, "src/simulatus") +PATH_SIMULATUS_ASSETS = path.join(PATH_SIMULATUS, "assets") +PATH_CLIENT: str = path.join(PATH_BASE, "src/legere") PATH_CONFIG: str = path.join(PATH_BASE, "configs") PATH_DOCKER: str = path.join(PATH_BASE, "docker") PATH_PLUGINS: str = path.join(PATH_BASE, "plugins") @@ -99,6 +106,10 @@ def from_env(v: str, default: str | None = None, *, prefix: bool = True): "CONFIG_CLIENT", Path.config("client.yaml"), ) +PATH_CONFIG_DUMMY = from_env( + "CONFIG_DUMMY", + Path.config("dummy.yaml"), +) PATH_CONFIG_TEST_APP = from_env( "CONFIG_APP_TEST", Path.config("app.test.yaml"), diff --git a/src/captura/views/assignments.py b/src/captura/views/assignments.py index 93ef73e..0e21fb3 100644 --- a/src/captura/views/assignments.py +++ b/src/captura/views/assignments.py @@ -163,7 +163,7 @@ def get_assignments_document( select(Collection) .join(Assignment) .where( - Assignment.id_document == document.id, + Assignment.uuid_document == document.uuid, Assignment.deleted == false(), Collection.deleted == false(), ) @@ -288,7 +288,7 @@ def get_assignments_collection( .where( Document.deleted == false(), Assignment.deleted == false(), - Assignment.id_collection == collection.id, + Assignment.uuid_collection == collection.uuid, ) ) if uuid_document is not None: diff --git a/src/captura/views/documents.py b/src/captura/views/documents.py index 5d28078..0394fcb 100644 --- a/src/captura/views/documents.py +++ b/src/captura/views/documents.py @@ -105,7 +105,7 @@ def post_document( (document,) = data_create.data.documents grant, *_ = data_create.data.token_user_grants.values() - grant.id_document = document.id + grant.uuid_document = document.uuid create.session.add(grant) create.session.commit() diff --git a/src/legere/__init__.py b/src/legere/__init__.py index 11710e8..c68cce4 100644 --- a/src/legere/__init__.py +++ b/src/legere/__init__.py @@ -442,7 +442,7 @@ def db(cls, _context: typer.Context): console = context.console_handler.console client = docker.DockerClient() # type: ignore - if (container := client.containers.get("captura-db")) is None: + if (container := client.containers.get("captura-db-1")) is None: console.print("[red]Docker compose project is not running.") raise typer.Exit(1) diff --git a/src/simulatus/__init__.py b/src/simulatus/__init__.py index a203e09..b4efb02 100644 --- a/src/simulatus/__init__.py +++ b/src/simulatus/__init__.py @@ -39,6 +39,7 @@ # --------------------------------------------------------------------------- # from captura import util from captura.auth import Auth, Token, TokenPermissionTier +from captura.config import Config from captura.controllers.access import Access from captura.controllers.base import ( BaseResolved, @@ -111,7 +112,8 @@ class BaseDummyProvider: } client_config_cls: Type - config: ConfigSimulatus + config: Config + config_dummy: ConfigSimulatus dummy: DummyConfig session: Session user: User @@ -119,7 +121,8 @@ class BaseDummyProvider: def __init__( self, - config: ConfigSimulatus, + config: Config, + config_dummy: ConfigSimulatus, session: Session, *, user: User, @@ -128,7 +131,8 @@ def __init__( ): self.client_config_cls = client_config_cls or ClientConfig self.config = config - self.dummy = config.dummy + self.config_dummy = config_dummy + self.dummy = config_dummy.dummy self.auth = auth if auth is not None else Auth.forPyTest(config) self.session = session self.user = user @@ -162,8 +166,8 @@ def mk_assignments( logger.debug("Making assignments...") assignments: Tuple[Assignment, ...] = tuple( Assignment( - id_document=document.id, - id_collection=collection.id, + uuid_document=document.uuid, + uuid_collection=collection.uuid, deleted=False, ) for collection in collections @@ -188,15 +192,15 @@ def mk_grants( # statement be emitted in addition to these queries. # # TLDR: Do not use ``session.merge``, just use ``DELETE`` or use - # options to avoid causing duplicate ``(id_user, id_document)`` + # options to avoid causing duplicate ``(uuid_user, uuid_document)`` # keys. if not exclude_grants_create: logger.debug("Making grants for documents created by self.") grants_created = tuple( Grant( level=Level.own, - id_user=self.user.id, - id_document=document.id, + uuid_user=self.user.uuid, + uuid_document=document.uuid, deleted=False, pending=False, pending_from=PendingFrom.created, @@ -212,17 +216,17 @@ def mk_grants( logger.debug("Making grants for `%s` on documents created by others.") a, b = dummies.grants.minimum_self, dummies.grants.maximum_self q_ids_has_grants = ( - select(Document.id) + select(Document.uuid) .join(Grant) - .group_by(Grant.id_document) - .having(func.count(Grant.id_user) > 0) - .where(Grant.id_user == self.user.id) + .group_by(Grant.uuid_document) + .having(func.count(Grant.uuid_user) > 0) + .where(Grant.uuid_user == self.user.uuid) ) q_grants_share = ( select(Grant) .join(Document) .where( - Document.id.not_in(q_ids_has_grants), + Document.uuid.not_in(q_ids_has_grants), Grant.pending_from == PendingFrom.created, ) .limit(b) @@ -240,8 +244,8 @@ def mk_grants( grants_self = tuple( Grant( uuid=secrets.token_urlsafe(8), - id_user=self.user.id, - id_document=grant.id_document, + uuid_user=self.user.uuid, + uuid_document=grant.uuid_document, uuid_parent=grant.uuid, **kwargs, ) @@ -257,8 +261,8 @@ def mk_grants( logger.debug("Making grants for others on documents created `%s`.") q_ids_users = ( - select(User.id) - .where(User.id != self.user.id) + select(User.uuid) + .where(User.uuid != self.user.uuid) .limit( randint( dummies.grants.minimum_other, @@ -266,7 +270,7 @@ def mk_grants( ) ) ) - id_users_other = set(self.session.scalars(q_ids_users)) + uuid_users_other = set(self.session.scalars(q_ids_users)) if not grants_created: grants_source = tuple(map(self.get_document_grant, documents)) @@ -278,15 +282,15 @@ def mk_grants( Grant( uuid=secrets.token_urlsafe(8), level=choice(list(Level)), - id_user=id_user, - id_document=grant.id_document, + uuid_user=uuid_user, + uuid_document=grant.uuid_document, uuid_parent=grant.uuid, deleted=bool(randint(0, 1)), pending=bool(randint(0, 1)), pending_from=choice((PendingFrom.grantee, PendingFrom.granter)), ) for grant in grants_source - for id_user in id_users_other + for uuid_user in uuid_users_other ) return grants_created + grants_self + grants_other @@ -392,7 +396,7 @@ def randomize_primary( def randomize_grants(self): logger.debug("Randomizing grants for `%s`.", self.user.uuid) q_uuids = select(Grant.uuid).where( - Grant.id_user == self.user.id, Grant.pending_from != PendingFrom.created + Grant.uuid_user == self.user.uuid, Grant.pending_from != PendingFrom.created ) uuids = self.session.scalars(q_uuids) @@ -479,7 +483,7 @@ def get_users( ) -> Tuple[User, ...]: callback = None if other: - callback = lambda q: q.where(User.id != self.user.id) # noqa: E731 + callback = lambda q: q.where(User.uuid != self.user.uuid) # noqa: E731 return self.get_primary( User, @@ -526,12 +530,12 @@ def callback(q): q = q.join(Grant).where(*conds) else: q_has_grants = ( - select(Grant.id_document) - .where(Grant.id_user == self.user.id) - .group_by(Grant.id_document) + select(Grant.uuid_document) + .where(Grant.uuid_user == self.user.uuid) + .group_by(Grant.uuid_document) .having(func.count(Grant.uuid) > 0) ) - q = q.where(Document.id.not_in(q_has_grants)) + q = q.where(Document.uuid.not_in(q_has_grants)) return q @@ -555,8 +559,8 @@ def get_documents_retry_callback(): self.session.add( Grant( uuid=secrets.token_urlsafe(8), - id_document=document.id, - id_user=self.user.id, + uuid_document=document.uuid, + uuid_user=self.user.uuid, level=level or Level.own, pending_from=PendingFrom.created, pending=kwargs.get("pending", False), @@ -570,8 +574,8 @@ def get_documents_retry_callback(): grants = tuple( Grant( uuid=secrets.token_urlsafe(8), - id_document=document.id, - id_user=self.user.id, + uuid_document=document.uuid, + uuid_user=self.user.uuid, level=level or Level.own, pending_from=PendingFrom.created, pending=kwargs.get("pending", False), @@ -601,7 +605,7 @@ def get_documents_data_callback( q_grants = ( select(Grant) .join(Document) - .where(Document.uuid.in_(uuid_documents), Grant.id_user == self.user.id) + .where(Document.uuid.in_(uuid_documents), Grant.uuid_user == self.user.uuid) ) data_raw["grants"] = { gg.uuid_document: gg for gg in self.session.scalars(q_grants) @@ -633,7 +637,7 @@ def get_collections_retry_callback(self): session = self.session logger.warning("Calling `get_collections_retry_callback`.") - collection = Mk.collection(id_user=self.user.id) + collection = Mk.collection(uuid_user=self.user.uuid) session.add(collection) session.commit() session.refresh(collection) @@ -658,22 +662,22 @@ def get_collections( def callback(q): match other: case True: - cond_other = Collection.id_user != self.user.id + cond_other = Collection.uuid_user != self.user.uuid case False: - cond_other = Collection.id_user == self.user.id + cond_other = Collection.uuid_user == self.user.uuid case _: cond_other = true() if order_by_document_count: q_ids = ( - select(Collection.id.label("id_collection")) + select(Collection.uuid.label("uuid_collection")) .join(Assignment) - .group_by(Collection.id) - .having(func.count(Assignment.id_document) > 0) + .group_by(Collection.uuid) + .having(func.count(Assignment.uuid_document) > 0) .where(cond_other) - .order_by(desc(func.count(Assignment.id_document))) + .order_by(desc(func.count(Assignment.uuid_document))) ) - q = q.where(Collection.id.in_(q_ids)) + q = q.where(Collection.uuid.in_(q_ids)) return q @@ -699,7 +703,7 @@ def get_collections_data( def get_document_grant(self, document: Document) -> Grant: grant = self.session.scalar( select(Grant).where( - Grant.id_document == document.id, Grant.id_user == self.user.id + Grant.uuid_document == document.uuid, Grant.uuid_user == self.user.uuid ) ) if grant is None: @@ -912,14 +916,14 @@ def get_data_secondary( # NOTE: Get assocs. Assocs are always labeled by their model_assoc = resolve_model(Resolved.kind_assoc) # type: ignore - id_source_name = f"id_{Resolved._attr_name_source}" + uuid_source_name = f"uuid_{Resolved._attr_name_source}" uuid_target_name = f"uuid_{Resolved.kind_target.name}" q = ( select(model_assoc) .join(model_target) .where( - getattr(model_assoc, id_source_name) == source.id, + getattr(model_assoc, uuid_source_name) == source.uuid, model_target.uuid.in_(uuid_target := uuids(targets)), ) ) @@ -1047,7 +1051,8 @@ def __new__(cls, name, bases, namespace): if (dummies_file := namespace.get("dummies_file")) is None: kind = KindObject._value2member_map_[M.__tablename__] - dummies_file = util.Path.test_assets(f"{kind.name}.yaml") + dummies_file = util.Path.simulatus_assets(f"{kind.name}.yaml") + namespace["dummies_file"] = dummies_file T = super().__new__(cls, name, bases, namespace) @@ -1172,7 +1177,8 @@ def q_select_suitable(self): def __init__( self, - config: ConfigSimulatus, + config: Config, + config_dummy: ConfigSimulatus, session: Session, *, auth: Auth | None = None, @@ -1180,7 +1186,8 @@ def __init__( client_config_cls: Type | None = None, ): self.config = config - self.dummy = config.dummy + self.config_dummy = config_dummy + self.dummy = config_dummy.dummy self.auth = auth if auth is not None else Auth.forPyTest(config) self.session = session @@ -1258,7 +1265,8 @@ def info_is_tainted(self, maximum_use_count: int | None = None) -> bool | None: class DummyHandler: dummy: DummyConfig - config: ConfigSimulatus + config: Config + config_dummy: ConfigSimulatus sessionmaker: sqa_sessionmaker[Session] auth: Auth # user_uuids: List[str] @@ -1266,13 +1274,16 @@ class DummyHandler: def __init__( self, sessionmaker: sqa_sessionmaker, - config: ConfigSimulatus, + config: Config, + config_dummy: ConfigSimulatus, # user_uuids: List[str], *, auth: Auth | None = None, ): - self.dummy = config.dummy + self.config_dummy = config_dummy + self.dummy = self.config_dummy.dummy self.config = config + self.sessionmaker = sessionmaker self.auth = auth or Auth.forPyTest(config) # self.user_uuids = user_uuids @@ -1304,7 +1315,7 @@ def q_select( ): return ( select( - User.id, + User.uuid, User.uuid, func.JSON_VALUE(User.content, "$.dummy.used_by").label("used_by"), func.JSON_LENGTH(User.content, "$.dummy.used_by").label( @@ -1359,7 +1370,7 @@ def restore( ) -> Self: with self.sessionmaker() as session: logger.debug("Getting current user count.") - uuids_existing = list(session.scalars(select(User.id, User.uuid))) + uuids_existing = list(session.scalars(select(User.uuid, User.uuid))) n_users = len(uuids_existing) assert n_users is not None @@ -1372,8 +1383,9 @@ def restore( logger.info("Generating `%s` dummies.", n_generate) for count in range(n_generate): dd = DummyProvider( - self.config, - session, + config=self.config, + config_dummy=self.config_dummy, + session=session, auth=self.auth, use_existing=False, ) diff --git a/src/simulatus/__main__.py b/src/simulatus/__main__.py index ee13a5b..efbe37b 100644 --- a/src/simulatus/__main__.py +++ b/src/simulatus/__main__.py @@ -18,6 +18,7 @@ # --------------------------------------------------------------------------- # from captura import User +from captura.config import Config from captura.fields import KindObject from captura.models import Base, Document from captura.schemas import TimespanLimitParams, UserExtraSchema, mwargs @@ -85,21 +86,22 @@ class ContextDataDummy(BaseModel): # NOTE: Global options for flags do not exist. Instead, create a manifest. quiet: bool = True - config: ConfigSimulatus + config: Config + config_dummy: ConfigSimulatus config_output: OutputConfig - def register_manifest(self, manifest_path: str | None) -> DummyConfig | None: + def register_manifest(self, manifest_path: str | None) -> ConfigSimulatus | None: if manifest_path is None: return None - manifest = DummyConfig.load(manifest_path) - self.config.dummy = manifest + manifest = ConfigSimulatus(dummy=DummyConfig.load(manifest_path)) + self.config_dummy = manifest return manifest def preview_manifest(self): data = HandlerData( - data=self.config.dummy.model_dump(), + data=self.config_dummy.model_dump(), output_config=self.config_output, ) data.print() @@ -109,7 +111,7 @@ def dummy_handler(self) -> DummyHandler: engine = self.config.engine() sm = _sessionmaker(engine) - return DummyHandler(sm, self.config) + return DummyHandler(sm, self.config, self.config_dummy) @classmethod def for_typer( @@ -117,17 +119,31 @@ def for_typer( context: typer.Context, quiet: Annotated[bool, typer.Option("--quiet/--loud")] = True, path_config: Annotated[Optional[str], typer.Option("--config")] = None, + path_config_dummy: Annotated[Optional[str], typer.Option("--config")] = None, ) -> None: + if path_config_dummy is None: + config_dummy = mwargs(ConfigSimulatus) + else: + with open(path_config_dummy, "r") as file: + config_dummy = ConfigSimulatus.model_validate( + yaml.safe_load(file), + ) + if path_config is None: - config = mwargs(ConfigSimulatus) + config = mwargs(Config) else: with open(path_config, "r") as file: - config = ConfigSimulatus.model_validate( + config = Config.model_validate( yaml.safe_load(file), ) config_output = mwargs(OutputConfig, output=Output.yaml) - context.obj = cls(config=config, quiet=quiet, config_output=config_output) + context.obj = cls( + config=config, + config_dummy=config_dummy, + quiet=quiet, + config_output=config_output, + ) # --------------------------------------------------------------------------- # @@ -302,8 +318,9 @@ def user( raise typer.Exit(1) else: dummy_provider = DummyProvider( - context.dummy_handler.config, - session, + config=context.config, + config_dummy=context.dummy_handler.config_dummy, + session=session, use_existing=False, ) user = dummy_provider.user @@ -354,7 +371,12 @@ def new(cls, _context: typer.Context, count: FlagCount = 1): handler = context.dummy_handler with handler.sessionmaker() as session: for _ in range(count): - DummyProvider(handler.config, session, use_existing=False) + DummyProvider( + config=handler.config, + config_dummy=handler.config_dummy, + session=session, + use_existing=False, + ) @classmethod def get(cls, _context: typer.Context, count: FlagCount = 1): @@ -367,7 +389,12 @@ def get(cls, _context: typer.Context, count: FlagCount = 1): q_existing = select(User).order_by(func.random()).limit(count) existing = session.scalars(q_existing) for ee in existing: - DummyProvider(handler.config, session, use_existing=ee) + DummyProvider( + config=handler.config, + config_dummy=handler.config_dummy, + session=session, + use_existing=ee, + ) @classmethod def search( @@ -408,8 +435,9 @@ def taint( users = tuple(session.scalars(q)) for user in users: DummyProvider( - context.config, - session, + config=context.config, + config_dummy=context.config_dummy, + session=session, use_existing=user, ).info_mark_tainted() @@ -460,7 +488,7 @@ def dispose( CONSOLE.print("[red]Maximum uses too small to prune.") raise typer.Exit() - context.config.dummy.users.maximum_uses = prune + context.config_dummy.dummy.users.maximum_uses = prune if preview: context.preview_manifest() return diff --git a/tests/assets/assignment.yaml b/src/simulatus/assets/assignment.yaml similarity index 50% rename from tests/assets/assignment.yaml rename to src/simulatus/assets/assignment.yaml index 5fdac82..dc65759 100644 --- a/tests/assets/assignment.yaml +++ b/src/simulatus/assets/assignment.yaml @@ -2,35 +2,35 @@ # Collection 5 - uuid: foobar--eee - id_collection: 4 - id_document: 7 + uuid_collection: eee-eee-eee + uuid_document: foobar-spam # --------------------------------------------------------------------------- # # Collection 6 - uuid: ex--foo-ool - id_document: 4 - id_collection: 5 + uuid_document: ex-parrot + uuid_collection: foo-ooo-ool - uuid: petshopfool - id_document: 6 - id_collection: 5 + uuid_document: petshoppe-- + uuid_collection: foo-ooo-ool - uuid: barspamfool - id_document: 7 - id_collection: 5 + uuid_document: foobar-spam + uuid_collection: foo-ooo-ool - uuid: draculafool - id_document: 8 - id_collection: 5 + uuid_document: draculaflow + uuid_collection: foo-ooo-ool # --------------------------------------------------------------------------- # # Document 5 - uuid: aaa-aaa-eee - id_document: 5 - id_collection: 4 + uuid_document: aaa-aaa-aaa + uuid_collection: eee-eee-eee - uuid: aaa-foo-ool - id_document: 5 - id_collection: 5 + uuid_document: aaa-aaa-aaa + uuid_collection: foo-ooo-ool diff --git a/tests/assets/collection.yaml b/src/simulatus/assets/collection.yaml similarity index 67% rename from tests/assets/collection.yaml rename to src/simulatus/assets/collection.yaml index 3505f07..992ee35 100644 --- a/tests/assets/collection.yaml +++ b/src/simulatus/assets/collection.yaml @@ -1,34 +1,32 @@ -- id_user: 1 - id: 1 +- uuid_user: 99d-99d-99d + uuid: collection1 name: foofoo description: The foofoo collection -- id_user: 1 - id: 2 +- uuid_user: 99d-99d-99d + uuid: collection2 name: Bar. description: The bar collection. -- id_user: 1 - id: 3 +- uuid_user: 99d-99d-99d + uuid: collection3 name: Spam and Etc. description: A collection about processed meat products. -- id_user: 2 - id: 4 +- uuid_user: 000-000-000 name: Chicharon. description: A collection about New Mexican food. uuid: 'eee-eee-eee' deleted: False -- id_user: 2 - id: 5 +- uuid_user: 000-000-000 name: Adovada and Chicharon. description: A collection about New Mexican food. uuid: 'foo-ooo-ool' deleted: False -- id_user: 2 - id: 6 +- uuid_user: 000-000-000 + uuid: 'ersomething' name: Mole and Tacos. description: A collection about Mexican food. diff --git a/tests/assets/document.yaml b/src/simulatus/assets/document.yaml similarity index 99% rename from tests/assets/document.yaml rename to src/simulatus/assets/document.yaml index 16b23f3..08bd24e 100644 --- a/tests/assets/document.yaml +++ b/src/simulatus/assets/document.yaml @@ -1,7 +1,6 @@ --- - uuid: ---0---0--- name: Lorm ipsum - id: 1 description: Lorem ipsum 1 content: text_format: md @@ -19,7 +18,6 @@ - uuid: -0---0---0- name: Lorm ipsum 2 - id: 2 description: Lorem ipsum 2 content: text_format: rst @@ -38,7 +36,7 @@ - name: Lorm ipsum 3 - id: 3 + uuid: lormipsum3 description: Lorem ipsum 3 content: text_format: md @@ -49,7 +47,6 @@ - uuid: ex-parrot name: Lorm ipsum 4 - id: 4 description: Lorem ipsum 4 content: text_format: md @@ -62,7 +59,6 @@ # NOTE: This document is important in tests and should be owned by user with uuid 00000000 - name: Lorem Ipsum 5 uuid: aaa-aaa-aaa - id: 5 description: Lorem ipsum 5 content: text_format: rst @@ -76,7 +72,6 @@ - uuid: petshoppe-- name: Lorem Ipsum 6 - id: 6 description: Lorem ipsum 6 content: text_format: md @@ -90,7 +85,6 @@ - uuid: foobar-spam name: Foo Document - id: 7 description: A document, foo. content: text_format: md @@ -112,7 +106,6 @@ - uuid: draculaflow name: Objectively a Banger - id: 8 description: A masterpiece. content: text_format: md diff --git a/tests/assets/event.yaml b/src/simulatus/assets/event.yaml similarity index 100% rename from tests/assets/event.yaml rename to src/simulatus/assets/event.yaml diff --git a/tests/assets/grant.yaml b/src/simulatus/assets/grant.yaml similarity index 73% rename from tests/assets/grant.yaml rename to src/simulatus/assets/grant.yaml index d23f356..c0c54cf 100644 --- a/tests/assets/grant.yaml +++ b/src/simulatus/assets/grant.yaml @@ -2,16 +2,16 @@ # Document 1 (---0---0---) - uuid: 1-111-111-1 - id_user: 1 - id_document: 1 + uuid_user: 99d-99d-99d + uuid_document: ---0---0--- level: own pending: False pending_from: created - uuid: a-aaa-aaa-a uuid_parent: 1-111-111-1 - id_user: 2 - id_document: 1 + uuid_user: 000-000-000 + uuid_document: ---0---0--- level: view pending: False pending_from: granter @@ -22,16 +22,16 @@ # NOTE: User 000-000-000 should have no grant! - uuid: 2-222-222-2 - id_user: 1 - id_document: 2 + uuid_user: 99d-99d-99d + uuid_document: -0---0---0- level: own pending: False pending_from: created # - uuid: b-bbb-bbb-b # uuid_parent: 2-222-222-2 -# id_user: 2 -# id_document: 2 +# uuid_user: 000-000-000 +# uuid_document: -0---0---0- # level: modify # pending: False # pending_from: grantee @@ -41,16 +41,16 @@ # Document 3 - uuid: 3-333-333-3 - id_user: 1 - id_document: 3 + uuid_user: 99d-99d-99d + uuid_document: lormipsum3 level: own pending: False pending_from: created - uuid: c-ccc-ccc-c uuid_parent: 3-333-333-3 - id_user: 2 - id_document: 3 + uuid_user: 000-000-000 + uuid_document: lormipsum3 level: modify pending: False pending_from: granter @@ -60,16 +60,16 @@ # Document 4 (ex-parrot) - uuid: 4-444-444-4 - id_user: 1 - id_document: 4 + uuid_user: 99d-99d-99d + uuid_document: ex-parrot level: own pending: False pending_from: created - uuid: d-ddd-ddd-d uuid_parent: 4-444-444-4 - id_user: 2 - id_document: 4 + uuid_user: 000-000-000 + uuid_document: ex-parrot level: modify pending: False pending_from: grantee @@ -79,16 +79,16 @@ # Document 5 (aaa-aaa-aaa) - uuid: 5-555-555-5 - id_user: 1 - id_document: 5 + uuid_user: 99d-99d-99d + uuid_document: aaa-aaa-aaa level: own pending: False pending_from: created - uuid: e-eee-eee-e uuid_parent: 5-555-555-5 - id_user: 2 - id_document: 5 + uuid_user: 000-000-000 + uuid_document: aaa-aaa-aaa level: own pending: False pending_from: granter @@ -98,24 +98,24 @@ # Document 6 (petshoppe--) - uuid: 6-666-666-6 - id_user: 2 - id_document: 6 + uuid_user: 000-000-000 + uuid_document: petshoppe-- level: own pending: False pending_from: created - uuid: f-fff-fff-f uuid_parent: 6-666-666-6 - id_user: 1 - id_document: 6 + uuid_user: 99d-99d-99d + uuid_document: petshoppe-- level: modify pending: False pending_from: grantee - uuid: -=-=-=-=-=- uuid_parent: 6-666-666-6 - id_user: 3 - id_document: 6 + uuid_user: 777-777-777 + uuid_document: petshoppe-- level: view pending: False pending_from: grantee @@ -125,16 +125,16 @@ # Document 7 (foobar-spam) - uuid: 7-777-777-7 - id_user: 1 - id_document: 7 + uuid_user: 99d-99d-99d + uuid_document: foobar-spam level: own pending: False pending_from: created - uuid: g-ggg-ggg-g uuid_parent: 7-777-777-7 - id_user: 2 - id_document: 7 + uuid_user: 000-000-000 + uuid_document: foobar-spam level: own pending: False pending_from: granter @@ -143,8 +143,8 @@ # Document 8 (draculaflow) - uuid: 888-888-888 - id_user: 2 - id_document: 8 + uuid_user: 000-000-000 + uuid_document: draculaflow level: own pending: False pending_from: created diff --git a/tests/assets/user.yaml b/src/simulatus/assets/user.yaml similarity index 95% rename from tests/assets/user.yaml rename to src/simulatus/assets/user.yaml index 136f3ca..d7b1306 100644 --- a/tests/assets/user.yaml +++ b/src/simulatus/assets/user.yaml @@ -1,5 +1,4 @@ -- id: 1 - uuid: 99d-99d-99d +- uuid: 99d-99d-99d subject: 721f1d63d7015cd2c54bcb441e923464f27768a89a1f46640088a5a839a5d186 name: you're mom description: The joke is that it is mispelled. @@ -13,7 +12,6 @@ # Because of tests not an admin - uuid: 000-000-000 subject: 9de6a6fa6734b71af099005fdeb709e73083fb6ce6d453f726da3e8aeb4c4595 - id: 2 admin: True name: acederberg description: maintainer of this project @@ -26,7 +24,6 @@ - uuid: 777-777-777 subject: b8494f0c413111c8a0a23372fd2a3cc4970e4a29478c22a6f60a122423edc0f4 - id: 3 name: Demo User description: Demo user email: demo@example.io @@ -38,7 +35,6 @@ - uuid: -0123456789 subject: e663ef439f4924a62ef50c7d2d3fee4e02b5e6fb46ad25191938eddd49681a9b - id: 4 name: Sum dood description: Whatever email: sumdood@whatever.org diff --git a/src/simulatus/config.py b/src/simulatus/config.py index 66e19a7..63c5cdc 100644 --- a/src/simulatus/config.py +++ b/src/simulatus/config.py @@ -3,10 +3,15 @@ import yaml from pydantic import Field +from yaml_settings_pydantic import ( + BaseYamlSettings, + YamlFileConfigDict, + YamlSettingsConfigDict, +) # --------------------------------------------------------------------------- # +from captura import util from captura.config import BaseHashable -from captura.config import Config as ConfigCaptura from captura.schemas import mwargs @@ -106,5 +111,20 @@ def load(cls, manifest_path: str) -> Self: return cls.model_validate(raw) -class ConfigSimulatus(ConfigCaptura): +class ConfigSimulatus(BaseYamlSettings): + model_config = YamlSettingsConfigDict( + # NOTE: Yes, this field is labeled by the constant value computed at + # the initial runtime. This can be overwritten with environment + # changes (e.g. mocks in tests) where getting this value from the + # environment. + yaml_files={ + util.PATH_CONFIG_DUMMY: YamlFileConfigDict( + envvar=util.prefix_env("DUMMY_CONFIG") + ) + }, + yaml_reload=False, + env_prefix=util.ENV_PREFIX, + env_nested_delimiter="__", + extra="allow", + ) dummy: DummyConfig diff --git a/src/simulatus/reports.py b/src/simulatus/reports.py index 12c93f0..e90b2ab 100644 --- a/src/simulatus/reports.py +++ b/src/simulatus/reports.py @@ -245,7 +245,7 @@ def content(self, v: Any) -> None: @classmethod def q_flat(cls, *additional_fields): return select( - User.id.label("id_user"), + User.uuid.label("id_user"), cls.uuid.label("uuid"), cls.uuid_parent.label("uuid_parent"), cls.uuid_user.label("uuid_user"), @@ -271,16 +271,16 @@ def q_content_data_count(cls, user: User | None = None): q_assignment = select(func.count(Assignment.uuid)) if user is not None: - q_document = select(Grant.id_document).where( + _q_document = select(Grant.uuid_document).where( Grant.pending_from == fields.PendingFrom.created, - Grant.id_user == user.id, + Grant.uuid_user == user.uuid, ) - q_document = select(func.count()).select_from(q_document.subquery()) + q_document = select(func.count()).select_from(_q_document.subquery()) q_collection = q_collection.join(User).where(User.uuid == user.uuid) q_assignment = q_assignment.join(Collection).where( - Collection.id_user == user.id + Collection.uuid_user == user.uuid ) - q_grant = q_grant.where(Grant.id_user == user.id) + q_grant = q_grant.where(Grant.uuid_user == user.uuid) q_event = select(func.count(Event.uuid)).where(Event.uuid_user == user.uuid) return select( @@ -335,7 +335,7 @@ def q_select(cls, user: User | None = None): .group_by(User.uuid, *_grant_agg) ) if user is not None: - q_reports_grants = q_reports_grants.where(Grant.id_user == user.id) + q_reports_grants = q_reports_grants.where(Grant.uuid_user == user.uuid) count_per_user: Any = literal_column("count_per_user") res_columns: Tuple[Any, ...] = ( diff --git a/tests/assets/edit.yaml b/tests/assets/edit.yaml deleted file mode 100644 index f8ed01d..0000000 --- a/tests/assets/edit.yaml +++ /dev/null @@ -1,175 +0,0 @@ - -- id_document: 6 - id: 1 - id_user: 1 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - Gravida neque convallis a cras semper auctor. - Id faucibus nisl tincidunt eget nullam. - Nisi lacus sed viverra tellus. - -- id_document: 6 - id_user: 1 - id: 2 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - Gravida neque convallis a cras semper auctor. - Id faucibus nisl tincidunt eget nullam. - Nisi lacus sed viverra tellus. - Turpis egestas sed tempus urna et. - -- id_document: 6 - id_user: 1 - id: 3 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - Gravida neque convallis a cras semper auctor. - Id faucibus nisl tincidunt eget nullam. - Nisi lacus sed viverra tellus. - -- id_document: 6 - id_user: 1 - id: 4 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - Gravida neque convallis a cras semper auctor. - Id faucibus nisl tincidunt eget nullam. - -- id_document: 6 - id_user: 1 - id: 5 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - Gravida neque convallis a cras semper auctor. - -- id_document: 6 - id_user: 1 - id: 6 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - Nulla pellentesque dignissim enim sit amet venenatis. - -- id_document: 6 - id_user: 1 - id: 7 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - Elit duis tristique sollicitudin nibh sit amet commodo nulla facilisi. - -- id_document: 6 - id_user: 1 - id: 8 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - Nibh ipsum consequat nisl vel pretium. - -- id_document: 6 - id_user: 1 - id: 9 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - Arcu risus quis varius quam quisque id diam vel quam. - -- id_document: 6 - id_user: 1 - id: 10 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - In ornare quam viverra orci sagittis eu volutpat odio. - -- id_document: 6 - id_user: 1 - id: 11 - content: | - - Rotton Possum - ============================ - - Odio aenean sed adipiscing diam donec adipiscing tristique risus. - Quis vel eros donec ac. - diff --git a/tests/config.py b/tests/config.py index 7b09507..0e72f78 100644 --- a/tests/config.py +++ b/tests/config.py @@ -10,7 +10,7 @@ # --------------------------------------------------------------------------- # from captura import util -from captura.config import BaseHashable +from captura.config import BaseHashable, Config from captura.schemas import mwargs from legere import Config as ClientConfig from legere import flags @@ -52,7 +52,7 @@ class PytestSubConfig(BaseHashable): ] -class PytestConfig(ConfigSimulatus): +class PytestConfig(ConfigSimulatus, Config): """Configuration with additional pytest section. This should not be used in app. @@ -62,7 +62,9 @@ class PytestConfig(ConfigSimulatus): pytestconfig: ClassVar[PytestConf] model_config = YamlSettingsConfigDict( - yaml_files=util.PATH_CONFIG_TEST_APP, + yaml_files={ + util.PATH_CONFIG_TEST_APP: YamlFileConfigDict(required=True), + }, yaml_reload=False, env_prefix=util.ENV_PREFIX, env_nested_delimiter="__", diff --git a/tests/conftest.py b/tests/conftest.py index a9d6d66..aaa2910 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -339,7 +339,7 @@ def dummy_handler( worker_id: str, ): name_module = f"(`module={request.node.name}`) " - handler = DummyHandler(sessionmaker, config, auth=auth) + handler = DummyHandler(sessionmaker, config=config, config_dummy=config, auth=auth) if worker_id != "master": return handler diff --git a/tests/test_controllers/test_access.py b/tests/test_controllers/test_access.py index d31cb53..1086f9a 100644 --- a/tests/test_controllers/test_access.py +++ b/tests/test_controllers/test_access.py @@ -249,8 +249,8 @@ def test_d_fn(self) -> None: # quser = ( # select(Document.uuid) # .select_from(Document) -# .join(Grant, onclause=Grant.id_document == Document.id) -# .join(User, onclause=User.id == Grant.id_user) +# .join(Grant, onclause=Grant.uuid_document == Document.uuid) +# .join(User, onclause=User.uuid == Grant.uuid_user) # .where( # User.uuid == "000-000-000", # Grant.level >= level.value, @@ -528,7 +528,7 @@ def test_overloads(self, dummy: DummyProvider, count): def test_private(self, dummy: DummyProvider, count): (collection,) = dummy.get_collections(1) (collection_other,) = dummy.get_collections(1, other=True) - assert collection_other.id_user != dummy.user.id + assert collection_other.uuid_user != dummy.user.uuid collection.deleted, collection.public = False, False collection_other.deleted, collection_other.public = False, False @@ -560,7 +560,7 @@ def test_private(self, dummy: DummyProvider, count): # NOTE: User can access their own private collection res = access.collection(collection.uuid) - assert res.id_user == access.token_user.id + assert res.uuid_user == access.token_user.uuid assert collection.uuid == res.uuid # TODO: Private users cannot have public collections. How to resolve? @@ -662,7 +662,7 @@ def test_modify(self, dummy: DummyProvider, count): # Can when owner, impersonate owner. collection_res = access.collection(collection.uuid) assert collection_res.uuid == collection.uuid - assert collection.id_user == dummy.user.id + assert collection.uuid_user == dummy.user.uuid class TestAccessDocument(BaseTestAccess): @@ -675,8 +675,8 @@ def test_document_other(self, dummy: DummyProvider): for document in dummy.get_documents(25, other=True): n_grants = dummy.session.scalar( select(func.count(Grant.uuid)).where( - Grant.id_user == dummy.user.id, - Grant.id_document == document.id, + Grant.uuid_user == dummy.user.uuid, + Grant.uuid_document == document.uuid, ) ) assert not n_grants diff --git a/tests/test_controllers/test_assoc.py b/tests/test_controllers/test_assoc.py index ce58c4c..1620dd0 100644 --- a/tests/test_controllers/test_assoc.py +++ b/tests/test_controllers/test_assoc.py @@ -37,7 +37,7 @@ def test_split_assocs(self, dummy: DummyProvider, count: int): assoc := data.data.assoc.get(uuid_assoc) ) is not None, "All assocs should be in data." assert assoc.deleted is True - assert assoc.id_document == data.data.document.id + assert assoc.uuid_document == data.data.document.uuid uuid_target_deleted.add(assoc.uuid_collection) uuid_target_active = set() @@ -55,7 +55,7 @@ def test_split_assocs(self, dummy: DummyProvider, count: int): select(func.count(Assignment.uuid)) .join(Collection) .where( - Assignment.id_document == data.data.document.id, + Assignment.uuid_document == data.data.document.uuid, Collection.uuid == uuid_target, ) ) @@ -214,7 +214,7 @@ def test_grant_document(self, dummy: DummyProvider, count: int): .join(Document) .where( User.uuid.in_(data.data.uuid_users), - Document.id == data.data.document.id, + Document.uuid == data.data.document.uuid, ) ) assert session.scalar(q) == 0 diff --git a/tests/test_dummy.py b/tests/test_dummy.py index a77f969..1542629 100644 --- a/tests/test_dummy.py +++ b/tests/test_dummy.py @@ -43,7 +43,7 @@ def test_mk(self, dummy: DummyProvider, session: Session, count: int): # NOTE: Verify that collections exist. q = select(func.count(Collection.uuid)).where( - Collection.id_user == dummy.user.id + Collection.uuid_user == dummy.user.uuid ) assert (n := session.scalar(q)) is not None and n > 0 @@ -52,20 +52,20 @@ def test_mk(self, dummy: DummyProvider, session: Session, count: int): # items. (3) q = select(func.count(Grant.uuid)).where( - Grant.id_user == dummy.user.id, + Grant.uuid_user == dummy.user.uuid, Grant.pending_from == PendingFrom.created, ) assert (n := session.scalar(q)) is not None and n > 0 q = select(func.count(Grant.pending_from.distinct())) q = q.where( - Grant.id_user == dummy.user.id, + Grant.uuid_user == dummy.user.uuid, Grant.pending_from != PendingFrom.created, ) assert (n := session.scalar(q)) is not None and n > 0 q = select(func.count(Grant.level.distinct())) - q = q.where(Grant.id_user == dummy.user.id) + q = q.where(Grant.uuid_user == dummy.user.uuid) assert session.scalar(q) == 3 q = select(func.count(Grant.pending.distinct())) @@ -207,7 +207,7 @@ def test_get_documents(self, dummy: DummyProvider, count: int): select(Grant) .join(Document) .where( - Grant.id_user == dummy.user.id, + Grant.uuid_user == dummy.user.uuid, Document.uuid.in_(uuid_documents), ) ) @@ -239,7 +239,7 @@ def test_get_documents(self, dummy: DummyProvider, count: int): .join(Document) .where( Document.uuid.in_(uuid_documents), - Grant.id_user == dummy.user.id, + Grant.uuid_user == dummy.user.uuid, ) ) n_grants = dummy.session.scalar(q_grants) @@ -426,17 +426,17 @@ def test_get_data_grant_document(self, dummy: DummyProvider, count: int): # have one grant, the grant to this document. assert len(token_user_grants := data.data.token_user_grants) == 1 assert (gg := token_user_grants.get(dummy.user.uuid)) is not None - assert data.data.document.id == gg.id_document + assert data.data.document.uuid == gg.uuid_document # NOTE: There is not necessarily a grant for every user. Grants should # be indexed using user uuids. grants = data.data.grants - id_document = data.data.document.id + id_document = data.data.document.uuid uuid_user = uuids(data.data.users) uuid_user_has_grants = set(grants) assert uuid_user.issuperset(uuid_user_has_grants) - assert all(gg.id_document == id_document for gg in grants.values()) + assert all(gg.uuid_document == id_document for gg in grants.values()) def test_get_data_grant_user(self, dummy: DummyProvider, count: int): data = dummy.get_data_grant_user() @@ -451,7 +451,7 @@ def test_get_data_grant_user(self, dummy: DummyProvider, count: int): assert set(gg.uuid_document for gg in token_user_grants).issubset( uuids(data.data.documents) ) - assert all(gg.id_user == dummy.user.id for gg in token_user_grants) + assert all(gg.uuid_user == dummy.user.uuid for gg in token_user_grants) # NOTE: For now, grants and token user grants are always the same as # the data provided will always have a document owned by @@ -469,7 +469,9 @@ def test_get_data_assignment_collection(self, dummy: DummyProvider, count: int): assert set(aa.uuid_document for aa in assignments).issubset( uuids(data.data.documents) ) - assert all(aa.id_collection == data.data.collection.id for aa in assignments) + assert all( + aa.uuid_collection == data.data.collection.uuid for aa in assignments + ) def test_get_data_assignment_document(self, dummy: DummyProvider, count: int): data = dummy.get_data_assignment_document() @@ -480,7 +482,7 @@ def test_get_data_assignment_document(self, dummy: DummyProvider, count: int): assert set(aa.uuid_collection for aa in assignments).issubset( uuids(data.data.collections) ) - assert all(aa.id_document == data.data.document.id for aa in assignments) + assert all(aa.uuid_document == data.data.document.uuid for aa in assignments) # NOTE: Test passing of kwargs. data = dummy.get_data_assignment_document( @@ -513,7 +515,7 @@ def test_get_primary_retry(self, dummy: DummyProvider, count: int): """Verify that ``get_primary`` is robust.""" # NOTE: Delete dummy collections. - q_rm = delete(Collection).where(Collection.id_user == dummy.user.id) + q_rm = delete(Collection).where(Collection.uuid_user == dummy.user.uuid) session = dummy.session session.execute(q_rm) @@ -532,7 +534,7 @@ def test_get_primary_retry(self, dummy: DummyProvider, count: int): # NOTE: Delete dummy documents where the user is designated as the # ``creator`` and grants on remaining documents. q_documents_created = select(Document).where( - Grant.id_user == dummy.user.id, + Grant.uuid_user == dummy.user.uuid, Grant.pending_from == PendingFrom.created, ) for doc in session.scalars(q_documents_created): @@ -540,11 +542,11 @@ def test_get_primary_retry(self, dummy: DummyProvider, count: int): session.commit() - session.execute(delete(Grant).where(Grant.id_user == dummy.user.id)) + session.execute(delete(Grant).where(Grant.uuid_user == dummy.user.uuid)) session.commit() # NOTE: Confirm document and grant removal with db and `get_documents`. - q = select(func.count(Grant.uuid)).where(Grant.id_user == dummy.user.id) + q = select(func.count(Grant.uuid)).where(Grant.uuid_user == dummy.user.uuid) assert not session.scalar(q), "No grants should remain for dummy user." kwargs = GetPrimaryKwargs( diff --git a/tests/test_models.py b/tests/test_models.py index b7a0b6a..87e3ec3 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -178,7 +178,7 @@ def test_document_deletion(self, dummy_disposable: DummyProvider, count: int): ) # NOTE: Because there are not dummies. - # q_edit_uuids = select(Edit.uuid).where(Edit.id_document == document.id) + # q_edit_uuids = select(Edit.uuid).where(Edit.uuid_document == document.uuid) # uuid_edit = set(session.scalars(q_edit_uuids)) # --------------------------------------------------------------- # @@ -278,7 +278,7 @@ def test_user_deletion_collections( user = dummy.user uuid_collections = set( session.scalars( - select(Collection.uuid).where(Collection.id_user == user.id) + select(Collection.uuid).where(Collection.uuid_user == user.uuid) ) ) if not len(uuid_collections): @@ -309,7 +309,7 @@ def test_user_deletion_collections( # user = dummy.user # # uuid_edits = set( - # session.scalars(select(Edit.uuid).where(Edit.id_user == user.id)) + # session.scalars(select(Edit.uuid).where(Edit.uuid_user == user.uuid)) # ) # if not (n_edits := len(uuid_edits)): # n_no_edits += 1 @@ -353,7 +353,7 @@ def test_user_deletion_collections( # # NOTE: Get collections and edits. Collections should be deleted, # # edits should not be deleted unless they belong to one of the # # above documents. - # q_uuid_edit = select(Edit.uuid).where(Edit.id_user == user.id) + # q_uuid_edit = select(Edit.uuid).where(Edit.uuid_user == user.uuid) # uuid_edit = set(session.scalars(q_uuid_edit)) # # q_uuid_edit_uniq = q_uuid_edit.join(Document).where( @@ -361,7 +361,7 @@ def test_user_deletion_collections( # ) # uuid_edit_uniq = set(session.scalars(q_uuid_edit_uniq)) # - # q_uuid_collection = select(Collection.uuid).where(Collection.id_user == user.id) + # q_uuid_collection = select(Collection.uuid).where(Collection.uuid_user == user.uuid) # uuid_collection = set(session.scalars(q_uuid_collection)) # # session.delete(user) @@ -383,7 +383,7 @@ def test_q_select_documents( def get_grants(docs: Resolvable[Document]) -> Tuple[Grant, ...]: uuid_document = Document.resolve_uuid(session, docs) q = select(Grant).join(Document) - q = q.where(Document.uuid.in_(uuid_document), Grant.id_user == user.id) + q = q.where(Document.uuid.in_(uuid_document), Grant.uuid_user == user.uuid) return tuple(session.scalars(q)) def uuids(docs) -> Set[str]: @@ -542,8 +542,8 @@ def uuids(docs) -> Set[str]: pending_from=PendingFrom.created, pending=False, deleted=False, - id_user=dummy.user.id, - id_document=doc.id, + uuid_user=dummy.user.uuid, + uuid_document=doc.uuid, ) session.add(grant) diff --git a/tests/test_views/test_assignments_collections_unit.py b/tests/test_views/test_assignments_collections_unit.py index f840098..3b37151 100644 --- a/tests/test_views/test_assignments_collections_unit.py +++ b/tests/test_views/test_assignments_collections_unit.py @@ -93,7 +93,7 @@ async def test_forbidden_403( (collection,) = dummy.get_collections(1, GetPrimaryKwargs(deleted=False)) uuid_document = [secrets.token_urlsafe(9)] - collection.id_user = user_other.id + collection.uuid_user = user_other.uuid if self.method == H.GET: collection.public = False msg = ErrAccessCollection._msg_private @@ -181,7 +181,7 @@ async def test_success_200( select(Assignment) .join(Document) .where( - Assignment.id_collection == collection.id, + Assignment.uuid_collection == collection.uuid, Assignment.deleted == false(), Document.deleted == false(), ) @@ -366,13 +366,13 @@ async def test_success_200( (collection,) = dummy.get_collections(1) documents = dummy.get_documents(9, GetPrimaryKwargs(deleted=False), other=True) uuid_document_list = list(dd.uuid for dd in documents) - id_document_list = [dd.id for dd in documents] + id_document_list = [dd.uuid for dd in documents] assert (n_documents := len(uuid_document_list)) > 1 session.execute( delete(Assignment).where( - Assignment.id_document.in_(id_document_list), - Assignment.id_collection == collection.id, + Assignment.uuid_document.in_(id_document_list), + Assignment.uuid_collection == collection.uuid, ) ) session.commit() @@ -434,8 +434,8 @@ async def test_success_200( update(Assignment) .values(deleted=True) .where( - Assignment.id_document.in_(id_document_list[: n_documents - 2]), - Assignment.id_collection == collection.id, + Assignment.uuid_document.in_(id_document_list[: n_documents - 2]), + Assignment.uuid_collection == collection.uuid, ) ) session.commit() diff --git a/tests/test_views/test_assignments_documents_unit.py b/tests/test_views/test_assignments_documents_unit.py index fce1eec..1bbb91b 100644 --- a/tests/test_views/test_assignments_documents_unit.py +++ b/tests/test_views/test_assignments_documents_unit.py @@ -104,7 +104,7 @@ async def test_forbidden_403( session, level = dummy.session, Level.view (document,) = dummy.get_documents(level=level, n=1) (collection,) = dummy.get_collections(1) - session.merge(Assignment(id_document=document.id, id_collection=collection.id)) + session.merge(Assignment(uuid_document=document.uuid, uuid_collection=collection.uuid)) session.commit() grant = dummy.get_document_grant(document) @@ -146,7 +146,7 @@ async def test_forbidden_403( _ = session.add(document) assignment = session.scalar( - select(Assignment).where(Assignment.id_document == document.id).limit(1) + select(Assignment).where(Assignment.uuid_document == document.uuid).limit(1) ) assert assignment is not None @@ -179,7 +179,7 @@ async def test_success_200( (document,) = dummy.get_documents(level=Level.view, n=1) assignments = ( - Assignment(id_document=document.id, id_collection=cc.id) + Assignment(uuid_document=document.uuid, uuid_collection=cc.uuid) for cc in dummy.get_collections(10) ) tuple(map(session.merge, assignments)) @@ -196,7 +196,7 @@ async def test_success_200( select(Assignment.uuid) .join(Collection) .where( - Assignment.id_document == document.id, + Assignment.uuid_document == document.uuid, Assignment.deleted == false(), Collection.deleted == false(), ) @@ -268,7 +268,7 @@ async def test_success_200( assert len(collections) assignments = tuple( - Assignment(id_document=document.id, id_collection=cc.id, deleted=False) + Assignment(uuid_document=document.uuid, uuid_collection=cc.uuid, deleted=False) for cc in collections ) tuple(map(session.merge, assignments)) @@ -277,8 +277,8 @@ async def test_success_200( n_created = session.scalar( q := select(func.count(Assignment.uuid)).where( - Assignment.id_collection.in_([cc.id for cc in collections]), - Assignment.id_document == document.id, + Assignment.uuid_collection.in_([cc.uuid for cc in collections]), + Assignment.uuid_document == document.uuid, ) ) assert n_created == n_collections @@ -369,7 +369,7 @@ async def test_success_200( (document,) = dummy.get_documents(n=1, level=Level.own) # NOTE: Delete all assignments for this document. - q = delete(Assignment).where(Assignment.id_document == document.id) + q = delete(Assignment).where(Assignment.uuid_document == document.uuid) session.execute(q) session.commit() diff --git a/tests/test_views/test_collections_unit.py b/tests/test_views/test_collections_unit.py index 65d07dd..7052abb 100644 --- a/tests/test_views/test_collections_unit.py +++ b/tests/test_views/test_collections_unit.py @@ -115,7 +115,7 @@ async def test_forbidden_403( (collection,) = dummy.get_collections(n=1) collection.public = True collection.deleted = False - collection.id_user = user_other.id + collection.uuid_user = user_other.uuid session.add(collection) session.commit() @@ -199,8 +199,8 @@ async def test_success_200( # Test reading a public collection not ownend collection.public = True - collection.id_user = next( - uu.id for uu in dummy.get_users(2) if uu.uuid != dummy.user.uuid + collection.uuid_user = next( + uu.uuid for uu in dummy.get_users(2) if uu.uuid != dummy.user.uuid ) session.add(collection) session.commit() @@ -360,7 +360,7 @@ async def test_success_200( assert data.data.uuid_user == user.uuid # For next test. # NOTE: Transfer ownership. - user_other = next((uu for uu in dummy.get_users(2) if uu.id != user.id)) + user_other = next((uu for uu in dummy.get_users(2) if uu.uuid != user.uuid)) res = await fn(collection.uuid, uuid_user=user_other.uuid) if err := self.check_status(requests, res): raise err @@ -405,7 +405,7 @@ async def test_success_200( ): (collection,), session = dummy.get_collections(1), dummy.session assert not collection.deleted - assert collection.id_user == dummy.user.id + assert collection.uuid_user == dummy.user.uuid fn, fn_read = self.fn(requests), requests.collections.read fn_read_assignments = requests.assignments.collections.read @@ -415,7 +415,7 @@ async def test_success_200( .join(Collection) .join(Document) .where( - Collection.id == collection.id, + Collection.uuid == collection.uuid, Document.deleted == false(), Collection.deleted == false(), ) diff --git a/tests/test_views/test_grants_documents_unit.py b/tests/test_views/test_grants_documents_unit.py index 5be8166..af30d63 100644 --- a/tests/test_views/test_grants_documents_unit.py +++ b/tests/test_views/test_grants_documents_unit.py @@ -268,8 +268,8 @@ async def test_deleted_410( session.refresh(document) grant = Grant( - id_document=document.id, - id_user=dummy.user.id, + uuid_document=document.uuid, + uuid_user=dummy.user.uuid, level=Level.own, pending=False, deleted=False, @@ -284,7 +284,7 @@ async def test_deleted_410( # users = dummy.get_users(n=3) # uuid_user = uuids(users) - # grants = tuple(Grant(id_document=document.id, id_user=uu.id) for uu in users) + # grants = tuple(Grant(id_document=document.uuid, uuid_user=uu.uuid) for uu in users) # tuple(map(session.merge, grants)) errhttp = mwargs( @@ -395,8 +395,8 @@ async def test_success_200_pending( session.refresh(document) grant = Grant( - id_document=document.id, - id_user=dummy.user.id, + uuid_document=document.uuid, + uuid_user=dummy.user.uuid, level=Level.own, pending=False, deleted=False, @@ -405,8 +405,8 @@ async def test_success_200_pending( users = dummy.get_users(10, other=True) grants = [ Grant( - id_document=document.id, - id_user=user.id, + uuid_document=document.uuid, + uuid_user=user.uuid, level=Level.view, pending=index % 2, deleted=False, @@ -716,8 +716,8 @@ async def test_forbidden_403_cannot_reject_other_owner( users = dummy.get_users(other=True, n=5) session.add( grant := Grant( - id_user=dummy.user.id, - id_document=document.id, + uuid_user=dummy.user.uuid, + uuid_document=document.uuid, level=Level.own, pending=False, deleted=False, @@ -725,8 +725,8 @@ async def test_forbidden_403_cannot_reject_other_owner( children=( grants := list( Grant( - id_user=user.id, - id_document=document.id, + uuid_user=user.uuid, + uuid_document=document.uuid, level=Level.own, pending=False, deleted=False, @@ -789,8 +789,8 @@ async def test_forbidden_403_pending_from( uuid_user = [user_other.uuid] session.add(user_other) q_grant_other = select(Grant).where( - Grant.id_document == document.id, - Grant.id_user == user_other.id, + Grant.uuid_document == document.uuid, + Grant.uuid_user == user_other.uuid, ) grant_other_init = session.scalar(q_grant_other) if grant_other_init is not None: @@ -799,8 +799,8 @@ async def test_forbidden_403_pending_from( session.add( grant_other := Grant( - id_user=user_other.id, - id_document=document.id, + uuid_user=user_other.uuid, + uuid_document=document.uuid, level=Level.view, pending=True, deleted=False, @@ -866,8 +866,8 @@ async def test_success_200( session.add( Grant( - id_user=dummy.user.id, - id_document=document.id, + uuid_user=dummy.user.uuid, + uuid_document=document.uuid, level=Level.own, pending=False, pending_from=PendingFrom.created, diff --git a/tests/test_views/test_grants_users_unit.py b/tests/test_views/test_grants_users_unit.py index d03795b..05e69a4 100644 --- a/tests/test_views/test_grants_users_unit.py +++ b/tests/test_views/test_grants_users_unit.py @@ -283,8 +283,8 @@ async def test_bad_request_400( documents = dummy.get_documents(other=True, n=5) grants = tuple( Grant( - id_document=document.id, - id_user=dummy.user.id, + uuid_document=document.uuid, + uuid_user=dummy.user.uuid, level=Level.view, deleted=True, pending=False,