diff --git a/api/db_migrations/versions/da6527f6cd76_create_scan_types_table.py b/api/db_migrations/versions/da6527f6cd76_create_scan_types_table.py new file mode 100644 index 00000000..29ed7813 --- /dev/null +++ b/api/db_migrations/versions/da6527f6cd76_create_scan_types_table.py @@ -0,0 +1,31 @@ +"""create scan types table + +Revision ID: da6527f6cd76 +Revises: b9ab107cd56a +Create Date: 2021-08-23 20:09:57.730128 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + + +# revision identifiers, used by Alembic. +revision = "da6527f6cd76" +down_revision = "b9ab107cd56a" +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + "scan_types", + sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True), + sa.Column("name", sa.Unicode(255), nullable=False, unique=True), + sa.Column("created_at", sa.DateTime, default=sa.func.now()), + sa.Column("updated_at", sa.DateTime, onupdate=sa.func.utc_timestamp()), + ) + + +def downgrade(): + op.drop_table("scan_types") diff --git a/api/models/ScanType.py b/api/models/ScanType.py new file mode 100644 index 00000000..420c27ce --- /dev/null +++ b/api/models/ScanType.py @@ -0,0 +1,35 @@ +import datetime +import uuid + +from sqlalchemy import DateTime, Column, String +from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy.orm import validates + + +from models import Base + + +class ScanType(Base): + __tablename__ = "scan_types" + + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + name = Column(String, nullable=False, index=False, unique=True) + created_at = Column( + DateTime, + index=False, + unique=False, + nullable=False, + default=datetime.datetime.utcnow, + ) + updated_at = Column( + DateTime, + index=False, + unique=False, + nullable=True, + onupdate=datetime.datetime.utcnow, + ) + + @validates("name") + def validate_name(self, _key, value): + assert value != "" + return value diff --git a/api/tests/models/test_ScanType.py b/api/tests/models/test_ScanType.py new file mode 100644 index 00000000..0753d1e6 --- /dev/null +++ b/api/tests/models/test_ScanType.py @@ -0,0 +1,49 @@ +import pytest + +from sqlalchemy.exc import IntegrityError + +from models.ScanType import ScanType + + +def test_scan_type_model(): + scan_type = ScanType(name="name") + assert scan_type.name == "name" + + +def test_scan_type_model_saved(assert_new_model_saved, session): + scan_type = ScanType(name="name") + session.add(scan_type) + session.commit() + assert scan_type.name == "name" + assert_new_model_saved(scan_type) + session.delete(scan_type) + session.commit() + + +def test_scan_type_empty_name_fails(session): + scan_type = ScanType() + session.add(scan_type) + with pytest.raises(IntegrityError): + session.commit() + session.rollback() + + +def test_scan_type_duplicate_name_fails(assert_new_model_saved, session): + scan_type = ScanType(name="name") + + session.add(scan_type) + session.commit() + + assert scan_type.name == "name" + assert_new_model_saved(scan_type) + + scan_type_two = ScanType(name="name") + + session.add(scan_type_two) + + with pytest.raises(IntegrityError): + session.commit() + + session.rollback() + session.delete(scan_type) + session.commit()