Skip to content

Commit

Permalink
CRM457-390 - Add GET param (#55)
Browse files Browse the repository at this point in the history
## Description of change

- Update documentation to cover Auth bits that were missed
- Add Param to select specific app version
- Update relevant methods and tests

## Link to relevant ticket

[CRM457-390](https://dsdmoj.atlassian.net/browse/CRM457-390)

## Notes for reviewer

## Screenshots of changes (if applicable)

### Before changes:

### After changes:

## How to manually test the feature

[CRM457-390]:
https://dsdmoj.atlassian.net/browse/CRM457-390?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
pking-moj authored Jan 10, 2024
1 parent c73d816 commit b6fc297
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ POSTGRES_USERNAME=
POSTGRES_PASSWORD=
POSTGRES_HOSTNAME=localhost
POSTGRES_NAME=laa_crime_application_store
NSM_CASEWORKER_AUTH_ID=secret_auth_key
NSM_CASEWORKER_URL=http://localhost:3000
APP_CLIENT_ID=
TENANT_ID=
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# laa-crime-application-store

LAA Crime Application Store is a service to provide the ability to store and version crime applications from CRM forms.
LAA Crime Application Store is a service to provide the ability to store and version crime applications from CRM forms.

## Setting up the service

Expand Down Expand Up @@ -44,10 +44,21 @@ pipenv run uvicorn laa_crime_application_store_app.main:app --reload
```
The application will reload on code changes to save on rebuild times

### Running locally with Docker
#### Authenticating Requests

This application uses [Entra ID](https://www.microsoft.com/en-gb/security/business/identity-access/microsoft-entra-id#overview)
to authenticate API requests through the use of the [fastapi-azure-auth](https://github.com/Intility/fastapi-azure-auth). To be able to authenticate
requests you will need to setup and add your application within Entra ID and add the following environment variables
```
APP_CLIENT_ID={uuid of the application created}
TENANT_ID={uuid of the tentant that the application was created in}
```
Once added, calls to the API will require a [bearer token requested from the same app/tenant id within the header](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow#use-a-token).

#### Running locally with Docker

To run via a docker container:
1. Perform the docker build with:
1. Perform the docker build with:

`docker-compose build app`
2. You can optionally set build arguments by adding:
Expand All @@ -68,7 +79,8 @@ pipenv run pytest --cov-report term --cov=laa_crime_application_store_app tests/
#### API Tests
API testing is done using the Postman tooling. This can be downloaded from [the Postman website()
and a free account created. Once this is done you can import the collections and environments found in the postman
folder to begin testing.
folder to begin testing. You will need to get a secret token from Entra ID from the Tenant and Application ID as setup
above to be able to authenticate requests.

### Running linters

Expand All @@ -77,4 +89,4 @@ Running linters can be done using the following command from the root of the pro
pipenv run black .
pipenv run isort .
pipenv run flake8
```
```
7 changes: 5 additions & 2 deletions laa_crime_application_store_app/routers/v1/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ async def get_applications(
@router.get("/application/{app_id}", response_model=App)
@auth_logger
async def get_application(
request: Request, app_id: UUID | None = None, db: Session = Depends(get_db)
request: Request,
app_id: UUID | None = None,
app_version: int | None = None,
db: Session = Depends(get_db),
):
logger.info("GETTING_APPLICATION", application_id=app_id)
application = ApplicationService().get_application(db, app_id)
application = ApplicationService().get_application(db, app_id, app_version)

if application is None:
return Response(status_code=400)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,24 @@

class ApplicationService:
@staticmethod
def get_application(db: Session, app_id: UUID):
def get_application(db: Session, app_id: UUID, app_version: int | None):
application = ApplicationService.__get_application_by_id(db, app_id)

if application is None:
logger.info("APPLICATION_NOT_FOUND", application_id=app_id)
return None

version = application.current_version if app_version is None else app_version

application_version = ApplicationService.__get_application_version(
db, app_id, application.current_version
db, app_id, version
)

if application_version is None:
logger.info(
"APPLICATION_VERSION_NOT_FOUND",
application_id=app_id,
version=application.current_version,
version=version,
)
return None

Expand Down
18 changes: 15 additions & 3 deletions postman/collections/Application.postman_collection.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions tests/routers/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def seed_application(dbsession):
app_id = uuid.uuid4()
application = Application(
id=app_id,
current_version=1,
current_version=2,
application_state="submitted",
application_risk="low",
application_type="crm7",
Expand All @@ -101,6 +101,12 @@ def seed_application(dbsession):
json_schema_version=1,
application={"id": 1},
)
dbsession.add_all([application, version])
version_2 = ApplicationVersion(
application_id=app_id,
version=2,
json_schema_version=1,
application={"id": 2},
)
dbsession.add_all([application, version, version_2])
dbsession.commit()
return app_id
26 changes: 20 additions & 6 deletions tests/routers/v1/application_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ def test_data_returns_200(client: TestClient, seed_application):
assert response.status_code == 200


def test_data_selected_version_returns_200(client: TestClient, seed_application):
response = client.get(
f"/v1/application/{seed_application}", params={"app_version": 2}
)
assert response.status_code == 200


def test_data_selected_version_returns_400(client: TestClient, seed_application):
response = client.get(
f"/v1/application/{seed_application}", params={"app_version": 3}
)
assert response.status_code == 400


@patch("laa_crime_application_store_app.internal.notifier.Notifier.notify")
def test_post_application_returns_200(
mock_notify, client: TestClient, dbsession: Session
Expand Down Expand Up @@ -147,9 +161,9 @@ def test_put_application_create_a_new_version(
"application": {"id": 10, "plea": "guilty"},
},
)
assert dbsession.query(ApplicationVersion).count() == 2
assert dbsession.query(ApplicationVersion).count() == 3
application = dbsession.query(Application).first()
latest_version = dbsession.query(ApplicationVersion).filter_by(version=2).first()
latest_version = dbsession.query(ApplicationVersion).filter_by(version=3).first()
assert latest_version.application == {"id": 10, "plea": "guilty"}
assert (datetime.now() - application.updated_at) < timedelta(seconds=3)

Expand Down Expand Up @@ -194,12 +208,12 @@ def test_put_application_returns_409_when_invalid_data(
},
)

assert dbsession.query(ApplicationVersion).count() == 1
assert dbsession.query(ApplicationVersion).count() == 2
assert response.status_code == 409


@patch("laa_crime_application_store_app.internal.notifier.Notifier.notify")
def test_put_application_has_no_effect_if_data_is_unchnaged(
def test_put_application_has_no_effect_if_data_is_unchanged(
mock_notify, client: TestClient, dbsession: Session, seed_application
):
mock_notify.return_value = True
Expand All @@ -212,11 +226,11 @@ def test_put_application_has_no_effect_if_data_is_unchnaged(
"application_state": "submitted",
"application_risk": "low",
"application_type": "crm7",
"application": {"id": 1},
"application": {"id": 2},
},
)

assert dbsession.query(ApplicationVersion).count() == 1
assert dbsession.query(ApplicationVersion).count() == 2
assert response.status_code == 201


Expand Down

0 comments on commit b6fc297

Please sign in to comment.