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
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 0x7f69386a5820>

    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:2095: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7b60>
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:2155: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5a]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7ce0>
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:2155: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[3.5f]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7c20>
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:2155: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[1d]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a8350>
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"] == 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) = timedelta(**{'days': 1.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[24h]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a8290>
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"] == 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) = timedelta(**{'hours': 24.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[2d]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a8410>
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"] == 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) = timedelta(**{'days': 2.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[3d]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a84d0>
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"] == 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) = timedelta(**{'days': 3.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[40h]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a81d0>
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"] == 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) = timedelta(**{'hours': 40.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_setup_introduction_reminders_delay_successful[48h]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7e90>
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"] == 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) = timedelta(**{'hours': 48.0})

tests/test_config.py:2184: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[0.5s]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a76e0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[0s]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a77a0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[10m]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f6938637710>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[1h]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69398b90a0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[1s]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7620>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[2h]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a5ee0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[30m]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a3710>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[3s]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a4e90>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[5m]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a59a0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_1]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a2720>
test_send_introduction_reminders_interval = '331.43s'

    @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.match(
                    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': 331.43}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 331.43}
E         
E         Full diff:
E           {
E         -     'seconds': 331.43,
E         +     'hours': 6,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_2]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a2930>
test_send_introduction_reminders_interval = '  467.202s   '

    @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.match(
                    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': 467.202}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 467.202}
E         
E         Full diff:
E           {
E         -     'seconds': 467.202,
E         +     'hours': 6,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_3]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a29f0>
test_send_introduction_reminders_interval = '351m'

    @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.match(
                    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': 351.0}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'minutes': 351.0}
E         
E         Full diff:
E           {
E         -     'minutes': 351.0,
E         +     'hours': 6,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_4]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a2ab0>
test_send_introduction_reminders_interval = '296.620h'

    @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.match(
                    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': 296.62}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 296.62}
E         
E         Full diff:
E           {
E         -     'hours': 296.62,
E         ?              -- ---
E         +     'hours': 6,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_5]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a2b70>
test_send_introduction_reminders_interval = '624.486s816.606m501.855h'

    @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.match(
                    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': 501...nds': 624.486}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 501.855}
E         Right contains 2 more items:
E         {'minutes': 816.606, 'seconds': 624.486}
E         
E         Full diff:
E           {
E         -     'hours': 501.855,
E         ?              ^^^^^^^
E         +     'hours': 6,
E         ?              ^
E         -     'minutes': 816.606,
E         -     'seconds': 624.486,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_6]
Stack Traces | 0.002s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a2c30>
test_send_introduction_reminders_interval = '163 s  971   m   142.407  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.match(
                    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': 142...conds': 163.0}
E         
E         Differing items:
E         {'hours': 6} != {'hours': 142.407}
E         Right contains 2 more items:
E         {'minutes': 971.0, 'seconds': 163.0}
E         
E         Full diff:
E           {
E         -     'hours': 142.407,
E         ?              ^^^^^^^
E         +     'hours': 6,
E         ?              ^
E         -     'minutes': 971.0,
E         -     'seconds': 163.0,
E           }

tests/test_config.py:1831: AssertionError
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_too_short_introduction_reminders_delay[5h]
Stack Traces | 0.005s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a5ac0>
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:2123: Failed
tests.test_config.TestSetupSendIntroductionRemindersDelay::test_invalid_introduction_reminders_delay[invalid_introduction_reminders_delay]
Stack Traces | 0.007s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersDelay object at 0x7f69386a7950>
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:2155: Failed
tests.test_config.TestSetupSendIntroductionRemindersInterval::test_setup_send_introduction_reminders_interval_successful[case_0]
Stack Traces | 0.009s run time
self = <tests.test_config.TestSetupSendIntroductionRemindersInterval object at 0x7f69386a1fd0>
test_send_introduction_reminders_interval = '213s'

    @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.match(
                    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': 213.0}
E         
E         Left contains 1 more item:
E         {'hours': 6}
E         Right contains 1 more item:
E         {'seconds': 213.0}
E         
E         Full diff:
E           {
E         -     'seconds': 213.0,
E         +     'hours': 6,
E           }

tests/test_config.py:1831: 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sync 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
3 participants