Skip to content

Commit

Permalink
Merge pull request #209 from Police-Data-Accessibility-Project/dev
Browse files Browse the repository at this point in the history
Dev → Main March 2024
  • Loading branch information
mbodeantor authored Mar 13, 2024
2 parents e880a82 + 632a1ec commit fccf933
Show file tree
Hide file tree
Showing 58 changed files with 3,145 additions and 723 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/pull.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
uses: styfle/[email protected]
with:
access_token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
Expand All @@ -30,6 +30,8 @@ jobs:
- uses: psf/black@stable

test_api:
env:
SECRET_KEY: ${{ secrets.SECRET_KEY }}
name: Test API
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -127,4 +129,4 @@ jobs:
cache-dependency-path: 'client/package-lock.json'
- run: npm ci
- name: Build app
run: npm run build
run: npm run build
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ jobs:
- name: Run tests
env:
VUE_APP_PDAP_API_KEY: ${{ secrets.VUE_APP_PDAP_API_KEY }}

run: python regular_api_checks.py
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,24 @@ pip install -r requirements.txt

### 5. Add environment secrets

Either add a `.env` file to your local root directory or manually export these secrets: `DO_DATABASE_URL` and `VITE_VUE_APP_BASE_URL`.
Either add a `.env` file to your local root directory or manually export these secrets: `DO_DATABASE_URL` and `VITE_VUE_API_BASE_URL`.

Reach out to [email protected] or make noise in Discord if you'd like access to these keys.

```
# .env
DO_DATABASE_URL="postgres://data_sources_app:<password>@db-postgresql-nyc3-38355-do-user-8463429-0.c.db.ondigitalocean.com:25060/defaultdb"
VITE_VUE_APP_BASE_URL="http://localhost:5000"
VITE_VUE_API_BASE_URL="http://localhost:5000"
VITE_VUE_APP_BASE_URL="http://localhost:8888"
```

```
# shell
export DO_DATABASE_URL=postgres://data_sources_app:<password>@db-postgresql-nyc3-38355-do-user-8463429-0.c.db.ondigitalocean.com:25060/defaultdb
export VITE_VUE_APP_BASE_URL="http://localhost:5000"
export VITE_VUE_API_BASE_URL="http://localhost:5000"
export VITE_VUE_APP_BASE_URL="http://localhost:8888"
```

### 6. Allow your IP address
Expand Down Expand Up @@ -108,14 +110,18 @@ pip install pytest
pytest
```

## Linting
Linting is enforced with black on PR creation. You can use black to automatically reformat your files before commiting them, this will allow your PR to pass this check. Any files that require reformatting will be listed on any failed checks on the PR.
```
black app_test.py
```

## Other helpful commands for the client app
## Client App

A few things to know:

- We use Vue3. This allows for using either the options or composition APIs. Feel free to use whichever you are most fluent in.
- We use `pinia` for state management. This works much better with the composition API than with options, so it is recommended to use the composition API if you need data from one of the `pinia` stores.

### Compiles and minifies for production
```
Expand Down
41 changes: 39 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@
from flask_restful import Api
from flask_cors import CORS
from resources.User import User
from resources.Login import Login
from resources.RefreshSession import RefreshSession
from resources.ApiKey import ApiKey
from resources.RequestResetPassword import RequestResetPassword
from resources.ResetPassword import ResetPassword
from resources.QuickSearch import QuickSearch
from resources.DataSources import DataSources
from resources.DataSources import DataSourceById
from resources.DataSources import (
DataSources,
DataSourcesNeedsIdentification,
DataSourceById,
)
from resources.Agencies import Agencies
from resources.Archives import Archives
from resources.SearchTokens import SearchTokens
Expand All @@ -19,6 +27,29 @@
api.add_resource(
User, "/user", resource_class_kwargs={"psycopg2_connection": psycopg2_connection}
)
api.add_resource(
Login, "/login", resource_class_kwargs={"psycopg2_connection": psycopg2_connection}
)
api.add_resource(
RefreshSession,
"/refresh-session",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
ApiKey,
"/api_key",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
RequestResetPassword,
"/request-reset-password",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
ResetPassword,
"/reset-password",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
QuickSearch,
"/quick-search/<search>/<location>",
Expand All @@ -34,6 +65,11 @@
"/data-sources",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
DataSourcesNeedsIdentification,
"/data-sources-needs-identification",
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)
api.add_resource(
DataSourceById,
"/data-sources-by-id/<data_source_id>",
Expand All @@ -50,5 +86,6 @@
resource_class_kwargs={"psycopg2_connection": psycopg2_connection},
)


