From 689d0c48c81995f15e30e2a887cb2dd0885684a9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 26 Feb 2021 11:28:32 +0100 Subject: [PATCH] change the model of tags from org to user --- .../6a2a939d5668_drop_unique_org_for_tag.py | 33 +++++++++++++++++++ ereuse_devicehub/resources/tag/model.py | 5 +-- ereuse_devicehub/resources/tag/view.py | 13 +++++++- tests/test_tag.py | 28 ++++++++++++---- 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py diff --git a/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py b/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py new file mode 100644 index 00000000..417c27f9 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/6a2a939d5668_drop_unique_org_for_tag.py @@ -0,0 +1,33 @@ +"""drop unique org for tag + +Revision ID: 6a2a939d5668 +Revises: eca457d8b2a4 +Create Date: 2021-02-25 18:47:47.441195 + +""" +from alembic import op +from alembic import context + + +# revision identifiers, used by Alembic. +revision = '6a2a939d5668' +down_revision = 'eca457d8b2a4' +branch_labels = None +depends_on = None + + +def get_inv(): + INV = context.get_x_argument(as_dictionary=True).get('inventory') + if not INV: + raise ValueError("Inventory value is not specified") + return INV + +def upgrade(): + op.drop_constraint('one tag id per organization', 'tag', schema=f'{get_inv()}') + op.drop_constraint('one secondary tag per organization', 'tag', schema=f'{get_inv()}') + op.create_unique_constraint('one tag id per owner', 'tag', ['id', 'owner_id'], schema=f'{get_inv()}') + + +def downgrade(): + op.create_unique_constraint('one tag id per organization', 'tag', ['id', 'org_id'], schema=f'{get_inv()}') + op.create_unique_constraint('one secondary tag per organization', 'tag', ['id', 'secondary'], schema=f'{get_inv()}') diff --git a/ereuse_devicehub/resources/tag/model.py b/ereuse_devicehub/resources/tag/model.py index 8aae5670..b5128830 100644 --- a/ereuse_devicehub/resources/tag/model.py +++ b/ereuse_devicehub/resources/tag/model.py @@ -97,8 +97,9 @@ class Tag(Thing): return url __table_args__ = ( - UniqueConstraint(id, org_id, name='one tag id per organization'), - UniqueConstraint(secondary, org_id, name='one secondary tag per organization') + UniqueConstraint(id, owner_id, name='one tag id per owner'), + # UniqueConstraint(id, org_id, name='one tag id per organization'), + # UniqueConstraint(secondary, org_id, name='one secondary tag per organization') ) @property diff --git a/ereuse_devicehub/resources/tag/view.py b/ereuse_devicehub/resources/tag/view.py index 6fd46770..2cb3009f 100644 --- a/ereuse_devicehub/resources/tag/view.py +++ b/ereuse_devicehub/resources/tag/view.py @@ -77,7 +77,8 @@ class TagDeviceView(View): @auth.Auth.requires_auth def put(self, tag_id: str, device_id: str): """Links an existing tag with a device.""" - tag = Tag.from_an_id(tag_id).one() # type: Tag + # tag = Tag.from_an_id(tag_id).one() # type: Tag + tag = Tag.from_an_id(tag_id).filter_by(owner=g.user).one() # type: Tag if tag.device_id: if tag.device_id == device_id: return Response(status=204) @@ -92,6 +93,16 @@ class TagDeviceView(View): db.session.commit() return Response(status=204) + @auth.Auth.requires_auth + def delete(self, tag_id: str, device_id: str): + tag = Tag.from_an_id(tag_id).filter_by(owner=g.user).one() # type: Tag + device = Device.query.filter_by(owner=g.user).filter_by(id=device_id).one() + if tag.device == device: + tag.device_id = None + db.session().final_flush() + db.session.commit() + return Response(status=204) + def get_device_from_tag(id: str): """Gets the device by passing a tag id. diff --git a/tests/test_tag.py b/tests/test_tag.py index b0336021..dcb8fe24 100644 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -51,13 +51,16 @@ def test_create_tag_default_org(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) -def test_create_tag_no_slash(): - """Checks that no tags can be created that contain a slash.""" - with raises(ValidationError): - Tag('/') - - with raises(ValidationError): - Tag('bar', secondary='/') +def test_create_same_tag_default_org_two_users(user: UserClient, user2: UserClient): + """Creates a tag using the default organization.""" + # import pdb; pdb.set_trace() + tag = Tag(id='foo-1', owner_id=user.user['id']) + tag2 = Tag(id='foo-1', owner_id=user2.user['id']) + db.session.add(tag) + db.session.add(tag2) + db.session.commit() + assert tag.org.name == 'FooOrg' # as defined in the settings + assert tag2.org.name == 'FooOrg' # as defined in the settings @pytest.mark.mvp @@ -78,6 +81,17 @@ def test_create_two_same_tags(user: UserClient): db.session.commit() +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_create_tag_no_slash(): + """Checks that no tags can be created that contain a slash.""" + with raises(ValidationError): + Tag('/') + + with raises(ValidationError): + Tag('bar', secondary='/') + + @pytest.mark.mvp def test_tag_post(app: Devicehub, user: UserClient): """Checks the POST method of creating a tag."""