fix(test): fixed tests for local usage and documentation in report.md

This commit is contained in:
ribardej
2025-11-06 12:28:42 +01:00
parent 6c8d2202b5
commit a214e2cd8b
2 changed files with 88 additions and 47 deletions

View File

@@ -101,17 +101,26 @@ async def test_e2e_transaction_workflow(fastapi_app, test_user):
async def test_register_then_login_and_fetch_me(fastapi_app): async def test_register_then_login_and_fetch_me(fastapi_app):
transport = ASGITransport(app=fastapi_app, raise_app_exceptions=True) transport = ASGITransport(app=fastapi_app, raise_app_exceptions=True)
async with AsyncClient(transport=transport, base_url="http://testserver") as ac: async with AsyncClient(transport=transport, base_url="http://testserver") as ac:
email = "newuser@example.com" # Use unique email to avoid duplicates across runs
suffix = uuid.uuid4().hex[:8]
email = f"newuser_{suffix}@example.com"
password = "StrongPassw0rd!" password = "StrongPassw0rd!"
reg = await ac.post("/auth/register", json={"email": email, "password": password}) reg = await ac.post("/auth/register", json={"email": email, "password": password})
assert reg.status_code in (status.HTTP_201_CREATED, status.HTTP_200_OK) assert reg.status_code in (status.HTTP_201_CREATED, status.HTTP_200_OK)
login = await ac.post("/auth/jwt/login", data={"username": email, "password": password}) login = await ac.post("/auth/jwt/login", data={"username": email, "password": password})
assert login.status_code == status.HTTP_200_OK assert login.status_code == status.HTTP_200_OK
token = login.json()["access_token"] token = login.json()["access_token"]
me = await ac.get("/users/me", headers={"Authorization": f"Bearer {token}"}) headers = {"Authorization": f"Bearer {token}"}
try:
me = await ac.get("/users/me", headers=headers)
assert me.status_code == status.HTTP_200_OK assert me.status_code == status.HTTP_200_OK
assert me.json()["email"] == email assert me.json()["email"] == email
finally:
# Cleanup: delete the created user so future runs wont conflict
d = await ac.delete("/users/me", headers=headers)
assert d.status_code == status.HTTP_204_NO_CONTENT
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -158,22 +167,44 @@ async def test_update_category_conflict_and_404(fastapi_app, test_user):
async def test_category_cross_user_isolation(fastapi_app): async def test_category_cross_user_isolation(fastapi_app):
transport = ASGITransport(app=fastapi_app) transport = ASGITransport(app=fastapi_app)
async with AsyncClient(transport=transport, base_url="http://testserver") as ac: async with AsyncClient(transport=transport, base_url="http://testserver") as ac:
# Generate unique emails for both users
sfx = uuid.uuid4().hex[:8]
u1 = {"email": f"u1_{sfx}@example.com", "password": "Aaaaaa1!"}
u2 = {"email": f"u2_{sfx}@example.com", "password": "Aaaaaa1!"}
# user1 # user1
u1 = {"email": "u1@example.com", "password": "Aaaaaa1!"}
assert (await ac.post("/auth/register", json=u1)).status_code in (200, 201) assert (await ac.post("/auth/register", json=u1)).status_code in (200, 201)
t1 = (await ac.post("/auth/jwt/login", data={"username": u1["email"], "password": u1["password"]})).json()["access_token"] t1 = (await ac.post("/auth/jwt/login", data={"username": u1["email"], "password": u1["password"]})).json()["access_token"]
h1 = {"Authorization": f"Bearer {t1}"}
# user1 creates a category # user1 creates a category
c = (await ac.post("/categories/create", json={"name": "Private"}, headers={"Authorization": f"Bearer {t1}"})).json() c = (await ac.post("/categories/create", json={"name": "Private"}, headers=h1)).json()
cat_id = c["id"]
# user2 # user2
u2 = {"email": "u2@example.com", "password": "Aaaaaa1!"}
assert (await ac.post("/auth/register", json=u2)).status_code in (200, 201) assert (await ac.post("/auth/register", json=u2)).status_code in (200, 201)
t2 = (await ac.post("/auth/jwt/login", data={"username": u2["email"], "password": u2["password"]})).json()["access_token"] t2 = (await ac.post("/auth/jwt/login", data={"username": u2["email"], "password": u2["password"]})).json()["access_token"]
h2 = {"Authorization": f"Bearer {t2}"}
try:
# user2 cannot read/delete user1's category # user2 cannot read/delete user1's category
g = await ac.get(f"/categories/{c['id']}", headers={"Authorization": f"Bearer {t2}"}) g = await ac.get(f"/categories/{cat_id}", headers=h2)
assert g.status_code == status.HTTP_404_NOT_FOUND assert g.status_code == status.HTTP_404_NOT_FOUND
d = await ac.delete(f"/categories/{c['id']}", headers={"Authorization": f"Bearer {t2}"}) d = await ac.delete(f"/categories/{cat_id}", headers=h2)
assert d.status_code == status.HTTP_404_NOT_FOUND assert d.status_code == status.HTTP_404_NOT_FOUND
finally:
# Cleanup: remove the created category as its owner
try:
_ = await ac.delete(f"/categories/{cat_id}", headers=h1)
except Exception:
pass
# Cleanup: delete both users to avoid email conflicts later
try:
_ = await ac.delete("/users/me", headers=h1)
except Exception:
pass
try:
_ = await ac.delete("/users/me", headers=h2)
except Exception:
pass