if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0")
109 changes: 105 additions & 4 deletions app_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,34 @@
)
from middleware.data_source_queries import (
data_sources_query,
data_sources_results,
approved_data_sources,
needs_identification_data_sources,
data_source_by_id_query,
data_source_by_id_results,
DATA_SOURCES_APPROVED_COLUMNS,
)

from middleware.user_queries import (
user_post_results,
user_check_email,
)
from middleware.login_queries import (
login_results,
create_session_token,
token_results,
is_admin,
)
from middleware.archives_queries import (
archives_get_results,
archives_get_query,
archives_put_broken_as_of_results,
archives_put_last_cached_results,
ARCHIVES_GET_COLUMNS,
)
from middleware.reset_token_queries import (
check_reset_token,
add_reset_token,
delete_reset_token,
)
from app_test_data import (
DATA_SOURCES_ROWS,
DATA_SOURCE_QUERY_RESULTS,
Expand Down Expand Up @@ -95,13 +110,19 @@ def test_unaltered_search_query(session):


def test_data_sources(session):
response = data_sources_results(conn=session)
response = approved_data_sources(conn=session)

assert response


def test_needs_identification(session):
response = needs_identification_data_sources(conn=session)

assert response


def test_data_sources_approved(session):
response = data_sources_results(conn=session)
response = approved_data_sources(conn=session)

assert (
len([d for d in response if "https://joinstatepolice.ny.gov/15-mile-run" in d])
Expand All @@ -125,6 +146,86 @@ def test_data_source_by_id_approved(session):
assert not response


def test_user_post_query(session):
curs = session.cursor()
user_post_results(curs, "unit_test", "unit_test")

email_check = curs.execute(
f"SELECT email FROM users WHERE email = 'unit_test'"
).fetchone()[0]

assert email_check == "unit_test"


def test_login_query(session):
curs = session.cursor()
user_data = login_results(curs, "test")

assert user_data["password_digest"]


def test_create_session_token_results(session):
curs = session.cursor()
token = create_session_token(curs, 1, "test")

curs = session.cursor()
new_token = token_results(curs, token)

assert new_token["email"]


def test_is_admin(session):
curs = session.cursor()
admin = is_admin(curs, "[email protected]")

assert admin


def test_not_admin(session):
curs = session.cursor()
admin = is_admin(curs, "test")

assert not admin


def test_user_check_email(session):
curs = session.cursor()
user_data = user_check_email(curs, "test")
print(user_data)

assert user_data["id"]


def test_check_reset_token(session):
curs = session.cursor()
reset_token = check_reset_token(curs, "test")
print(reset_token)

assert reset_token["id"]


def test_add_reset_token(session):
curs = session.cursor()
add_reset_token(curs, "unit_test", "unit_test")

email_check = curs.execute(
f"SELECT email FROM reset_tokens WHERE email = 'unit_test'"
).fetchone()[0]

assert email_check == "unit_test"


def test_delete_reset_token(session):
curs = session.cursor()
delete_reset_token(curs, "test", "test")

email_check = curs.execute(
f"SELECT email FROM reset_tokens WHERE email = 'test'"
).fetchone()

assert not email_check


def test_archives_get_results(session):
response = archives_get_results(conn=session)

Expand Down
51 changes: 51 additions & 0 deletions app_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,57 @@
"ok",
"approved",
),
(
"Media Bulletins for ",
"NULL",
"NULL",
"Media Bulletins",
"https://hollister.ca.gov/government/city-departments/police/",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
datetime.datetime(2023, 10, 26, 18, 20, 54, tzinfo=datetime.timezone.utc),
datetime.datetime(2023, 11, 8, 19, 5, 30, tzinfo=datetime.timezone.utc),
"NULL",
"NULL",
"NULL",
'{"id": "usrtLIB4Vr3jTH8Ro", "email": "[email protected]", "name": "Josh Chamberlain"}',
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"NULL",
"needs identification",
),
]
DATA_SOURCE_QUERY_RESULTS = [
(
Expand Down
Loading

0 comments on commit fccf933

Please sign in to comment.