diff --git a/alembic/versions/02ac8bdcf16f_update_portfolios_defense_component_.py b/alembic/versions/02ac8bdcf16f_update_portfolios_defense_component_.py new file mode 100644 index 00000000..8d202c57 --- /dev/null +++ b/alembic/versions/02ac8bdcf16f_update_portfolios_defense_component_.py @@ -0,0 +1,36 @@ +"""update portfolios defense component column type + +Revision ID: 02ac8bdcf16f +Revises: 08f2a640e9c2 +Create Date: 2019-12-26 16:10:54.366461 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '02ac8bdcf16f' # pragma: allowlist secret +down_revision = '08f2a640e9c2' # pragma: allowlist secret +branch_labels = None +depends_on = None + + +def upgrade(): + ### commands auto generated by Alembic - please adjust! ### + op.alter_column('portfolios', 'defense_component', + type_=postgresql.ARRAY(sa.VARCHAR()), + existing_type=sa.VARCHAR(), + postgresql_using="string_to_array(defense_component, ',')::character varying[]", + nullable=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('portfolios', 'defense_component', + type_=sa.VARCHAR(), + existing_type=postgresql.ARRAY(sa.VARCHAR()), + postgresql_using="defense_component[1]::character varying", + nullable=False) + # ### end Alembic commands ### diff --git a/atst/models/portfolio.py b/atst/models/portfolio.py index 8cfc35d6..0e48745b 100644 --- a/atst/models/portfolio.py +++ b/atst/models/portfolio.py @@ -1,5 +1,6 @@ from sqlalchemy import Column, String from sqlalchemy.orm import relationship +from sqlalchemy.types import ARRAY from itertools import chain from atst.models.base import Base @@ -20,7 +21,7 @@ class Portfolio( name = Column(String, nullable=False) description = Column(String) defense_component = Column( - String, nullable=False + ARRAY(String), nullable=False ) # Department of Defense Component applications = relationship( diff --git a/script/seed_sample.py b/script/seed_sample.py index 9f64f049..47b7efb9 100644 --- a/script/seed_sample.py +++ b/script/seed_sample.py @@ -34,7 +34,7 @@ from atst.routes.dev import _DEV_USERS as DEV_USERS from atst.utils import pick from tests.factories import ( - random_service_branch, + random_defense_component, TaskOrderFactory, CLINFactory, AttachmentFactory, @@ -308,7 +308,7 @@ def create_demo_portfolio(name, data): portfolio = Portfolios.create( user=portfolio_owner, - portfolio_attrs={"name": name, "defense_component": random_service_branch()}, + portfolio_attrs={"name": name, "defense_component": random_defense_component()}, ) add_task_orders_to_portfolio(portfolio) @@ -336,7 +336,7 @@ def seed_db(): user=amanda, portfolio_attrs={ "name": "TIE Interceptor", - "defense_component": random_service_branch(), + "defense_component": random_defense_component(), }, ) add_task_orders_to_portfolio(tie_interceptor) @@ -347,7 +347,7 @@ def seed_db(): user=amanda, portfolio_attrs={ "name": "TIE Fighter", - "defense_component": random_service_branch(), + "defense_component": random_defense_component(), }, ) add_task_orders_to_portfolio(tie_fighter) @@ -363,7 +363,7 @@ def seed_db(): user=user, portfolio_attrs={ "name": ship, - "defense_component": random_service_branch(), + "defense_component": random_defense_component(), }, ) add_task_orders_to_portfolio(portfolio) diff --git a/templates/portfolios/admin.html b/templates/portfolios/admin.html index d1e6e353..89f905b0 100644 --- a/templates/portfolios/admin.html +++ b/templates/portfolios/admin.html @@ -41,9 +41,13 @@
-
{{ "forms.task_order.defense_component_label" | translate }}
+
{{ "portfolios.admin.defense_component_label" | translate }}
{% if portfolio.defense_component %} -
{{ portfolio.defense_component }}
+
+ {% for component in portfolio.defense_component %} + {{ "forms.portfolio.defense_component.choices.%s" | format(component) | translate }}
+ {% endfor %} +
{% else %}
{{ "fragments.portfolio_admin.none" | translate }}
{% endif %} diff --git a/tests/factories.py b/tests/factories.py index ee4159f6..8ed74dd0 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -21,6 +21,10 @@ def random_service_branch(): return random_choice(data.SERVICE_BRANCHES) +def random_defense_component(): + return [random_choice(data.SERVICE_BRANCHES)] + + def random_dod_id(): return "".join(random.choices(string.digits, k=10)) @@ -104,7 +108,7 @@ class PortfolioFactory(Base): model = Portfolio name = factory.Faker("domain_word") - defense_component = factory.LazyFunction(random_service_branch) + defense_component = factory.LazyFunction(random_defense_component) description = factory.Faker("sentence") @classmethod diff --git a/tests/routes/portfolios/test_index.py b/tests/routes/portfolios/test_index.py index 489f73b2..f15f4149 100644 --- a/tests/routes/portfolios/test_index.py +++ b/tests/routes/portfolios/test_index.py @@ -34,7 +34,7 @@ def test_create_portfolio_success(client, user_session): data={ "name": "My project name", "description": "My project description", - "defense_component": "army", + "defense_component": ["army"], }, ) diff --git a/translations.yaml b/translations.yaml index 8e1081cc..5f00a464 100644 --- a/translations.yaml +++ b/translations.yaml @@ -310,6 +310,7 @@ portfolios: alert_header: Are you sure you want to delete this member? alert_message: 'The member will be removed from the portfolio, but their log history will be retained.' alert_title: Warning! You are about to delete a member from the portfolio. + defense_component_label: Department of Defense Component no_members: There are currently no members in this portfolio. permissions_info: Learn more about these permissions portfolio_members_subheading: These members have different levels of access to the portfolio.