Skip to content

Conversation

@MattyTheHacker
Copy link
Member

No description provided.

@MattyTheHacker MattyTheHacker self-assigned this May 30, 2025
@MattyTheHacker MattyTheHacker added the test suite Changes and additions to the project test suite and unit tests label May 30, 2025
@MattyTheHacker MattyTheHacker linked an issue May 30, 2025 that may be closed by this pull request
@codecov
Copy link

codecov bot commented May 30, 2025

❌ 28 Tests Failed:

Tests completed Failed Passed Skipped
413 28 385 0
View the top 3 failed test(s) by shortest run time
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_default_send_introduction_reminders_delay
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33ce8550>

    def test_default_send_introduction_reminders_delay(self) -> None:
        """Test that a default value is used when no `SEND_INTRODUCTION_REMINDERS_DELAY`."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            assert os.environ.get("SEND_INTRODUCTION_REMINDERS_DELAY") is None
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS"] == "once"
E       AssertionError: assert False == 'once'

tests/test_config.py:2098: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33de36c0>
test_invalid_introduction_reminders_delay = '3.5'

    @pytest.mark.parametrize(
        "test_invalid_introduction_reminders_delay",
        ("invalid_introduction_reminders_delay", "3.5", "3.5f", "3.5a"),
    )
    def test_invalid_introduction_reminders_delay(
        self, test_invalid_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` is invalid."""
        INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must contain the delay "
            "in any combination of seconds, minutes, hours, days or weeks."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
    
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_invalid_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2160: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5a]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cfc890>
test_invalid_introduction_reminders_delay = '3.5a'

    @pytest.mark.parametrize(
        "test_invalid_introduction_reminders_delay",
        ("invalid_introduction_reminders_delay", "3.5", "3.5f", "3.5a"),
    )
    def test_invalid_introduction_reminders_delay(
        self, test_invalid_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` is invalid."""
        INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must contain the delay "
            "in any combination of seconds, minutes, hours, days or weeks."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
    
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_invalid_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2160: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[1d]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cc2170>
test_send_introduction_reminders_delay = '1d'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=1)
E        +  where datetime.timedelta(days=1) = <class 'datetime.timedelta'>(**{'days': 1.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[24h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cc1f90>
test_send_introduction_reminders_delay = '24h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=1)
E        +  where datetime.timedelta(days=1) = <class 'datetime.timedelta'>(**{'hours': 24.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[3d]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33b0aa50>
test_send_introduction_reminders_delay = '3d'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=3)
E        +  where datetime.timedelta(days=3) = <class 'datetime.timedelta'>(**{'days': 3.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[40h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33ccafc0>
test_send_introduction_reminders_delay = '40h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=1, seconds=57600)
E        +  where datetime.timedelta(days=1, seconds=57600) = <class 'datetime.timedelta'>(**{'hours': 40.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[48h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33ccaf10>
test_send_introduction_reminders_delay = '48h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=2)
E        +  where datetime.timedelta(days=2) = <class 'datetime.timedelta'>(**{'hours': 48.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[0.5s]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33ca0f50>
too_short_introduction_reminders_delay = '0.5s'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[0s]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cf1c50>
too_short_introduction_reminders_delay = '0s'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[10m]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33dcb460>
too_short_introduction_reminders_delay = '10m'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[1h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33b01910>
too_short_introduction_reminders_delay = '1h'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[1s]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33ca0e60>
too_short_introduction_reminders_delay = '1s'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[2h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cb4c30>
too_short_introduction_reminders_delay = '2h'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[30m]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33dcb570>
too_short_introduction_reminders_delay = '30m'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[3s]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cbcb50>
too_short_introduction_reminders_delay = '3s'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[5h]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cb4b00>
too_short_introduction_reminders_delay = '5h'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[5m]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cbca50>
too_short_introduction_reminders_delay = '5m'

    @pytest.mark.parametrize(
        "too_short_introduction_reminders_delay",
        ("5h", "2h", "1h", "30m", "10m", "5m", "3s", "1s", "0.5s", "0s"),
    )
    def test_too_short_introduction_reminders_delay(
        self, too_short_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` too short."""
        TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must be longer than or equal to 1 day."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                too_short_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=TOO_SHORT_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2128: Failed
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_1]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33ce82d0>
test_send_introduction_reminders_interval = '188.821s'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'seconds': 188.821}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 188.821}
E         
E         Full diff:
E           {
E         -     'seconds': 188.821,
E         +     'hours': 6,
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_2]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33cb48a0>
test_send_introduction_reminders_interval = '  650s   '

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'seconds': 650.0}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 650.0}
E         
E         Full diff:
E           {
E         -     'seconds': 650.0,
E         +     'hours': 6,
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_3]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33cb49d0>
test_send_introduction_reminders_interval = '51.804m'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'minutes': 51.804}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'minutes': 51.804}
E         
E         Full diff:
E           {
E         -     'minutes': 51.804,
E         +     'hours': 6,
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_4]
Stack Traces | 0.003s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33c929f0>
test_send_introduction_reminders_interval = '517h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'hours': 517.0}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 517.0}
E         
E         Full diff:
E           {
E         -     'hours': 517.0,
E         ?              ^^^^^
E         +     'hours': 6,
E         ?              ^
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5f]
Stack Traces | 0.004s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cfc7d0>
test_invalid_introduction_reminders_delay = '3.5f'

    @pytest.mark.parametrize(
        "test_invalid_introduction_reminders_delay",
        ("invalid_introduction_reminders_delay", "3.5", "3.5f", "3.5a"),
    )
    def test_invalid_introduction_reminders_delay(
        self, test_invalid_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` is invalid."""
        INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must contain the delay "
            "in any combination of seconds, minutes, hours, days or weeks."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
    
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_invalid_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2160: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[invalid_introduction_reminders_delay]
Stack Traces | 0.004s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c33cf1fd0>
test_invalid_introduction_reminders_delay = 'invalid_introduction_reminders_delay'

    @pytest.mark.parametrize(
        "test_invalid_introduction_reminders_delay",
        ("invalid_introduction_reminders_delay", "3.5", "3.5f", "3.5a"),
    )
    def test_invalid_introduction_reminders_delay(
        self, test_invalid_introduction_reminders_delay: str
    ) -> None:
        """Test that an error is raised when `SEND_INTRODUCTION_REMINDERS_DELAY` is invalid."""
        INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE: Final[str] = (
            "SEND_INTRODUCTION_REMINDERS_DELAY must contain the delay "
            "in any combination of seconds, minutes, hours, days or weeks."
        )
    
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
    
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_invalid_introduction_reminders_delay
            )
    
