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

Make response expiry date mandatory #1104

Merged
merged 13 commits into from
May 18, 2023
2 changes: 1 addition & 1 deletion app/data_models/metadata_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class MetadataProxy:
case_id: str
collection_exercise_sid: str
response_id: str
response_expires_at: datetime
survey_metadata: Optional[SurveyMetadata] = None
schema_url: Optional[str] = None
schema_name: Optional[str] = None
language_code: Optional[str] = None
response_expires_at: Optional[datetime] = None
channel: Optional[str] = None
region_code: Optional[str] = None
version: Optional[AuthPayloadVersion] = None
Expand Down
6 changes: 2 additions & 4 deletions app/data_models/questionnaire_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,10 @@ def save(self) -> None:
collection_exercise_sid = (
self.collection_exercise_sid or self._metadata["collection_exercise_sid"]
)
response_expires_at = self._metadata.get("response_expires_at")
response_expires_at = self._metadata["response_expires_at"]
self._storage.save(
data=data,
collection_exercise_sid=collection_exercise_sid,
submitted_at=self.submitted_at,
expires_at=parse_iso_8601_datetime(response_expires_at)
if response_expires_at
else None,
expires_at=parse_iso_8601_datetime(response_expires_at),
)
2 changes: 1 addition & 1 deletion app/utilities/metadata_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class RunnerMetadataSchema(Schema, StripWhitespaceMixin):
) # type:ignore
case_type = VALIDATORS["string"](required=False) # type:ignore
response_expires_at = VALIDATORS["iso_8601_date_string"](
required=False,
required=True,
validate=lambda x: parse_iso_8601_datetime(x) > datetime.now(tz=timezone.utc),
) # type:ignore

Expand Down
2 changes: 1 addition & 1 deletion app/utilities/metadata_parser_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class RunnerMetadataSchema(Schema, StripWhitespaceMixin):
required=False, validate=validate.Length(min=1)
) # type:ignore
response_expires_at = VALIDATORS["iso_8601_date_string"](
required=False,
required=True,
validate=lambda x: parse_iso_8601_datetime(x) > datetime.now(tz=timezone.utc),
) # type:ignore
region_code = VALIDATORS["string"](
Expand Down
6 changes: 5 additions & 1 deletion tests/app/data_model/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from app.data_models.progress_store import CompletionStatus
from app.data_models.session_store import SessionStore
from app.storage import storage_encryption
from tests.app.parser.conftest import get_response_expires_at


@pytest.fixture
Expand Down Expand Up @@ -81,7 +82,10 @@ def store_to_serialize(answer_store):
@pytest.fixture
def basic_input():
return {
"METADATA": {"test": True},
"METADATA": {
"test": True,
"response_expires_at": get_response_expires_at(),
},
"ANSWERS": [{"answer_id": "test", "value": "test"}],
"LISTS": [],
"PROGRESS": [
Expand Down
6 changes: 6 additions & 0 deletions tests/app/data_model/test_metadata_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"tx_id": "tx_id",
"collection_exercise_sid": "collection_exercise_sid",
"case_id": "case_id",
"response_expires_at": "2023-05-24T10:46:32+00:00",
}

METADATA_V2 = {
Expand All @@ -22,6 +23,7 @@
"tx_id": "tx_id",
"collection_exercise_sid": "collection_exercise_sid",
"case_id": "case_id",
"response_expires_at": "2023-05-24T10:46:32+00:00",
petechd marked this conversation as resolved.
Show resolved Hide resolved
"survey_metadata": {
"data": {
"ru_ref": "432423423423",
Expand All @@ -46,6 +48,10 @@
MetadataProxy.from_dict(METADATA_V2)["schema_name"],
METADATA_V2["schema_name"],
),
(
MetadataProxy.from_dict(METADATA_V2)["response_expires_at"],
METADATA_V2["response_expires_at"],
),
(MetadataProxy.from_dict(METADATA_V1)["non_existing"], None),
(MetadataProxy.from_dict(METADATA_V2)["non_existing"], None),
),
Expand Down
10 changes: 10 additions & 0 deletions tests/app/parser/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: disable=redefined-outer-name
import uuid
from datetime import datetime, timedelta, timezone

import pytest

Expand Down Expand Up @@ -37,6 +38,7 @@ def fake_metadata_runner():
"response_id": str(uuid.uuid4()),
"account_service_url": "https://ras.ons.gov.uk",
"case_id": str(uuid.uuid4()),
"response_expires_at": get_response_expires_at(),
}


Expand All @@ -48,6 +50,7 @@ def fake_business_metadata_runner():

metadata["eq_id"] = "mbs"
metadata["form_type"] = "0253"
metadata["response_expires_at"] = get_response_expires_at()

return metadata

Expand All @@ -67,6 +70,7 @@ def fake_metadata_full():
"return_by": "2016-07-07",
"case_ref": "1000000000000001",
"case_id": str(uuid.uuid4()),
"response_expires_at": get_response_expires_at(),
}

return dict(fake_metadata_runner(), **fake_questionnaire_claims)
Expand All @@ -84,6 +88,7 @@ def fake_metadata_runner_v2():
"case_id": str(uuid.uuid4()),
"version": AuthPayloadVersion.V2.value,
"survey_metadata": {"data": {"key": "value"}},
"response_expires_at": get_response_expires_at(),
}


