Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M2 4162 #880

Merged
merged 2 commits into from Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Pipfile
Expand Up @@ -83,6 +83,7 @@ cachetools = "==5.3.0"
pyld = "==2.0.3"
types-requests = "==2.31.0.10"
types-pytz = "==2023.3.1.1"
gevent = "~=23.9"

[requires]
python_version = "3.10"
365 changes: 224 additions & 141 deletions Pipfile.lock

Large diffs are not rendered by default.

28 changes: 19 additions & 9 deletions README.md
Expand Up @@ -20,7 +20,7 @@ And
- ✅ [The 12-Factor App](https://12factor.net)
- ✅ [Domain driven design](https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG)

</br>
<br/>

🔌 **Code quality tools:**
- ✅ [flake8](https://github.com/pycqa/flake8)
Expand All @@ -29,7 +29,7 @@ And
- ✅ [mypy](https://github.com/python/mypy)
- ✅ [pytest](https://github.com/pytest-dev/pytest)

</br>
<br/>

## ✋ <span style="color:#9DB7FF">Mandatory steps</span>

Expand All @@ -51,7 +51,7 @@ git clone git@github.com:ChildMindInstitute/mindlogger-backend-refactor.git
#### 2.1 Description 📜
| Key | Default value | Description |
| --- |------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| PYTHONPATH | src/ | This variable makes all folders inside `src/` reachable in a runtime. </br> ***NOTE:*** You don't need to do this if you use Docker as far as it is hardcoded in `Dockerfile` |
| PYTHONPATH | src/ | This variable makes all folders inside `src/` reachable in a runtime. <br/> ***NOTE:*** You don't need to do this if you use Docker as far as it is hardcoded in `Dockerfile` |
| DATABASE__HOST | postgres | Database Host |
| DATABASE__USER | postgres | User name for Postgresql Database user |
| DATABASE__PASSWORD | postgres | Password for Postgresql Database user |
Expand Down Expand Up @@ -82,7 +82,7 @@ cp .env.default .env
```


</br>
<br/>


## 👨‍🦯 <span style="color:#9DB7FF">Local development</span>
Expand Down Expand Up @@ -115,7 +115,7 @@ pipenv shell
pipenv sync --dev
```

</br>
<br/>

> 🛑 **NOTE:** if you don't use `pipenv` for some reason remember that you will not have automatically exported variables from your `.env` file.
>
Expand All @@ -136,7 +136,7 @@ set -o allexport; source .env; set +o allexport

> 🛑 **NOTE:** Please do not forget about environment variables! Now all environment variables for the Postgres Database which runs in docker are already passed to docker-compose.yaml from the .env file.

</br>
<br/>


### 3. Provide code quality ✨
Expand Down Expand Up @@ -177,7 +177,7 @@ P.S. You don't need to do this additional step if you run application via Docker
uvicorn src.main:app --proxy-headers --port {PORT} --reload
```

</br>
<br/>

### 5. Running Tests ▶️

Expand Down Expand Up @@ -216,8 +216,18 @@ psql# create user test;
# Set password for the user
psql# alter user test with password 'test';
```
</br>
</br>

#### Test coverage

To correctly calculate test coverage, you need to run the coverage with the `--concurrency=thread,gevent` parameter:

```bash
coverage run --concurrency=thread,gevent -m pytest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can it be async for concurrency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed to analyze asynchronous code. Details of the problem are described here:
nedbat/coveragepy#1082

coverage report -m
```

<br/>
<br/>

## 🐳 <span style="color:#9DB7FF">Docker development</span>

Expand Down
1 change: 0 additions & 1 deletion src/apps/activities/crud/reusable_item_choices.py
Expand Up @@ -39,7 +39,6 @@ async def get_item_templates(
async def get_item_templates_count(self, user_id_: uuid.UUID) -> int:
query: Query = select(count(ReusableItemChoiceSchema.id))
query = query.where(ReusableItemChoiceSchema.user_id == user_id_)
query = query.order_by(ReusableItemChoiceSchema.id)
db_result = await self._execute(query)

return db_result.scalars().first() or 0
Expand Down
11 changes: 6 additions & 5 deletions src/apps/activities/services/activity.py
Expand Up @@ -235,25 +235,26 @@ async def update_create(
role=Role.RESPONDENT,
)

respondents_with_indvdl_schdl = []
respondents_with_indvdl_schdl: list[uuid.UUID] = []
for respondent in respondents_in_applet:
respondent_uuid = uuid.UUID(f"{respondent}")
number_of_indvdl_events = await EventCRUD(
self.session
).count_individual_events_by_user(
applet_id=applet_id, user_id=uuid.UUID(respondent)
applet_id=applet_id, user_id=respondent_uuid
)
if number_of_indvdl_events > 0:
respondents_with_indvdl_schdl.append(respondent)
respondents_with_indvdl_schdl.append(respondent_uuid)

if respondents_with_indvdl_schdl:
for respondent in respondents_with_indvdl_schdl:
for respondent_uuid in respondents_with_indvdl_schdl:
await ScheduleService(
self.session
).create_default_schedules(
applet_id=applet_id,
activity_ids=list(new_activities),
is_activity=True,
respondent_id=uuid.UUID(respondent),
respondent_id=respondent_uuid,
)
else:
await ScheduleService(self.session).create_default_schedules(
Expand Down
22 changes: 22 additions & 0 deletions src/apps/activities/tests/test_reusable_items.py
Expand Up @@ -11,6 +11,7 @@ class TestReusableItem(BaseTest):
create_url = "activities/item_choices"
update_url = "activities/item_choices"
delete_url = "activities/item_choices/{id}"
retrieve_url = "activities/item_choices"

@rollback
async def test_create_item_choice(self):
Expand Down Expand Up @@ -111,3 +112,24 @@ async def test_create_item_choice_with_long_int_value(self):

res_data = response.json()
assert response.status_code == 422, res_data

@rollback
async def test_retrieve_item_choice(self):
await self.client.login(
self.login_url, "tom@mindlogger.com", "Test1234!"
)
create_data = dict(
token_name="Average age 3",
token_value="21",
input_type="radiobutton",
)

response = await self.client.post(self.create_url, data=create_data)
created_data = response.json()["result"]
assert response.status_code == 201, response.json()
assert response.json()["result"]["id"]

response = await self.client.get(self.retrieve_url)
assert response.status_code == 200, response.json()
assert response.json()["count"] == 1
assert response.json()["result"][0] == created_data
9 changes: 5 additions & 4 deletions src/apps/activity_flows/service/flow.py
Expand Up @@ -177,23 +177,24 @@ async def update_create(

respondents_with_indvdl_schdl = []
for respondent in respondents_in_applet:
respondent_uuid = uuid.UUID(f"{respondent}")
number_of_indvdl_events = await EventCRUD(
self.session
).count_individual_events_by_user(
applet_id=applet_id, user_id=uuid.UUID(respondent)
applet_id=applet_id, user_id=respondent_uuid
)
if number_of_indvdl_events > 0:
respondents_with_indvdl_schdl.append(respondent)
respondents_with_indvdl_schdl.append(respondent_uuid)

if respondents_with_indvdl_schdl:
for respondent in respondents_with_indvdl_schdl:
for respondent_uuid in respondents_with_indvdl_schdl:
await ScheduleService(
self.session
).create_default_schedules(
applet_id=applet_id,
activity_ids=list(new_flows),
is_activity=False,
respondent_id=uuid.UUID(respondent),
respondent_id=respondent_uuid,
)
else:
await ScheduleService(self.session).create_default_schedules(
Expand Down