>           with pytest.raises(
                ImproperlyConfiguredError,
                match=INVALID_SEND_INTRODUCTION_REMINDERS_DELAY_MESSAGE,
            ):
E           Failed: DID NOT RAISE <class 'exceptions.config_changes.ImproperlyConfiguredError'>

tests/test_config.py:2160: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[2d]
Stack Traces | 0.004s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6c346257f0>
test_send_introduction_reminders_delay = '2d'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_delay", ("48h", "40h", "24h", "1d", "2d", "3d")
    )
    def test_setup_introduction_reminders_delay_successful(
        self, test_send_introduction_reminders_delay: str
    ) -> None:
        """Test that the given `SEND_INTRODUCTION_REMINDERS_DELAY` is used when provided."""
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_DELAY"] = (
                test_send_introduction_reminders_delay
            )
    
            RuntimeSettings._setup_send_introduction_reminders_delay()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_DELAY"] == datetime.timedelta(
            **{
                key: float(value)
                for key, value in (
                    re.fullmatch(
                        r"\A(?:(?P<seconds>(?:\d*\.)?\d+)s)?(?:(?P<minutes>(?:\d*\.)?\d+)m)?(?:(?P<hours>(?:\d*\.)?\d+)h)?(?:(?P<days>(?:\d*\.)?\d+)d)?(?:(?P<weeks>(?:\d*\.)?\d+)w)?\Z",
                        test_send_introduction_reminders_delay.lower().strip(),
                    )
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
                if value
            },
        )
E       AssertionError: assert datetime.timedelta(0) == datetime.timedelta(days=2)
E        +  where datetime.timedelta(days=2) = <class 'datetime.timedelta'>(**{'days': 2.0})
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_config.py:2189: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_5]
Stack Traces | 0.004s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33dcb240>
test_send_introduction_reminders_interval = '103s322.302m202h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'hours': 202...conds': 103.0}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 202.0}
E         Right contains 2 more items:
E         {'minutes': 322.302, 'seconds': 103.0}
E         
E         Full diff:
E           {
E         -     'hours': 202.0,
E         ?              ^^^^^
E         +     'hours': 6,
E         ?              ^
E         -     'minutes': 322.302,
E         -     'seconds': 103.0,
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_6]
Stack Traces | 0.004s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33dcb350>
test_send_introduction_reminders_interval = '631.161 s  352   m   213.18  h'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'hours': 213...nds': 631.161}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 213.18}
E         Right contains 2 more items:
E         {'minutes': 352.0, 'seconds': 631.161}
E         
E         Full diff:
E           {
E         -     'hours': 213.18,
E         ?              ^^^^^^
E         +     'hours': 6,
E         ?              ^
E         -     'minutes': 352.0,
E         -     'seconds': 631.161,
E           }

