From 1344dc4a96597182d69c378bbac038c8d0dc0ead Mon Sep 17 00:00:00 2001 From: Conor Brady Date: Mon, 19 Aug 2024 13:36:38 -0700 Subject: [PATCH] Update .gitignore and env example keys (#3856) - Use wildcard for ignoring all `.env` files in any directory - Remove unused example env keys - Add missing example env keys --- .gitignore | 6 +- api/app/.env.example | 3 - api/app/tests/conftest.py | 138 ++++++++++++++++++-------------------- web/.env.example | 9 ++- web/src/types/window.d.ts | 1 - web/src/utils/env.ts | 3 - 6 files changed, 69 insertions(+), 91 deletions(-) diff --git a/.gitignore b/.gitignore index 6408381c9..0379abe08 100644 --- a/.gitignore +++ b/.gitignore @@ -74,11 +74,7 @@ web/typings/ .yarn-integrity # dotenv environment variables file -api/app/.env -api/env/.env.test -api/app/.env.docker -web/.env -tileserv/tools/.env +**/.env # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/api/app/.env.example b/api/app/.env.example index ec235c083..2fbf297d4 100644 --- a/api/app/.env.example +++ b/api/app/.env.example @@ -7,9 +7,6 @@ WFWX_BASE_URL=https://somewhere WFWX_USER=someusear WFWX_SECRET=somesecret WFWX_MAX_PAGE_SIZE=1000 -BC_FIRE_WEATHER_USER=user -BC_FIRE_WEATHER_SECRET=password -BC_FIRE_WEATHER_FILTER_ID=0 KEYCLOAK_PUBLIC_KEY=thisispublickey KEYCLOAK_CLIENT=client # POSTGRES_WRITE_HOST=host.docker.internal diff --git a/api/app/tests/conftest.py b/api/app/tests/conftest.py index e026be3d5..fe069c8fd 100644 --- a/api/app/tests/conftest.py +++ b/api/app/tests/conftest.py @@ -1,4 +1,5 @@ -""" Global fixtures """ +"""Global fixtures""" + from datetime import timezone, datetime import logging from typing import Optional @@ -12,9 +13,13 @@ from app.utils.time import get_pst_tz, get_utc_now from app import auth from app.tests.common import ( - MockJWTDecode, default_aiobotocore_get_session, default_mock_requests_get, - default_mock_requests_post, default_mock_requests_session_get, - default_mock_requests_session_post) + MockJWTDecode, + default_aiobotocore_get_session, + default_mock_requests_get, + default_mock_requests_post, + default_mock_requests_session_get, + default_mock_requests_session_post, +) import app.db.database from app.weather_models import ModelEnum, ProjectionEnum import app.jobs.env_canada @@ -29,32 +34,26 @@ @pytest.fixture def anyio_backend(): - """ Specifies asyncio as the anyio backend """ - return 'asyncio' + """Specifies asyncio as the anyio backend""" + return "asyncio" @pytest.fixture(autouse=True) def mock_env(monkeypatch): - """ Automatically mock environment variable """ + """Automatically mock environment variable""" monkeypatch.setenv("BASE_URI", "https://python-test-base-uri") monkeypatch.setenv("USE_WFWX", "False") monkeypatch.setenv("WFWX_USER", "user") monkeypatch.setenv("WFWX_SECRET", "secret") - monkeypatch.setenv( - "WFWX_AUTH_URL", "https://wf1/pub/oauth2/v1/oauth/token") + monkeypatch.setenv("WFWX_AUTH_URL", "https://wf1/pub/oauth2/v1/oauth/token") monkeypatch.setenv("WFWX_BASE_URL", "https://wf1/wfwx") monkeypatch.setenv("WFWX_MAX_PAGE_SIZE", "1000") monkeypatch.setenv("KEYCLOAK_PUBLIC_KEY", "public_key") - monkeypatch.setenv("BC_FIRE_WEATHER_USER", "someuser") - monkeypatch.setenv("BC_FIRE_WEATHER_SECRET", "password") - monkeypatch.setenv("BC_FIRE_WEATHER_FILTER_ID", "1") - monkeypatch.setenv("OPENSHIFT_BASE_URI", - "https://console.pathfinder.gov.bc.ca:8443") + monkeypatch.setenv("OPENSHIFT_BASE_URI", "https://console.pathfinder.gov.bc.ca:8443") monkeypatch.setenv("PROJECT_NAMESPACE", "project_namespace") monkeypatch.setenv("STATUS_CHECKER_SECRET", "some_secret") monkeypatch.setenv("PATRONI_CLUSTER_NAME", "some_suffix") - monkeypatch.setenv("ROCKET_URL_POST_MESSAGE", - "https://rc-notifications-test.ca/api/v1/chat.postMessage") + monkeypatch.setenv("ROCKET_URL_POST_MESSAGE", "https://rc-notifications-test.ca/api/v1/chat.postMessage") monkeypatch.setenv("ROCKET_AUTH_TOKEN", "sometoken") monkeypatch.setenv("ROCKET_USER_ID", "someid") monkeypatch.setenv("ROCKET_CHANNEL", "#channel") @@ -67,55 +66,53 @@ def mock_env(monkeypatch): @pytest.fixture(autouse=True) def mock_aiobotocore_get_session(monkeypatch): - """ Patch the session by default """ - monkeypatch.setattr(app.utils.s3, 'get_session', default_aiobotocore_get_session) + """Patch the session by default""" + monkeypatch.setattr(app.utils.s3, "get_session", default_aiobotocore_get_session) @pytest.fixture(autouse=True) def mock_requests(monkeypatch): - """ Patch all calls to request.get by default. - """ - monkeypatch.setattr(requests, 'get', default_mock_requests_get) - monkeypatch.setattr(requests, 'post', default_mock_requests_post) + """Patch all calls to request.get by default.""" + monkeypatch.setattr(requests, "get", default_mock_requests_get) + monkeypatch.setattr(requests, "post", default_mock_requests_post) @pytest.fixture(autouse=True) def mock_redis(monkeypatch): - """ Patch redis by default """ - class MockRedis(): - """ mocked redis class """ + """Patch redis by default""" + + class MockRedis: + """mocked redis class""" def __init__(self) -> None: - """ Mock init """ + """Mock init""" def get(self, name): - """ mock get """ + """mock get""" return None - def set(self, - name, value, - ex=None, px=None, nx=False, xx=False, keepttl=False): - """ mock set """ + def set(self, name, value, ex=None, px=None, nx=False, xx=False, keepttl=False): + """mock set""" def delete(self, name): - """ mock delete """ + """mock delete""" def create_mock_redis(): return MockRedis() - monkeypatch.setattr(app.utils.redis, '_create_redis', create_mock_redis) + + monkeypatch.setattr(app.utils.redis, "_create_redis", create_mock_redis) @pytest.fixture(autouse=True) def mock_get_now(monkeypatch): - """ Patch all calls to app.util.time: get_utc_now and get_pst_now """ + """Patch all calls to app.util.time: get_utc_now and get_pst_now""" # May 21, 2020 timestamp = 1590076213962 / 1000 # The default value for WeatherDataRequest cannot be mocked out, as it # is declared prior to test mocks being loaded. We manipulate the class # directly in order to have the desire default be deterministic. - WeatherDataRequest.__fields__['time_of_interest'].default = datetime.fromtimestamp( - timestamp, tz=timezone.utc) + WeatherDataRequest.__fields__["time_of_interest"].default = datetime.fromtimestamp(timestamp, tz=timezone.utc) def mock_utc_now(): return datetime.fromtimestamp(timestamp, tz=timezone.utc) @@ -123,32 +120,29 @@ def mock_utc_now(): def mock_pst_now(): return datetime.fromtimestamp(timestamp, tz=get_pst_tz()) - monkeypatch.setattr(app.utils.time, '_get_utc_now', mock_utc_now) - monkeypatch.setattr(app.utils.time, '_get_pst_now', mock_pst_now) + monkeypatch.setattr(app.utils.time, "_get_utc_now", mock_utc_now) + monkeypatch.setattr(app.utils.time, "_get_pst_now", mock_pst_now) @pytest.fixture(autouse=True) def mock_get_pst_today_start_and_end(monkeypatch): - """ Patch all calls to app.util.time: get_pst_today_start_and_end """ + """Patch all calls to app.util.time: get_pst_today_start_and_end""" def mock_get_pst_today(): start = datetime.fromtimestamp(1623974400, tz=get_pst_tz()) end = datetime.fromtimestamp(1624060800, tz=get_pst_tz()) return start, end - monkeypatch.setattr(app.utils.time, 'get_pst_today_start_and_end', mock_get_pst_today) + monkeypatch.setattr(app.utils.time, "get_pst_today_start_and_end", mock_get_pst_today) @pytest.fixture(autouse=True) def mock_session(monkeypatch): - """ Ensure that all unit tests mock out the database session by default! """ - monkeypatch.setattr(app.db.database, '_get_write_session', MagicMock()) - monkeypatch.setattr(app.db.database, '_get_read_session', MagicMock()) + """Ensure that all unit tests mock out the database session by default!""" + monkeypatch.setattr(app.db.database, "_get_write_session", MagicMock()) + monkeypatch.setattr(app.db.database, "_get_read_session", MagicMock()) - prediction_model = PredictionModel(id=1, - abbreviation='GDPS', - projection='latlon.15x.15', - name='Global Deterministic Prediction System') + prediction_model = PredictionModel(id=1, abbreviation="GDPS", projection="latlon.15x.15", name="Global Deterministic Prediction System") def mock_get_prediction_model(session, model, projection) -> Optional[PredictionModel]: if model == ModelEnum.GDPS and projection == ProjectionEnum.LATLON_15X_15: @@ -156,74 +150,70 @@ def mock_get_prediction_model(session, model, projection) -> Optional[Prediction return None def mock_get_prediction_run(session, prediction_model_id: int, prediction_run_timestamp: datetime): - return PredictionModelRunTimestamp( - id=1, prediction_model_id=1, prediction_run_timestamp=get_utc_now(), - prediction_model=prediction_model, complete=True) + return PredictionModelRunTimestamp(id=1, prediction_model_id=1, prediction_run_timestamp=get_utc_now(), prediction_model=prediction_model, complete=True) - monkeypatch.setattr(app.jobs.env_canada, 'get_prediction_model', mock_get_prediction_model) - monkeypatch.setattr(app.weather_models.process_grib, 'get_prediction_model', mock_get_prediction_model) + monkeypatch.setattr(app.jobs.env_canada, "get_prediction_model", mock_get_prediction_model) + monkeypatch.setattr(app.weather_models.process_grib, "get_prediction_model", mock_get_prediction_model) - monkeypatch.setattr(app.jobs.env_canada, 'get_prediction_run', mock_get_prediction_run) + monkeypatch.setattr(app.jobs.env_canada, "get_prediction_run", mock_get_prediction_run) @pytest.fixture() def mock_env_with_use_wfwx(monkeypatch): - """ Set environment variable USE_WFWX to 'True' """ - monkeypatch.setenv("USE_WFWX", 'True') + """Set environment variable USE_WFWX to 'True'""" + monkeypatch.setenv("USE_WFWX", "True") @pytest.fixture() def mock_jwt_decode(monkeypatch): - """ Mock pyjwt's decode method """ + """Mock pyjwt's decode method""" def mock_function(*args, **kwargs): return MockJWTDecode() monkeypatch.setattr("jwt.decode", mock_function) + @pytest.fixture(autouse=True) def mock_sentry(monkeypatch): - """ Mock sentrys' set_user function """ + """Mock sentrys' set_user function""" def mock_sentry(*args, **kwargs): pass - monkeypatch.setattr('app.auth.set_user', mock_sentry) + monkeypatch.setattr("app.auth.set_user", mock_sentry) @pytest.fixture() def mock_requests_session(monkeypatch): - """ Patch all calls to requests.Session.* """ - monkeypatch.setattr(requests.Session, 'get', - default_mock_requests_session_get) - monkeypatch.setattr(requests.Session, 'post', - default_mock_requests_session_post) + """Patch all calls to requests.Session.*""" + monkeypatch.setattr(requests.Session, "get", default_mock_requests_session_get) + monkeypatch.setattr(requests.Session, "post", default_mock_requests_session_post) return monkeypatch @pytest.fixture(autouse=True) def spy_access_logging(mocker: MockerFixture): """Spies on access audting logging for tests""" - return mocker.spy(auth, 'create_api_access_audit_log') + return mocker.spy(auth, "create_api_access_audit_log") -@then(parsers.parse('the response status code is {status}'), converters={'status': int}) +@then(parsers.parse("the response status code is {status}"), converters={"status": int}) def assert_status_code(response, status: int): - """ Assert that we receive the expected status code """ - assert response['response'].status_code == status + """Assert that we receive the expected status code""" + assert response["response"].status_code == status @then("the response isn't cached") def then_response_not_cached(response): - """ Check that the response isn't being cached """ - if response['response'].status_code == 200: - assert response['response'].headers.get('cache-control', None) == 'max-age=0' + """Check that the response isn't being cached""" + if response["response"].status_code == 200: + assert response["response"].headers.get("cache-control", None) == "max-age=0" -@then(parsers.parse("the response is {response_json}"), - converters={'response_json': load_json_file(__file__)}) +@then(parsers.parse("the response is {response_json}"), converters={"response_json": load_json_file(__file__)}) def then_response(response, response_json: dict): - """ Check entire response """ + """Check entire response""" if response_json is not None: # it's very useful having this code hang around: # import json @@ -232,4 +222,4 @@ def then_response(response, response_json: dict): # actual_filename = get_complete_filename(__file__, 'actual.json') # with open(actual_filename, 'w', encoding="utf-8") as file_pointer: # json.dump(actual, file_pointer, indent=2) - assert response['response'].json() == response_json + assert response["response"].json() == response_json diff --git a/web/.env.example b/web/.env.example index 9b0049b39..0c0c8de6d 100644 --- a/web/.env.example +++ b/web/.env.example @@ -1,13 +1,12 @@ REACT_APP_API_BASE_URL=http://localhost:8080/api -REACT_APP_RASTER_SERVER_BASE_URL=https://wps-dev-raster-tileserver.apps.silver.devops.gov.bc.ca/v0.0.1 REACT_APP_HIDE_DISCLAIMER=true -REACT_APP_KEYCLOAK_AUTH_URL=https://dev.oidc.gov.bc.ca/auth +REACT_APP_KEYCLOAK_AUTH_URL=https://dev.loginproxy.gov.bc.ca/auth REACT_APP_SM_LOGOUT_URL=https://logontest7.gov.bc.ca/clp-cgi/logoff.cgi?retnow=1&returl= -REACT_APP_KEYCLOAK_REALM=8wl6x4cp +REACT_APP_KEYCLOAK_REALM=standard REACT_APP_KEYCLOAK_CLIENT=wps-web -REACT_APP_WF1_AUTH_URL=https://wf1/auth REACT_APP_MS_TEAMS_SPRINT_REVIEW_URL=http://localhost:3000 REACT_APP_MIRO_SPRINT_REVIEW_BOARD_URL=http://localhost:3000 REACT_APP_PMTILES_BUCKET=https://My_S3_Bucket REACT_APP_SENTRY_DSN=123 -REACT_APP_SENTRY_ENV=development \ No newline at end of file +REACT_APP_SENTRY_ENV=development +REACT_APP_MUI_LICENSE_KEY=mui \ No newline at end of file diff --git a/web/src/types/window.d.ts b/web/src/types/window.d.ts index 49885b964..051fe48d9 100644 --- a/web/src/types/window.d.ts +++ b/web/src/types/window.d.ts @@ -5,7 +5,6 @@ interface Window { REACT_APP_KEYCLOAK_AUTH_URL: string REACT_APP_KEYCLOAK_REALM: string REACT_APP_KEYCLOAK_CLIENT: string - REACT_APP_WF1_AUTH_URL: string API_BASE_URL: string | undefined RASTER_SERVER_BASE_URL: string | undefined REACT_APP_MS_TEAMS_SPRINT_REVIEW_URL: string diff --git a/web/src/utils/env.ts b/web/src/utils/env.ts index 576b9066a..d638f86b8 100644 --- a/web/src/utils/env.ts +++ b/web/src/utils/env.ts @@ -6,7 +6,6 @@ let ENV = { KC_AUTH_URL: process.env.REACT_APP_KEYCLOAK_AUTH_URL as string, KC_REALM: process.env.REACT_APP_KEYCLOAK_REALM as string, KC_CLIENT: process.env.REACT_APP_KEYCLOAK_CLIENT as string, - WF1_AUTH_URL: process.env.REACT_APP_WF1_AUTH_URL as string, TEST_AUTH: process.env.TEST_AUTH, MS_TEAMS_SPRINT_REVIEW_URL: process.env.REACT_APP_MS_TEAMS_SPRINT_REVIEW_URL as string, MIRO_SPRINT_REVIEW_BOARD_URL: process.env.REACT_APP_MIRO_SPRINT_REVIEW_BOARD_URL as string, @@ -28,7 +27,6 @@ if (process.env.NODE_ENV === 'production') { KC_AUTH_URL: window.env.REACT_APP_KEYCLOAK_AUTH_URL, KC_REALM: window.env.REACT_APP_KEYCLOAK_REALM, KC_CLIENT: window.env.REACT_APP_KEYCLOAK_CLIENT, - WF1_AUTH_URL: window.env.REACT_APP_WF1_AUTH_URL, TEST_AUTH: undefined, MS_TEAMS_SPRINT_REVIEW_URL: window.env.REACT_APP_MS_TEAMS_SPRINT_REVIEW_URL, MIRO_SPRINT_REVIEW_BOARD_URL: window.env.REACT_APP_MIRO_SPRINT_REVIEW_BOARD_URL, @@ -50,7 +48,6 @@ export const { SM_LOGOUT_URL, MS_TEAMS_SPRINT_REVIEW_URL, MIRO_SPRINT_REVIEW_BOARD_URL, - WF1_AUTH_URL, PMTILES_BUCKET, MUI_LICENSE, SENTRY_DSN,