Expand All @@ -103,6 +108,7 @@ def fake_metadata_full_v2_business():
"case_ref": "1000000000000001",
"ru_ref": "123456789",
"form_type": "I",
"response_expires_at": get_response_expires_at(),
}

metadata = fake_metadata_runner_v2()
Expand Down Expand Up @@ -140,3 +146,7 @@ def fake_questionnaire_metadata_requirements_full():
{"name": "ref_p_end_date", "type": "string"},
{"name": "account_service_url", "type": "url", "optional": True},
]


def get_response_expires_at() -> str:
return (datetime.now(tz=timezone.utc) + timedelta(days=1)).isoformat()
3 changes: 3 additions & 0 deletions tests/app/submitter/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from app.questionnaire.questionnaire_schema import QuestionnaireSchema
from app.settings import ACCOUNT_SERVICE_BASE_URL_SOCIAL
from app.submitter import RabbitMQSubmitter
from tests.app.parser.conftest import get_response_expires_at

METADATA_V1 = MetadataProxy.from_dict(
{
Expand All @@ -39,6 +40,7 @@
"display_address": "68 Abingdon Road, Goathill",
"case_ref": "1000000000000001",
"jti": str(uuid.uuid4()),
"response_expires_at": get_response_expires_at(),
}
)

Expand Down Expand Up @@ -69,6 +71,7 @@
"region_code": "GB-ENG",
"channel": "RH",
"jti": str(uuid.uuid4()),
"response_expires_at": get_response_expires_at(),
}
)

Expand Down
6 changes: 6 additions & 0 deletions tests/app/views/handlers/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from app.data_models.session_data import SessionData
from app.data_models.session_store import SessionStore
from app.questionnaire import QuestionnaireSchema
from tests.app.parser.conftest import get_response_expires_at

time_to_freeze = datetime.now(timezone.utc).replace(second=0, microsecond=0)
tx_id = str(uuid.uuid4())
Expand Down Expand Up @@ -39,6 +40,7 @@
channel = "H"
case_ref = "1000000000000001"
region_code = "GB_WLS"
response_expires_at = get_response_expires_at()


@pytest.fixture
Expand Down Expand Up @@ -126,6 +128,7 @@ def metadata():
"region_code": region_code,
"case_id": case_id,
"language_code": language_code,
"response_expires_at": response_expires_at,
}
)

Expand All @@ -143,6 +146,7 @@ def metadata_v2():
"channel": channel,
"region_code": region_code,
"account_service_url": "account_service_url",
"response_expires_at": get_response_expires_at(),
"survey_metadata": {
"data": {
"period_id": period_id,
Expand Down Expand Up @@ -210,6 +214,7 @@ def mock_questionnaire_store(mocker):
"schema_name": schema_name,
"account_service_url": "account_service_url",
"response_id": "response_id",
"response_expires_at": get_response_expires_at(),
}
)
return questionnaire_store
Expand All @@ -231,6 +236,7 @@ def mock_questionnaire_store_v2(mocker):
"channel": channel,
"region_code": region_code,
"account_service_url": "account_service_url",
"response_expires_at": get_response_expires_at(),
"survey_metadata": {
"data": {
"period_id": period_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
GB_WLS_REGION_CODE,
IndividualResponseFulfilmentRequest,
)
from tests.app.parser.conftest import get_response_expires_at

DUMMY_MOBILE_NUMBER = "07700900258"

Expand All @@ -27,6 +28,7 @@ def test_sms_fulfilment_request_payload():
response_id="response_id",
account_service_url="account_service_url",
collection_exercise_sid="collection_exercise_sid",
response_expires_at=get_response_expires_at(),
)

fulfilment_request = IndividualResponseFulfilmentRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from app.utilities.schema import load_schema_from_name
from app.views.handlers.question import Question

from ...parser.conftest import get_response_expires_at
from .conftest import set_storage_data


Expand Down Expand Up @@ -35,6 +36,7 @@ def test_question_with_dynamic_answers(storage, language, mocker):
questionnaire_store.list_store = ListStore(
[{"items": ["tUJzGV", "vhECeh"], "name": "supermarkets"}]
)
questionnaire_store.set_metadata({"response_expires_at": get_response_expires_at()})
schema = load_schema_from_name("test_dynamic_answers_list_source")

mocker.patch(
Expand Down
5 changes: 5 additions & 0 deletions tests/functional/jwt_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export function generateToken(
const iat = KJUR.jws.IntDate.get("now");
const exp = KJUR.jws.IntDate.get("now") + 1800;
const caseId = uuidv4();
const currentDate = new Date();
currentDate.setUTCDate(currentDate.getUTCDate() + 1);
const isoDate = currentDate.toISOString();

if (version === "v2") {
payload = {
Expand All @@ -106,6 +109,7 @@ export function generateToken(
account_service_url: "http://localhost:8000",
survey_metadata: getSurveyMetadata(theme, userId, displayAddress, periodId, periodStr),
version: "v2",
response_expires_at: isoDate,
};
} else {
payload = {
Expand All @@ -131,6 +135,7 @@ export function generateToken(
region_code: regionCode,
language_code: languageCode,
account_service_url: "http://localhost:8000",
response_expires_at: isoDate,
};
}

Expand Down
2 changes: 2 additions & 0 deletions tests/integration/create_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from app.authentication.auth_payload_version import AuthPayloadVersion
from app.keys import KEY_PURPOSE_AUTHENTICATION
from tests.app.parser.conftest import get_response_expires_at

ACCOUNT_SERVICE_URL = "http://upstream.url"

Expand Down Expand Up @@ -88,6 +89,7 @@ def _get_payload_with_params(
payload_vars["exp"] = payload_vars["iat"] + float(3600) # one hour from now
payload_vars["jti"] = str(uuid4())
payload_vars["case_id"] = str(uuid4())
payload_vars["response_expires_at"] = get_response_expires_at()

for key, value in extra_payload.items():
payload_vars[key] = value
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/routes/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
ACCOUNT_SERVICE_BASE_URL_SOCIAL,
ONS_URL,
)
from tests.app.parser.conftest import get_response_expires_at
from tests.integration.create_token import ACCOUNT_SERVICE_URL
from tests.integration.integration_test_case import IntegrationTestCase

Expand All @@ -31,6 +32,7 @@ class TestErrors(IntegrationTestCase): # pylint: disable=too-many-public-method
"language_code": "en",
"account_service_url": "http://correct.place",
"roles": [],
"response_expires_at": get_response_expires_at(),
}

def test_errors_404(self):
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/routes/test_jwt_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
TEST_DO_NOT_USE_SR_PUBLIC_KEY,
TEST_DO_NOT_USE_UPSTREAM_PRIVATE_KEY,
)
from tests.app.parser.conftest import get_response_expires_at
from tests.integration.app_context_test_case import AppContextTestCase
from tests.integration.integration_test_case import (
EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY_KID,
Expand Down Expand Up @@ -85,6 +86,7 @@ def create_payload():
"ru_name": "Test",
"return_by": "2016-09-09",
"account_service_url": "http://upstream.url/",
"response_expires_at": get_response_expires_at(),
}


Expand Down
2 changes: 2 additions & 0 deletions tests/integration/test_flush_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from mock import patch

from tests.app.parser.conftest import get_response_expires_at
from tests.integration.integration_test_case import IntegrationTestCase


Expand Down Expand Up @@ -179,6 +180,7 @@ def test_flush_data_successful_v2(
"lists": [],
},
"started_at": "2023-02-07T11:42:32.380784+00:00",
"response_expires_at": get_response_expires_at(),
}
self.launchSurveyV2("test_textfield")
form_data = {"name-answer": "Joe Bloggs"}
Expand Down