Correctly handle unique constraints
This commit is contained in:
parent
d54609543e
commit
ca7c89633b
|
@ -1,9 +1,8 @@
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
from teal.db import SchemaSQLAlchemy
|
||||||
from teal.db import SQLAlchemy as _SQLAlchemy
|
|
||||||
|
|
||||||
|
|
||||||
class SQLAlchemy(_SQLAlchemy):
|
class SQLAlchemy(SchemaSQLAlchemy):
|
||||||
"""
|
"""
|
||||||
Superuser must create the required extensions in the public
|
Superuser must create the required extensions in the public
|
||||||
schema of the database, as it is in the `search_path`
|
schema of the database, as it is in the `search_path`
|
||||||
|
|
|
@ -5,12 +5,12 @@ from uuid import UUID
|
||||||
|
|
||||||
from flask import current_app as app, request
|
from flask import current_app as app, request
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
|
from teal.resource import View
|
||||||
|
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.resources.device.models import Component, Computer
|
from ereuse_devicehub.resources.device.models import Component, Computer
|
||||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||||
from ereuse_devicehub.resources.event.models import Event, Snapshot, WorkbenchRate
|
from ereuse_devicehub.resources.event.models import Event, Snapshot, WorkbenchRate
|
||||||
from teal.resource import View
|
|
||||||
|
|
||||||
|
|
||||||
class EventView(View):
|
class EventView(View):
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -44,7 +44,7 @@ setup(
|
||||||
'psycopg2-binary',
|
'psycopg2-binary',
|
||||||
'python-stdnum',
|
'python-stdnum',
|
||||||
'PyYAML',
|
'PyYAML',
|
||||||
'teal>=0.2.0a12',
|
'teal>=0.2.0a13',
|
||||||
'requests',
|
'requests',
|
||||||
'requests-toolbelt',
|
'requests-toolbelt',
|
||||||
'sqlalchemy-utils[password, color, phone]',
|
'sqlalchemy-utils[password, color, phone]',
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy.exc import IntegrityError
|
|
||||||
from sqlalchemy_utils import PhoneNumber
|
from sqlalchemy_utils import PhoneNumber
|
||||||
|
from teal.db import UniqueViolation
|
||||||
|
from teal.enums import Country
|
||||||
|
|
||||||
from ereuse_devicehub.config import DevicehubConfig
|
from ereuse_devicehub.config import DevicehubConfig
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.devicehub import Devicehub
|
from ereuse_devicehub.devicehub import Devicehub
|
||||||
from ereuse_devicehub.resources.agent import OrganizationDef, models, schemas
|
from ereuse_devicehub.resources.agent import OrganizationDef, models, schemas
|
||||||
from ereuse_devicehub.resources.agent.models import Membership, Organization, Person, System
|
from ereuse_devicehub.resources.agent.models import Membership, Organization, Person, System
|
||||||
from teal.enums import Country
|
|
||||||
from tests.conftest import app_context, create_user
|
from tests.conftest import app_context, create_user
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ def test_membership_repeated():
|
||||||
db.session.add(person)
|
db.session.add(person)
|
||||||
|
|
||||||
person.member_of.add(Membership(org, person))
|
person.member_of.add(Membership(org, person))
|
||||||
with pytest.raises(IntegrityError):
|
with pytest.raises(UniqueViolation):
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ def test_membership_repeating_id():
|
||||||
person2 = Person(name='Tommy')
|
person2 = Person(name='Tommy')
|
||||||
person2.member_of.add(Membership(org, person2, id='acme-1'))
|
person2.member_of.add(Membership(org, person2, id='acme-1'))
|
||||||
db.session.add(person2)
|
db.session.add(person2)
|
||||||
with pytest.raises(IntegrityError) as e:
|
with pytest.raises(UniqueViolation) as e:
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
assert 'One member id per organization' in str(e)
|
assert 'One member id per organization' in str(e)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from typing import List, Tuple
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from teal.db import UniqueViolation
|
||||||
|
|
||||||
from ereuse_devicehub.client import UserClient
|
from ereuse_devicehub.client import UserClient
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
|
@ -274,11 +275,10 @@ def test_snapshot_different_properties_same_tags(user: UserClient, tag_id: str):
|
||||||
user.post(pc2, res=Snapshot, status=422)
|
user.post(pc2, res=Snapshot, status=422)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(reason='duplicate Snapshot is a human error and needs a nice error message.')
|
|
||||||
def test_snapshot_upload_twice_uuid_error(user: UserClient):
|
def test_snapshot_upload_twice_uuid_error(user: UserClient):
|
||||||
pc1 = file('basic.snapshot')
|
pc1 = file('basic.snapshot')
|
||||||
user.post(pc1, res=Snapshot)
|
user.post(pc1, res=Snapshot)
|
||||||
user.post(pc1, res=Snapshot, status=422)
|
user.post(pc1, res=Snapshot, status=UniqueViolation)
|
||||||
|
|
||||||
|
|
||||||
def test_erase(user: UserClient):
|
def test_erase(user: UserClient):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from sqlalchemy.exc import IntegrityError
|
from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation
|
||||||
|
from teal.marshmallow import ValidationError
|
||||||
|
|
||||||
from ereuse_devicehub.client import UserClient
|
from ereuse_devicehub.client import UserClient
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
|
@ -10,8 +11,6 @@ from ereuse_devicehub.resources.device.models import Desktop
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis
|
from ereuse_devicehub.resources.enums import ComputerChassis
|
||||||
from ereuse_devicehub.resources.tag import Tag
|
from ereuse_devicehub.resources.tag import Tag
|
||||||
from ereuse_devicehub.resources.tag.view import CannotCreateETag, TagNotLinked
|
from ereuse_devicehub.resources.tag.view import CannotCreateETag, TagNotLinked
|
||||||
from teal.db import MultipleResourcesFound, ResourceNotFound
|
|
||||||
from teal.marshmallow import ValidationError
|
|
||||||
from tests import conftest
|
from tests import conftest
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ def test_create_two_same_tags():
|
||||||
"""Ensures there cannot be two tags with the same ID and organization."""
|
"""Ensures there cannot be two tags with the same ID and organization."""
|
||||||
db.session.add(Tag(id='foo-bar'))
|
db.session.add(Tag(id='foo-bar'))
|
||||||
db.session.add(Tag(id='foo-bar'))
|
db.session.add(Tag(id='foo-bar'))
|
||||||
with raises(IntegrityError):
|
with raises(UniqueViolation):
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
# And it works if tags are in different organizations
|
# And it works if tags are in different organizations
|
||||||
|
|
Reference in a new issue