def _extend_session_expiry(session_store: SessionStore) -> None:
    """
    Extends the expiration time of the session
    :param session_store:
    """
    session_timeout = cookie_session.get("expires_in")
    if session_timeout:
        new_expiration_time = datetime.now(tz=timezone.utc) + timedelta(
            seconds=session_timeout)

        # Only update expiry time if its greater than 60s different to what is currently set
        if (not session_store.expiration_time
                or (new_expiration_time -
                    session_store.expiration_time).total_seconds() > 60):
            session_store.expiration_time = new_expiration_time
            session_store.save()
            logger.debug("session expiry extended")
class SessionStoreTest(AppContextTestCase):
    def setUp(self):
        super().setUp()
        self._app.permanent_session_lifetime = timedelta(seconds=1)
        self.session_store = SessionStore("user_ik", "pepper")
        self.expires_at = datetime.utcnow() + timedelta(seconds=3)
        self.session_data = SessionData(
            tx_id="tx_id",
            schema_name="some_schema_name",
            period_str="period_str",
            language_code=None,
            launch_language_code=None,
            survey_url=None,
            ru_name="ru_name",
            ru_ref="ru_ref",
            questionnaire_id="questionnaire_id",
            response_id="response_id",
            case_id="case_id",
        )

    def test_no_session(self):
        with self._app.test_request_context():
            self.assertIsNone(self.session_store.user_id)
            self.assertIsNone(self.session_store.session_data)

    def test_create(self):
        with self._app.test_request_context():
            self.session_store.create("eq_session_id", "test",
                                      self.session_data, self.expires_at)
            self.assertEqual("eq_session_id", self.session_store.eq_session_id)
            self.assertEqual("test", self.session_store.user_id)
            self.assertEqual(self.session_data,
                             self.session_store.session_data)

    def test_save(self):
        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=self.session_data,
                expires_at=self.expires_at,
            ).save()
            session_store = SessionStore("user_ik", "pepper", "eq_session_id")
            self.assertEqual(session_store.session_data.tx_id, "tx_id")

    def test_delete(self):
        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=self.session_data,
                expires_at=self.expires_at,
            ).save()
            self.assertEqual("test", self.session_store.user_id)
            self.session_store.delete()
            self.assertEqual(self.session_store.user_id, None)

    def test_add_data_to_session(self):
        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=self.session_data,
                expires_at=self.expires_at,
            ).save()
            current_time = datetime.utcnow().isoformat()
            self.session_store.session_data.submitted_time = current_time
            self.session_store.save()

            session_store = SessionStore("user_ik", "pepper", "eq_session_id")
            self.assertEqual(session_store.session_data.submitted_time,
                             current_time)

    def test_should_not_delete_when_no_session(self):
        with self.app_request_context("/status") as context:

            # Call clear with a valid user_id but no session in database
            self.session_store.delete()

            # No database calls should have been made
            self.assertEqual(
                context.app.eq["storage"].client.delete_call_count, 0)

    def test_session_store_ignores_new_values_in_session_data(self):
        session_data = SessionData(
            tx_id="tx_id",
            schema_name="some_schema_name",
            period_str="period_str",
            language_code=None,
            launch_language_code=None,
            survey_url=None,
            ru_name="ru_name",
            ru_ref="ru_ref",
            response_id="response_id",
            questionnaire_id="questionnaire_id",
            case_id="case_id",
        )

        session_data.additional_value = "some cool new value you do not know about yet"

        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=self.session_data,
                expires_at=self.expires_at,
            ).save()

            session_store = SessionStore("user_ik", "pepper", "eq_session_id")

            self.assertFalse(
                hasattr(session_store.session_data, "additional_value"))

    def test_session_store_ignores_multiple_new_values_in_session_data(self):
        session_data = SessionData(
            tx_id="tx_id",
            schema_name="some_schema_name",
            period_str="period_str",
            language_code=None,
            launch_language_code=None,
            survey_url=None,
            ru_name="ru_name",
            ru_ref="ru_ref",
            response_id="response_id",
            questionnaire_id="questionnaire_id",
            case_id="case_id",
        )

        session_data.additional_value = "some cool new value you do not know about yet"
        session_data.second_additional_value = "some other not so cool value"

        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=session_data,
                expires_at=self.expires_at,
            ).save()

            session_store = SessionStore("user_ik", "pepper", "eq_session_id")

            self.assertFalse(
                hasattr(session_store.session_data, "additional_value"))
            self.assertFalse(
                hasattr(session_store.session_data, "second_additional_value"))

    def test_session_store_stores_trading_as_value_if_present(self):
        session_data = SessionData(
            tx_id="tx_id",
            schema_name="some_schema_name",
            period_str="period_str",
            language_code=None,
            launch_language_code=None,
            survey_url=None,
            ru_name="ru_name",
            ru_ref="ru_ref",
            response_id="response_id",
            questionnaire_id="questionnaire_id",
            trad_as="trading_as",
            case_id="case_id",
        )
        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=session_data,
                expires_at=self.expires_at,
            ).save()

            session_store = SessionStore("user_ik", "pepper", "eq_session_id")

            self.assertTrue(hasattr(session_store.session_data, "trad_as"))

    def test_session_store_stores_none_for_trading_as_if_not_present(self):
        session_data = SessionData(
            tx_id="tx_id",
            schema_name="some_schema_name",
            period_str="period_str",
            language_code=None,
            launch_language_code=None,
            survey_url=None,
            ru_name="ru_name",
            ru_ref="ru_ref",
            response_id="response_id",
            questionnaire_id="questionnaire_id",
            case_id="case_id",
        )
        with self._app.test_request_context():
            self.session_store.create(
                eq_session_id="eq_session_id",
                user_id="test",
                session_data=session_data,
                expires_at=self.expires_at,
            ).save()

            session_store = SessionStore("user_ik", "pepper", "eq_session_id")

            self.assertIsNone(session_store.session_data.trad_as)