diff --git a/ereuse_devicehub/resources/tag/model.py b/ereuse_devicehub/resources/tag/model.py index 7f6acc4f..9a5231d7 100644 --- a/ereuse_devicehub/resources/tag/model.py +++ b/ereuse_devicehub/resources/tag/model.py @@ -125,6 +125,19 @@ class Tag(Thing): """Return a SQLAlchemy filter expression for printable queries.""" return cls.org_id == Organization.get_default_org_id() + def delete(self): + """Deletes the tag. + + This method removes the tag if is named tag and don't have any linked device. + """ + if self.device: + raise TagLinked(self) + if self.provider: + # if is an unnamed tag not delete + raise TagUnnamed(self.id) + + db.session.delete(self) + def __repr__(self) -> str: return ''.format(self) @@ -133,3 +146,15 @@ class Tag(Thing): def __format__(self, format_spec: str) -> str: return '{0.org.name} {0.id}'.format(self) + + +class TagLinked(ValidationError): + def __init__(self, tag): + message = 'The tag {} is linked to device {}.'.format(tag.id, tag.device.id) + super().__init__(message, field_names=['device']) + + +class TagUnnamed(ValidationError): + def __init__(self, id): + message = 'This tag {} is unnamed tag. It is imposible delete.'.format(id) + super().__init__(message, field_names=['device']) diff --git a/ereuse_devicehub/resources/tag/view.py b/ereuse_devicehub/resources/tag/view.py index 2b1d2c1a..75f575f5 100644 --- a/ereuse_devicehub/resources/tag/view.py +++ b/ereuse_devicehub/resources/tag/view.py @@ -60,6 +60,14 @@ class TagView(View): db.session.commit() return Response(status=201) + @auth.Auth.requires_auth + def delete(self, id): + tag = Tag.from_an_id(id).filter_by(owner=g.user).one() + tag.delete() + db.session().final_flush() + db.session.commit() + return Response(status=204) + class TagDeviceView(View): """Endpoints to work with the device of the tag; /tags/23/device.""" diff --git a/tests/test_tag.py b/tests/test_tag.py index b3a8fd4d..ce6a517e 100644 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -35,6 +35,49 @@ def test_create_tag(user: UserClient): assert tag.provider == URL('http://foo.bar') +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_delete_tags(user: UserClient, client: Client): + """Delete a named tag.""" + # Delete Tag Named + # import pdb; pdb.set_trace() + pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']) + db.session.add(pc) + db.session.commit() + tag = Tag(id='bar', owner_id=user.user['id'], device_id=pc.id) + db.session.add(tag) + db.session.commit() + tag = Tag.query.one() + assert tag.id == 'bar' + # Is not possible delete one tag linked to one device + res, _ = user.delete(res=Tag, item=tag.id, status=422) + msg = 'The tag bar is linked to device' + assert msg in res['message'][0] + + tag.device_id = None + db.session.add(tag) + db.session.commit() + # Is not possible delete one tag from an anonymous user + client.delete(res=Tag, item=tag.id, status=401) + + # Is possible delete one normal tag + user.delete(res=Tag, item=tag.id) + user.get(res=Tag, item=tag.id, status=404) + + # Delete Tag UnNamed + org = Organization(name='bar', tax_id='bartax') + tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id']) + db.session.add(tag) + db.session.commit() + tag = Tag.query.one() + assert tag.id == 'bar-1' + res, _ = user.delete(res=Tag, item=tag.id, status=422) + msg = 'This tag {} is unnamed tag. It is imposible delete.'.format(tag.id) + assert msg in res['message'] + tag = Tag.query.one() + assert tag.id == 'bar-1' + + @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_create_tag_default_org(user: UserClient):