tests/test_config.py:1834: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_0]
Stack Traces | 0.005s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f6c33ce8190>
test_send_introduction_reminders_interval = '635s'

    @pytest.mark.parametrize(
        "test_send_introduction_reminders_interval",
        (
            f"{random.randint(3, 999)}s",
            f"{random.randint(3, 999)}.{random.randint(0, 999)}s",
            (
                f"  {random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }s   "
            ),
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}m",
            f"{random.randint(1, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}h",
            (
                f"{random.randint(3, 999)}{random.choice(('', f'.{random.randint(0, 999)}'))}s{
                    random.randint(0, 999)
                }{random.choice(('', f'.{random.randint(0, 999)}'))}m{random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }h"
            ),
            (
                f"{random.randint(3, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                } s  {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }   m   {random.randint(0, 999)}{
                    random.choice(('', f'.{random.randint(0, 999)}'))
                }  h"
            ),
        ),
        ids=[f"case_{i}" for i in range(7)],
    )
    def test_setup_send_introduction_reminders_interval_successful(
        self, test_send_introduction_reminders_interval: str
    ) -> None:
        """
        Test that the given `SEND_INTRODUCTION_REMINDERS_INTERVAL` is used when provided.
    
        In this test, the provided `SEND_INTRODUCTION_REMINDERS_INTERVAL` is valid
        and so must be saved successfully.
        """
        RuntimeSettings: Final[type[Settings]] = config._settings_class_factory()
        RuntimeSettings._setup_send_introduction_reminders()
    
        with (
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_DELAY"),
            EnvVariableDeleter("SEND_INTRODUCTION_REMINDERS_INTERVAL"),
        ):
            os.environ["SEND_INTRODUCTION_REMINDERS_INTERVAL"] = (
                test_send_introduction_reminders_interval
            )
    
            RuntimeSettings._setup_send_introduction_reminders_interval()
    
        RuntimeSettings._is_env_variables_setup = True
    
>       assert RuntimeSettings()["SEND_INTRODUCTION_REMINDERS_INTERVAL"] == {
            key: float(value)
            for key, value in (
                re.fullmatch(
                    r"\A(?:(?P<seconds>(?:\d*\.)?\d+)\s*s)?\s*(?:(?P<minutes>(?:\d*\.)?\d+)\s*m)?\s*(?:(?P<hours>(?:\d*\.)?\d+)\s*h)?\Z",
                    test_send_introduction_reminders_interval.lower().strip(),
                )
                .groupdict()  # type: ignore[union-attr]
                .items()
            )
            if value
        }
E       AssertionError: assert {'hours': 6} == {'seconds': 635.0}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 635.0}
E         
E         Full diff:
E           {
E         -     'seconds': 635.0,
E         +     'hours': 6,
E           }

tests/test_config.py:1834: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@MattyTheHacker MattyTheHacker force-pushed the 515-implement-config-unit-testing branch from 9c5a784 to 782bcfd Compare May 30, 2025 17:49
@MattyTheHacker MattyTheHacker added sync Request bots to automatically keep this PR up to date with it's base branch and removed conflict A bot has identified that this PR has a conflict, preventing automatic syncing to the base branch labels Nov 4, 2025
@automatic-pr-updater automatic-pr-updater bot added conflict A bot has identified that this PR has a conflict, preventing automatic syncing to the base branch and removed sync Request bots to automatically keep this PR up to date with it's base branch labels Nov 11, 2025
@automatic-pr-updater
Copy link
Contributor

This pull request has a merge conflict with the base branch! Please resolve the conflict manually, remove the conflict label and re-add the filter label (if applicable).

@MattyTheHacker MattyTheHacker added sync Request bots to automatically keep this PR up to date with it's base branch and removed conflict A bot has identified that this PR has a conflict, preventing automatic syncing to the base branch labels Nov 11, 2025
@automatic-pr-updater automatic-pr-updater bot added conflict A bot has identified that this PR has a conflict, preventing automatic syncing to the base branch and removed sync Request bots to automatically keep this PR up to date with it's base branch labels Nov 17, 2025
@automatic-pr-updater
Copy link
Contributor

This pull request has a merge conflict with the base branch! Please resolve the conflict manually, remove the conflict label and re-add the filter label (if applicable).

@MattyTheHacker MattyTheHacker added sync Request bots to automatically keep this PR up to date with it's base branch and removed conflict A bot has identified that this PR has a conflict, preventing automatic syncing to the base branch labels Nov 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sync Request bots to automatically keep this PR up to date with it's base branch test suite Changes and additions to the project test suite and unit tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement config unit testing

4 participants