View File

@@ -14,7 +14,7 @@
- 289229, Lukáš Trkan, lukastrkan - 289229, Lukáš Trkan, lukastrkan
- 289258, Dejan Ribarovski, derib2613, ribardej - 289258, Dejan Ribarovski, derib2613, ribardej
**Brief Description**: (něco spíš jako abstract, introuction, story behind) **Brief Description**:
Our application is a finance tracker, so a person can easily track his cash flow Our application is a finance tracker, so a person can easily track his cash flow
through multiple bank accounts. Person can label transactions with custom categories through multiple bank accounts. Person can label transactions with custom categories
and later filter by them. and later filter by them.
@@ -34,9 +34,16 @@ flowchart LR
client[Client/Frontend] <--> svc[Backend API] client[Client/Frontend] <--> svc[Backend API]
svc --> proc_queue svc --> proc_queue
svc <--> db[(Database)] svc <--> db[(Database)]
svc <--> cache[(Cache)]
``` ```
The workflow works in the following way:
- Client connects to the frontend. After login, frontend automatically fetches the stored transactions from
the database via the backend API
- When the client opts for fetching new transactions via the Bank API, the backend delegates the task
to a background worker service via the Message queue.
- After successful load, these transactions are stored to the database and displayed to the client
- There is also a Task planner, that executes periodic tasks, like fetching new transactions automatically from the Bank API
### Components ### Components
- Frontend (frontend/): React + TypeScript app built with Vite. Talks to the backend via REST, handles login/registration, shows latest transactions, filtering, and allows adding transactions. - Frontend (frontend/): React + TypeScript app built with Vite. Talks to the backend via REST, handles login/registration, shows latest transactions, filtering, and allows adding transactions.
@@ -249,28 +256,28 @@ open http://localhost:5173
``` ```
## Testing Instructions ## Testing Instructions
The tests are located in 7project/backend/tests directory
If you want to test locally, you have to have the DB running locally as well (start the docker compose in /backend).
```bash
cd backend
```
### Unit Tests ### Unit Tests
There are only 3 basic unit tests, since our services logic is very simple
```bash ```bash
# Commands to run unit tests pytest tests/test_unit_user_service.py
# For example:
# go test ./...
# npm test
``` ```
### Integration Tests ### Integration Tests
There are 11 basic unit tests, testing the individual backend API logic
```bash ```bash
# Commands to run integration tests pytest tests/test_integration_app.py
# Any setup required for integration tests
``` ```
### End-to-End Tests ### End-to-End Tests
There are 7 e2e tests testing more complex app logic
```bash ```bash
# Commands to run e2e tests pytest tests/test_e2e.py
# How to set up test environment
``` ```
## Usage Examples ## Usage Examples
@@ -347,22 +354,22 @@ curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8000/authenticated-route
--- ---
## Self-Assessment Table ## Progress Table
> Be honest and detailed in your assessments. > Be honest and detailed in your assessments.
> This information is used for individual grading. > This information is used for individual grading.
> Link to the specific commit on GitHub for each contribution. > Link to the specific commit on GitHub for each contribution.
| Task/Component | Assigned To | Status | Time Spent | Difficulty | Notes | | Task/Component | Assigned To | Status | Time Spent | Difficulty | Notes |
|-----------------------------------------------------------------------|-------------| ------------- |----------------|------------| ----------- | |-----------------------------------------------------------------------|-------------| ------------- |------------|------------| ----------- |
| [Project Setup & Repository](https://github.com/dat515-2025/Group-8#) | Lukas | ✅ Complete | [X hours] | Medium | [Any notes] | | [Project Setup & Repository](https://github.com/dat515-2025/Group-8#) | Lukas | ✅ Complete | [X hours] | Medium | [Any notes] |
| [Design Document](https://github.com/dat515-2025/Group-8/blob/main/6design/design.md) | Both | ✅ Complete | 2 Hours | Easy | [Any notes] | | [Design Document](https://github.com/dat515-2025/Group-8/blob/main/6design/design.md) | Both | ✅ Complete | 4 Hours | Easy | [Any notes] |
| [Backend API Development](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/api) | Dejan | 🔄 In Progress | 10 hours | Medium | [Any notes] | | [Backend API Development](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/api) | Dejan | ✅ Complete | 12 hours | Medium | [Any notes] |
| [Database Setup & Models](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/models) | Lukas | 🔄 In Progress | [X hours] | Medium | [Any notes] | | [Database Setup & Models](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/models) | Lukas | 🔄 In Progress | [X hours] | Medium | [Any notes] |
| [Frontend Development](https://github.com/dat515-2025/Group-8/tree/main/7project/frontend) | Dejan | 🔄 In Progress | 7 hours so far | Medium | [Any notes] | | [Frontend Development](https://github.com/dat515-2025/Group-8/tree/main/7project/frontend) | Dejan | ✅ Complete | 17 hours | Medium | [Any notes] |
| [Docker Configuration](https://github.com/dat515-2025/Group-8/blob/main/7project/compose.yml) | Lukas | ✅ Complete | [X hours] | Easy | [Any notes] | | [Docker Configuration](https://github.com/dat515-2025/Group-8/blob/main/7project/compose.yml) | Lukas | ✅ Complete | [X hours] | Easy | [Any notes] |
| [Cloud Deployment](https://github.com/dat515-2025/Group-8/blob/main/7project/deployment/app-demo-deployment.yaml) | Lukas | ✅ Complete | [X hours] | Hard | [Any notes] | | [Cloud Deployment](https://github.com/dat515-2025/Group-8/blob/main/7project/deployment/app-demo-deployment.yaml) | Lukas | ✅ Complete | [X hours] | Hard | [Any notes] |
| [Testing Implementation](https://github.com/dat515-2025/group-name) | Dejan | 🔄 In Progress | [X hours] | Medium | [Any notes] | | [Testing Implementation](https://github.com/dat515-2025/group-name) | Dejan | ✅ Complete | 16 hours | Medium | [Any notes] |
| [Documentation](https://github.com/dat515-2025/group-name) | Both | 🔄 In Progress | [X hours] | Easy | [Any notes] | | [Documentation](https://github.com/dat515-2025/group-name) | Both | 🔄 In Progress | [X hours] | Easy | [Any notes] |
| [Presentation Video](https://github.com/dat515-2025/group-name) | Both | ❌ Not Started | [X hours] | Medium | [Any notes] | | [Presentation Video](https://github.com/dat515-2025/group-name) | Both | ❌ Not Started | [X hours] | Medium | [Any notes] |
@@ -386,14 +393,17 @@ curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8000/authenticated-route
### Dejan ### Dejan
| Date | Activity | Hours | Description | | Date | Activity | Hours | Description |
|-----------------|----------------------|--------|----------------------------------------------------------------------------------| |-----------------|----------------------|--------|---------------------------------------------------------------|
| 25.9. | Design | 2 | 6design | | 25.9. | Design | 2 | 6design |
| 9.10 to 11.10. | Backend APIs | 10 | Implemented Backend APIs | | 9.10 to 11.10. | Backend APIs | 12 | Implemented Backend APIs |
| 13.10 to 15.10. | Frontend Development | 7 | Created user interface mockups | | 13.10 to 15.10. | Frontend Development | 8 | Created user interface mockups |
| Continually | Documantation | 5 | Documenting the dev process | | Continually | Documentation | 6 | Documenting the dev process |
| 21.10 to 23.10 | Tests, forntend | 10 | Test basics, balance charts, and frontend improvement | | 21.10 to 23.10 | Tests, frontend | 10 | Test basics, balance charts, and frontend improvement |
| 28.10 to 30.10 | Tests, forntend | 7 | Tests improvement with test database setup, UI fix and exchange rate integration | | 28.10 to 30.10 | CI | 6 | Integrated tests with test database setup on github workflows |
| **Total** | | **41** | | | 28.10 to 30.10 | Frontend | 7 | UI improvements and exchange rate API integration |
| 4.11 to 6.11 | Tests | 6 | Test fixes improvement, more integration and e2e |
| 4.11 to 6.11 | Frontend | 6 | Fixes, Improved UI, added support for mobile devices |
| **Total** | | **63** | |
### Group Total: [XXX.X] hours ### Group Total: [XXX.X] hours