Skip to content

Commit

Permalink
Merge pull request #115 from eoyilmaz/74-remove-projectis_active-attr…
Browse files Browse the repository at this point in the history
…ibute

[#74] Removed `Project.active` attribute and the related column. The …
  • Loading branch information
eoyilmaz authored Nov 18, 2024
2 parents feef80f + 1729f32 commit d1e2f0c
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 27 deletions.
46 changes: 46 additions & 0 deletions alembic/versions/644f5251fc0d_remove_project_active_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Remove Project.active attribute
Revision ID: 644f5251fc0d
Revises: 5078390e5527
Create Date: 2024-11-18 12:47:09.673241
"""

from alembic import op

import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "644f5251fc0d"
down_revision = "5078390e5527"


def upgrade():
"""Upgrade the tables."""
# just remove the "active" column
with op.batch_alter_table("Projects", schema=None) as batch_op:
batch_op.drop_column("active")


def downgrade():
"""Downgrade the tables."""
with op.batch_alter_table("Projects", schema=None) as batch_op:
batch_op.add_column(sa.Column("active", sa.Boolean(), nullable=True))

# restore the value by checking the status
op.execute(
"""UPDATE "Projects" SET active = (
SELECT
(
CASE WHEN "Projects".status_id = (
SELECT
"Statuses".id
FROM "Statuses"
WHERE "Statuses".code = 'WIP'
)
THEN true ELSE false END
) as active
FROM "Projects"
)
"""
)
2 changes: 1 addition & 1 deletion src/stalker/db/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
logger: logging.Logger = log.get_logger(__name__)

# TODO: Try to get it from the API (it was not working inside a package before)
alembic_version: str = "5078390e5527"
alembic_version: str = "644f5251fc0d"


def setup(settings: Optional[Dict[str, Any]] = None) -> None:
Expand Down
12 changes: 5 additions & 7 deletions src/stalker/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
from sqlalchemy.orm import Mapped, mapped_column, relationship, validates

from stalker.db.declarative import Base
from stalker.db.session import DBSession
from stalker.log import get_logger
from stalker.models.entity import Entity
from stalker.models.mixins import CodeMixin, DateRangeMixin, ReferenceMixin, StatusMixin
from stalker.models.status import Status

if TYPE_CHECKING: # pragma: no cover
from stalker.models.asset import Asset
Expand Down Expand Up @@ -218,10 +220,6 @@ class Project(Entity, ReferenceMixin, StatusMixin, DateRangeMixin, CodeMixin):
"inherit_condition": project_id == Entity.entity_id,
}

# TODO: Remove this attribute, because we have the statuses to control if a project
# is active or not. #74
active: Mapped[Optional[bool]] = mapped_column(default=True)

clients = association_proxy(
"client_role", "client", creator=lambda n: ProjectClient(client=n)
)
Expand Down Expand Up @@ -352,8 +350,6 @@ def __init__(
self.fps = fps
self.is_stereoscopic = bool(is_stereoscopic)

self.active = True

def __eq__(self, other: Any) -> bool:
"""Check the equality.
Expand Down Expand Up @@ -559,7 +555,9 @@ def is_active(self) -> bool:
Returns:
bool: True if the project is active, False otherwise.
"""
return self.active
with DBSession.no_autoflush:
wip = Status.query.filter_by(code="WIP").first()
return self.status == wip

@property
def total_logged_seconds(self) -> int:
Expand Down
14 changes: 8 additions & 6 deletions src/stalker/models/studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from stalker.models.mixins import DateRangeMixin, WorkingHoursMixin
from stalker.models.project import Project
from stalker.models.schedulers import SchedulerBase
from stalker.models.status import Status


logger = log.get_logger(__name__)

Expand Down Expand Up @@ -389,9 +391,9 @@ def active_projects(self) -> List[Project]:
Returns:
List[Project]: List of active Project instances in this studio.
"""
# TODO: Filter through the status of the project as the active attribute is
# going to be removed with #74.
return Project.query.filter_by(active=True).all()
with DBSession.no_autoflush:
wip = Status.query.filter_by(code="WIP").first()
return Project.query.filter(Project.status == wip).all()

@property
def inactive_projects(self) -> List[Project]:
Expand All @@ -400,9 +402,9 @@ def inactive_projects(self) -> List[Project]:
Returns:
List[Project]: List of inactive Project instances in this studio.
"""
# TODO: Filter through the status of the project as the active attribute is
# going to be removed with #74.
return Project.query.filter_by(active=False).all()
with DBSession.no_autoflush:
wip = Status.query.filter_by(code="WIP").first()
return Project.query.filter(Project.status != wip).all()

@property
def departments(self) -> List[Department]:
Expand Down
36 changes: 24 additions & 12 deletions tests/models/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
Repository,
Sequence,
Shot,
Status,
StatusList,
Structure,
Task,
Expand Down Expand Up @@ -1421,11 +1422,31 @@ def test_to_tjp_is_working_as_expected(setup_project_db_test):
)


def test_active_attribute_is_true_by_default(setup_project_db_test):
"""active attribute is True by default."""
def test_project_instance_does_not_have_active_attribute(setup_project_db_test):
"""Project instances does not have active attribute."""
data = setup_project_db_test
new_project = Project(**data["kwargs"])
assert new_project.active is True
assert hasattr(new_project, "active") is False


@pytest.mark.parametrize(
"status, expected",
[
["RTS", False],
["WIP", True],
["CMPL", False],
],
)
def test_is_active_property_depends_on_the_status(
setup_project_db_test, status, expected
):
"""is_active property depends on the Project.status."""
data = setup_project_db_test
new_project = Project(**data["kwargs"])
status_ins = Status.query.filter_by(code=status).first()
assert status_ins is not None
new_project.status = status_ins
assert new_project.is_active is expected


def test_is_active_is_read_only(setup_project_db_test):
Expand All @@ -1445,15 +1466,6 @@ def test_is_active_is_read_only(setup_project_db_test):
assert str(cm.value) == error_message


def test_is_active_is_working_as_expected(setup_project_db_test):
"""is_active is working as expected."""
data = setup_project_db_test
data["test_project"].active = True
assert data["test_project"].is_active is True
data["test_project"].active = False
assert data["test_project"].is_active is False


def test_total_logged_seconds_attribute_is_read_only(setup_project_db_test):
"""total_logged_seconds attribute is a read-only attribute."""
data = setup_project_db_test
Expand Down
9 changes: 8 additions & 1 deletion tests/models/test_studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Repository,
SchedulerBase,
Shot,
Status,
Studio,
Task,
TaskJugglerScheduler,
Expand Down Expand Up @@ -46,6 +47,10 @@ def schedule(self):
def setup_studio_db_tests(setup_postgresql_db):
"""Set up the test for stalker.models.studio.Studio class."""
data = dict()

data["status_rts"] = Status.query.filter_by(code="RTS").first()
data["status_wip"] = Status.query.filter_by(code="WIP").first()

data["test_user1"] = User(
name="User 1", login="user1", email="user1@users.com", password="password"
)
Expand Down Expand Up @@ -80,18 +85,20 @@ def setup_studio_db_tests(setup_postgresql_db):
data["test_project1"] = Project(
name="Test Project 1", code="TP1", repository=data["test_repo"]
)
data["test_project1"].status = data["status_wip"]
DBSession.add(data["test_project1"])

data["test_project2"] = Project(
name="Test Project 2", code="TP2", repository=data["test_repo"]
)
data["test_project2"].status = data["status_wip"]
DBSession.add(data["test_project2"])

# an inactive project
data["test_project3"] = Project(
name="Test Project 3", code="TP3", repository=data["test_repo"]
)
data["test_project3"].active = False
data["test_project3"].status = data["status_rts"]
DBSession.save(data["test_project3"])

# create assets and shots
Expand Down

0 comments on commit d1e2f0c

Please sign in to comment.