Skip to content

Commit

Permalink
Merge branch 'develop' into bugfix/m2-6921-summary-completed-only-and…
Browse files Browse the repository at this point in the history
…-order

# Conflicts:
#	src/apps/answers/tests/test_answers.py
  • Loading branch information
iwankrshkin committed Jun 7, 2024
2 parents c5b4b7b + d5aeca7 commit 87ed950
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 2 deletions.
17 changes: 17 additions & 0 deletions copilot/environments/overrides/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Overriding Copilot generated CloudFormation templates with YAML Patches

The file `cfn.patches.yml` contains a list of YAML/JSON patches to apply to
your template before AWS Copilot deploys it.

To view examples and an explanation of how YAML patches work, check out the [documentation](https://aws.github.io/copilot-cli/docs/developing/overrides/yamlpatch).

Note only [`add`](https://www.rfc-editor.org/rfc/rfc6902#section-4.1),
[`remove`](https://www.rfc-editor.org/rfc/rfc6902#section-4.2), and
[`replace`](https://www.rfc-editor.org/rfc/rfc6902#section-4.3)
operations are supported by Copilot.
Patches are applied in the order specified in the file.

## Troubleshooting

* `copilot [noun] package` preview the transformed template by writing to stdout.
* `copilot [noun] package --diff` show the difference against the template deployed in your environment.
21 changes: 21 additions & 0 deletions copilot/environments/overrides/cfn.patches.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Delete the task role resource
# - op: remove
# path: /Resources/TaskRole

# Add a service connect alias
# - op: add
# path: /Resources/Service/Properties/ServiceConnectConfiguration/Services/0/ClientAliases/-
# value:
# Port: !Ref TargetPort
# DnsName: yamlpatchiscool

# Replace the task role in the task definition
# - op: replace
# path: /Resources/TaskDefinition/Properties/TaskRoleArn
# value: arn:aws:iam::123456789012:role/MyTaskRole

# Only 10 policies allowed per account. Hard limit.
# A shared policy is created via terraform
# https://github.com/aws/copilot-cli/issues/5743#issuecomment-2022882367
- op: remove
path: /Resources/LogResourcePolicy
15 changes: 13 additions & 2 deletions copilot/scripts/env-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
. ${SCRIPT_DIR}/funcs.sh

#copilot svc show -n mindlogger-backend --json | jq -r '.configurations[] | select( .environment | contains("pr-1393") ) | .environment'
#copilot svc show -n mindlogger-backend --json | jq -r '.configurations[] | select( .environment | contains("pr-1302") ) | .environment'

#Create environment only once
if copilot env ls -a "$APP_NAME" | grep -q "$ENV_NAME"; then
echo "Environment already exists"
exit 0
echo "Environment already exists, checking status"
ENV_CHECK=$(copilot svc show -n mindlogger-backend --json | jq -r ".configurations[] | select( .environment | contains(\"$ENV_NAME\") ) | .environment")

if [ -z "${ENV_CHECK}" ]; then
echo "Service does not exist, rebuilding..."
${SCRIPT_DIR}/env-stop.sh
else
echo "Status good, continuing..."
exit 0
fi
else
if [ "$ENV_NAME" == 'feature' ]; then
echo "You must create feature from bootstrap script locally"
Expand Down
18 changes: 18 additions & 0 deletions src/apps/answers/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ async def get_summary_activities(
self, applet_id: uuid.UUID, filters: SummaryActivityFilter
) -> list[SummaryActivity]:
assert self.user_id
applet = await AppletsCRUD(self.session).get_by_id(applet_id)
act_hst_crud = ActivityHistoriesCRUD(self.session)
activities = await act_hst_crud.get_last_histories_by_applet(applet_id=applet_id)
activity_ver_ids = [activity.id_version for activity in activities]
Expand All @@ -1047,11 +1048,21 @@ async def get_summary_activities(
submitted_activities[activity_id] = max(submit_date, date) if date else submit_date
submitted_activities[activity_history_id] = submit_date

current_activity_histories = await act_hst_crud.retrieve_by_applet_version(f"{applet.id}_{applet.version}")
current_activities_map = {str(ah.id): ah for ah in current_activity_histories}
results = []
for activity in activities:
activity_history_answer_date = submitted_activities.get(
activity.id_version, submitted_activities.get(str(activity.id))
)
has_answer = bool(activity_history_answer_date)
if not has_answer:
activity_curr = current_activities_map.get(str(activity.id))
if not activity_curr:
continue
elif activity_curr.is_reviewable:
continue

results.append(
SummaryActivity(
id=activity.id,
Expand All @@ -1067,6 +1078,7 @@ async def get_summary_activity_flows(
self, applet_id: uuid.UUID, target_subject_id: uuid.UUID | None
) -> list[SummaryActivityFlow]:
assert self.user_id
applet = await AppletsCRUD(self.session).get_by_id(applet_id)
flow_crud = FlowsHistoryCRUD(self.session)
answer_crud = AnswersCRUD(self.answer_session)
flow_history_ids_with_date = await answer_crud.get_submitted_flows_with_last_date(applet_id, target_subject_id)
Expand All @@ -1079,11 +1091,17 @@ async def get_summary_activity_flows(
submitted_activity_flows[flow_id] = max(submit_date, date) if date else submit_date
submitted_activity_flows[version_id] = submit_date

flow_histories = await flow_crud.retrieve_by_applet_version(f"{applet.id}_{applet.version}")
flow_histories_curr = [flow_h.id for flow_h in flow_histories]
results = []
for flow_history in sorted(activity_flow_histories, key=lambda x: x.order):
flow_history_answer_date = submitted_activity_flows.get(
flow_history.id_version, submitted_activity_flows.get(str(flow_history.id))
)
has_answer = bool(flow_history_answer_date)
if not has_answer and flow_history.id not in flow_histories_curr:
continue

results.append(
SummaryActivityFlow(
id=flow_history.id,
Expand Down
64 changes: 64 additions & 0 deletions src/apps/answers/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,67 @@ async def editor_user_reviewer_applet_one(user: UserSchema, session: AsyncSessio
applet_id = uuid.UUID("92917a56-d586-4613-b7aa-991f2c4b15b1")
srv = UserAppletAccessService(session, user.id, applet_id)
await srv.add_role(user.id, Role.EDITOR)


@pytest.fixture
async def applet__activity_turned_into_assessment(
session: AsyncSession, tom: User, applet_data: AppletCreate
) -> AppletFull:
"""
Applet with one Activity0 updated into applet with Activity0(is_reviewable=True) and Activity1
All activities has no answers
"""
srv = AppletService(session, tom.id)
applet = await srv.create(applet_data)
data = AppletUpdate(**applet.dict())

activity_new = data.activities[0].copy(deep=True)
activity_new.id = uuid.uuid4()
activity_new.key = uuid.uuid4()
for i in range(len(activity_new.items)):
activity_new.items[i].id = uuid.uuid4()
activity_new.name = "New activity"
data.activities.append(activity_new)

data.activities[0].is_reviewable = True
data.activities[0].name = "Reviewer assessment"
updated_applet = await srv.update(applet.id, data)
return updated_applet


@pytest.fixture
async def applet__deleted_activity_without_answers(
session: AsyncSession, tom: User, applet_data: AppletCreate
) -> AppletFull:
"""
Applet with one Activity0 updated into applet with Activity1 and deleted Activity1
All activities has no answers
"""
srv = AppletService(session, tom.id)
applet = await srv.create(applet_data)
data = AppletUpdate(**applet.dict())

activity_new = data.activities[0].copy(deep=True)
activity_new.id = uuid.uuid4()
activity_new.key = uuid.uuid4()
for i in range(len(activity_new.items)):
activity_new.items[i].id = uuid.uuid4()
activity_new.name = "New activity"
data.activities = [activity_new]
updated_applet = await srv.update(applet.id, data)
return updated_applet


@pytest.fixture
async def applet__deleted_flow_without_answers(
session: AsyncSession, tom: User, applet_with_flow: AppletFull
) -> AppletFull:
srv = AppletService(session, tom.id)
data = applet_with_flow.dict()
activity_flow = data["activity_flows"][0]
for i in range(len(activity_flow["items"])):
activity_flow["items"][i]["activity_key"] = data["activities"][0]["key"]
data["activity_flows"] = [activity_flow]
update_data = AppletUpdate(**data)
updated_applet = await srv.update(applet_with_flow.id, update_data)
return updated_applet
58 changes: 58 additions & 0 deletions src/apps/answers/tests/test_answers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,64 @@ async def test_flow_submission_not_completed(
assert set(data.keys()) == {"flow", "submission", "summary"}
assert data["submission"]["isCompleted"] is False

async def test_get_summary_activities_no_answer_no_empty_deleted_history(
self, client: TestClient, tom: User, applet: AppletFull
):
client.login(tom)

response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["name"] == applet.activities[0].name
assert response.json()["result"][0]["id"] == str(applet.activities[0].id)
assert not response.json()["result"][0]["isPerformanceTask"]
assert not response.json()["result"][0]["hasAnswer"]

async def test_activity_turned_into_assessment_not_included_in_list(
self, client: TestClient, tom: User, applet__activity_turned_into_assessment: AppletFull
):
client.login(tom)
response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet__activity_turned_into_assessment.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["id"] == str(applet__activity_turned_into_assessment.activities[1].id)

async def test_deleted_activity_without_answers_not_included_in_list(
self, client: TestClient, tom: User, applet__deleted_activity_without_answers: AppletFull
):
client.login(tom)
response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet__deleted_activity_without_answers.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["id"] == str(applet__deleted_activity_without_answers.activities[0].id)

async def test_deleted_flow_not_included_in_submission_list(
self, client: TestClient, tom: User, applet__deleted_flow_without_answers: AppletFull
):
client.login(tom)
url = self.summary_activity_flows_url.format(applet_id=applet__deleted_flow_without_answers.id)
response = await client.get(url)
assert response.status_code == 200
payload = response.json()
assert applet__deleted_flow_without_answers.activity_flows[0].id
assert payload["count"] == 1
assert payload["result"][0]["id"] == str(applet__deleted_flow_without_answers.activity_flows[0].id)

async def test_summary_flow_list_order_completed_submissions_only(
self, client, tom: User, applet_with_flow: AppletFull, tom_answer_activity_flow_not_completed
):
Expand Down

0 comments on commit 87ed950

Please sign in to comment.