diff --git a/README.md b/README.md index 763a5b0..9520c25 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Simply a customs agent DISCORD_TOKEN=YOUR DISCORD BOT TOKEN SERVER_ID=YOUR SERVER ID (RIGHT CLICK ON SERVER ICON AND COPY ID) LOGGER_FILENAME=YOUR LOG FILENAME + DASHBOARD_PORT=PORT OF THE DASHBOARD ON THE LOCAL MACHINE ``` :warning: Do not add space between `=`. Even for string, **do not** add `"`. @@ -104,9 +105,14 @@ If this happens, script will ask you if you want to contact them by hand or auto ## Commands To fix linter and format errors run these two commands: -```commandline +```sh ruff check . --fix ``` -```commandline +```sh black . ``` + +To run tests: +```sh +pytest +``` diff --git a/bot/application/miscellaneous/miscellaneous_service.py b/bot/application/miscellaneous/miscellaneous_service.py new file mode 100644 index 0000000..c563122 --- /dev/null +++ b/bot/application/miscellaneous/miscellaneous_service.py @@ -0,0 +1,27 @@ +import socket + +from bot.config.logger.logger import Logger +from bot.config.service_locator import ServiceLocator +from bot.domain.discord_client.discord_client import DiscordClient + + +class MiscellaneousService: + + DOCKER_HOST: str = "host.docker.internal" + + def __init__(self, discord_client: DiscordClient, dashboard_port: int): + self.__logger: Logger = ServiceLocator.get_dependency(Logger) + self.__discord_client = discord_client + + self.__dashboard_board: int = dashboard_port + + def __get_host_ip_address(self) -> str: + try: + ip_address: str = socket.gethostbyname(self.DOCKER_HOST) + return f"http://{ip_address}" + except socket.gaierror: + return "http://127.0.0.1" + + def retrieve_dashboard_url(self) -> str: + ip_address: str = self.__get_host_ip_address() + return f"{ip_address}:{self.__dashboard_board}" diff --git a/bot/application/student/student_service.py b/bot/application/student/student_service.py index 78a21d8..ef45434 100644 --- a/bot/application/student/student_service.py +++ b/bot/application/student/student_service.py @@ -33,13 +33,13 @@ class StudentService(StudentRegisteredObservable, MemberRemovedObservable): - def __init__(self, student_repository: StudentRepository): + def __init__( + self, discord_client: DiscordClient, student_repository: StudentRepository + ): super().__init__() self.__logger: Logger = ServiceLocator.get_dependency(Logger) - self.__discord_client: DiscordClient = ServiceLocator.get_dependency( - DiscordClient - ) + self.__discord_client = discord_client self.__student_repository = student_repository diff --git a/bot/config/constants.py b/bot/config/constants.py index dd46a29..4caa02c 100644 --- a/bot/config/constants.py +++ b/bot/config/constants.py @@ -11,3 +11,4 @@ class DotenvConfigurationKey: DISCORD_TOKEN: str = "DISCORD_TOKEN" SERVER_ID: str = "SERVER_ID" LOGGER_FILENAME: str = "LOGGER_FILENAME" + DASHBOARD_PORT: str = "DASHBOARD_PORT" diff --git a/bot/config/environment/context/application_context.py b/bot/config/environment/context/application_context.py index eb5f6ec..a75748f 100644 --- a/bot/config/environment/context/application_context.py +++ b/bot/config/environment/context/application_context.py @@ -6,6 +6,7 @@ from pymongo.collection import Collection from bot.application.discord.discord_service import DiscordService +from bot.application.miscellaneous.miscellaneous_service import MiscellaneousService from bot.application.student.exception.invalid_format_exception import ( InvalidFormatException, ) @@ -30,6 +31,7 @@ ) from bot.resource.cog.association.association import AssociationCog from bot.resource.cog.error_handler.error_handler import ErrorHandlerCog +from bot.resource.cog.miscellaneous.miscellaneous import MiscellaneousCog from bot.resource.cog.registration.register_member import RegisterMemberCog from bot.config.environment.dotenv_configuration import DotEnvConfiguration from bot.config.logger.logger import Logger @@ -83,10 +85,13 @@ async def build_application(self): task_scheduler = TaskScheduler() - student_service = self._instantiate_student_service(student_repository) + student_service = self._instantiate_student_service( + discord_client, student_repository + ) discord_service = self._instantiate_discord_service( discord_client, student_repository ) + miscellaneous_service = self._instantiate_miscellaneous_service(discord_client) student_service.register_to_on_student_registered(discord_service) @@ -96,12 +101,14 @@ async def build_application(self): (StudentRepository, student_repository), (StudentService, student_service), (DiscordService, discord_service), + (MiscellaneousService, miscellaneous_service), ] self.__register_dependencies(dependencies) cogs = [ self._instantiate_register_member_cog(), self._instantiate_association_cog(), + self._instantiate_miscellaneous_cog(), self._instantiate_error_handler_cog(), ] await self.__register_cogs(discord_client, cogs) @@ -142,6 +149,10 @@ def _instantiate_association_cog(self) -> AssociationCog: def _instantiate_register_member_cog(self) -> RegisterMemberCog: pass + @abstractmethod + def _instantiate_miscellaneous_cog(self) -> MiscellaneousCog: + pass + @abstractmethod def _instantiate_error_handler_cog(self) -> ErrorHandlerCog: pass @@ -162,7 +173,7 @@ def _instantiate_student_repository( @abstractmethod def _instantiate_student_service( - self, student_repository: StudentRepository + self, discord_client: DiscordClient, student_repository: StudentRepository ) -> StudentService: pass @@ -172,6 +183,12 @@ def _instantiate_discord_service( ) -> DiscordService: pass + @abstractmethod + def _instantiate_miscellaneous_service( + self, discord_client: DiscordClient + ) -> MiscellaneousService: + pass + @abstractmethod def _instantiate_tasks(self, discord_client: DiscordClient) -> List[Task]: pass diff --git a/bot/config/environment/context/development_context.py b/bot/config/environment/context/development_context.py index 10938ce..63c6b47 100644 --- a/bot/config/environment/context/development_context.py +++ b/bot/config/environment/context/development_context.py @@ -7,12 +7,14 @@ from pymongo.collection import Collection from bot.application.discord.discord_service import DiscordService +from bot.application.miscellaneous.miscellaneous_service import MiscellaneousService from bot.application.student.student_service import StudentService from bot.application.task.kick_unregistered_user_task import KickUnregisteredUserTask from bot.application.task.sentence_of_the_day_task import SentenceOfTheDayTask from bot.domain.task.task import Task from bot.resource.cog.association.association import AssociationCog from bot.resource.cog.error_handler.error_handler import ErrorHandlerCog +from bot.resource.cog.miscellaneous.miscellaneous import MiscellaneousCog from bot.resource.cog.registration.register_member import RegisterMemberCog from bot.config.environment.context.application_context import ApplicationContext from bot.config.constants import ConfigurationFilename @@ -53,6 +55,9 @@ def _instantiate_association_cog(self) -> AssociationCog: def _instantiate_register_member_cog(self) -> RegisterMemberCog: return RegisterMemberCog() + def _instantiate_miscellaneous_cog(self) -> MiscellaneousCog: + return MiscellaneousCog() + def _instantiate_error_handler_cog(self) -> ErrorHandlerCog: return ErrorHandlerCog() @@ -63,15 +68,20 @@ def _instantiate_student_repository( return CachedStudentRepository(student_repository) def _instantiate_student_service( - self, student_repository: StudentRepository + self, discord_client: DiscordClient, student_repository: StudentRepository ) -> StudentService: - return StudentService(student_repository) + return StudentService(discord_client, student_repository) def _instantiate_discord_service( self, discord_client: DiscordClient, student_repository: StudentRepository ) -> DiscordService: return DiscordService(discord_client, student_repository) + def _instantiate_miscellaneous_service( + self, discord_client: DiscordClient + ) -> MiscellaneousService: + return MiscellaneousService(discord_client, self._configuration.dashboard_port) + def _instantiate_tasks(self, discord_client: DiscordClient) -> List[Task]: return [ KickUnregisteredUserTask( diff --git a/bot/config/environment/context/docker_context.py b/bot/config/environment/context/docker_context.py index d1fbb31..85f4f75 100644 --- a/bot/config/environment/context/docker_context.py +++ b/bot/config/environment/context/docker_context.py @@ -7,12 +7,14 @@ from pymongo.collection import Collection from bot.application.discord.discord_service import DiscordService +from bot.application.miscellaneous.miscellaneous_service import MiscellaneousService from bot.application.student.student_service import StudentService from bot.application.task.kick_unregistered_user_task import KickUnregisteredUserTask from bot.application.task.sentence_of_the_day_task import SentenceOfTheDayTask from bot.domain.task.task import Task from bot.resource.cog.association.association import AssociationCog from bot.resource.cog.error_handler.error_handler import ErrorHandlerCog +from bot.resource.cog.miscellaneous.miscellaneous import MiscellaneousCog from bot.resource.cog.registration.register_member import RegisterMemberCog from bot.config.environment.context.application_context import ApplicationContext from bot.config.logger.logger import Logger @@ -51,6 +53,9 @@ def _instantiate_association_cog(self) -> AssociationCog: def _instantiate_register_member_cog(self) -> RegisterMemberCog: return RegisterMemberCog() + def _instantiate_miscellaneous_cog(self) -> MiscellaneousCog: + return MiscellaneousCog() + def _instantiate_error_handler_cog(self) -> ErrorHandlerCog: return ErrorHandlerCog() @@ -61,15 +66,20 @@ def _instantiate_student_repository( return CachedStudentRepository(student_repository) def _instantiate_student_service( - self, student_repository: StudentRepository + self, discord_client: DiscordClient, student_repository: StudentRepository ) -> StudentService: - return StudentService(student_repository) + return StudentService(discord_client, student_repository) def _instantiate_discord_service( self, discord_client: DiscordClient, student_repository: StudentRepository ) -> DiscordService: return DiscordService(discord_client, student_repository) + def _instantiate_miscellaneous_service( + self, discord_client: DiscordClient + ) -> MiscellaneousService: + return MiscellaneousService(discord_client, self._configuration.dashboard_port) + def _instantiate_tasks(self, discord_client: DiscordClient) -> List[Task]: return [ KickUnregisteredUserTask( diff --git a/bot/config/environment/context/production_context.py b/bot/config/environment/context/production_context.py index bd820d7..4e3ec97 100644 --- a/bot/config/environment/context/production_context.py +++ b/bot/config/environment/context/production_context.py @@ -7,12 +7,14 @@ from pymongo.collection import Collection from bot.application.discord.discord_service import DiscordService +from bot.application.miscellaneous.miscellaneous_service import MiscellaneousService from bot.application.student.student_service import StudentService from bot.application.task.kick_unregistered_user_task import KickUnregisteredUserTask from bot.application.task.sentence_of_the_day_task import SentenceOfTheDayTask from bot.domain.task.task import Task from bot.resource.cog.association.association import AssociationCog from bot.resource.cog.error_handler.error_handler import ErrorHandlerCog +from bot.resource.cog.miscellaneous.miscellaneous import MiscellaneousCog from bot.resource.cog.registration.register_member import RegisterMemberCog from bot.config.environment.context.application_context import ApplicationContext from bot.config.constants import ConfigurationFilename @@ -53,6 +55,9 @@ def _instantiate_association_cog(self) -> AssociationCog: def _instantiate_register_member_cog(self) -> RegisterMemberCog: return RegisterMemberCog() + def _instantiate_miscellaneous_cog(self) -> MiscellaneousCog: + return MiscellaneousCog() + def _instantiate_error_handler_cog(self) -> ErrorHandlerCog: return ErrorHandlerCog() @@ -63,15 +68,20 @@ def _instantiate_student_repository( return CachedStudentRepository(student_repository) def _instantiate_student_service( - self, student_repository: StudentRepository + self, discord_client: DiscordClient, student_repository: StudentRepository ) -> StudentService: - return StudentService(student_repository) + return StudentService(discord_client, student_repository) def _instantiate_discord_service( self, discord_client: DiscordClient, student_repository: StudentRepository ) -> DiscordService: return DiscordService(discord_client, student_repository) + def _instantiate_miscellaneous_service( + self, discord_client: DiscordClient + ) -> MiscellaneousService: + return MiscellaneousService(discord_client, self._configuration.dashboard_port) + def _instantiate_tasks(self, discord_client: DiscordClient) -> List[Task]: return [ KickUnregisteredUserTask( diff --git a/bot/config/environment/dotenv_configuration.py b/bot/config/environment/dotenv_configuration.py index 9ecd3b7..768623a 100644 --- a/bot/config/environment/dotenv_configuration.py +++ b/bot/config/environment/dotenv_configuration.py @@ -64,3 +64,7 @@ def server_id(self) -> int: @property def logger_filename(self) -> str: return self.__get_string(DotenvConfigurationKey.LOGGER_FILENAME) + + @property + def dashboard_port(self) -> int: + return self.__get_int(DotenvConfigurationKey.DASHBOARD_PORT) diff --git a/bot/resource/cog/association/association.py b/bot/resource/cog/association/association.py index a68216c..99a2faa 100644 --- a/bot/resource/cog/association/association.py +++ b/bot/resource/cog/association/association.py @@ -5,14 +5,12 @@ from bot.resource.cog.association.embed.asetin_embed import AsetinEmbed from bot.config.logger.logger import Logger from bot.config.service_locator import ServiceLocator -from bot.domain.discord_client.discord_client import DiscordClient from bot.resource.decorator.prohibit_self_message import prohibit_self_message class AssociationCog(commands.Cog, name="Association"): def __init__(self): - self.__bot = ServiceLocator.get_dependency(DiscordClient) self.__logger: Logger = ServiceLocator.get_dependency(Logger) @commands.command( diff --git a/bot/resource/cog/miscellaneous/__init__.py b/bot/resource/cog/miscellaneous/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/resource/cog/miscellaneous/miscellaneous.py b/bot/resource/cog/miscellaneous/miscellaneous.py new file mode 100644 index 0000000..e8b24ec --- /dev/null +++ b/bot/resource/cog/miscellaneous/miscellaneous.py @@ -0,0 +1,43 @@ +from discord import Message +from discord.ext import commands +from discord.ext.commands import Context + +from bot.application.miscellaneous.miscellaneous_service import MiscellaneousService +from bot.config.logger.logger import Logger +from bot.config.service_locator import ServiceLocator +from bot.domain.constants import DiscordRole +from bot.domain.discord_client.discord_client import DiscordClient +from bot.resource.decorator.prohibit_self_message import prohibit_self_message +from bot.resource.decorator.role_check import role_check + + +class MiscellaneousCog(commands.Cog, name="Miscellaneous"): + def __init__(self): + self.__bot = ServiceLocator.get_dependency(DiscordClient) + self.__logger: Logger = ServiceLocator.get_dependency(Logger) + self.__miscellaneous_service: MiscellaneousService = ( + ServiceLocator.get_dependency(MiscellaneousService) + ) + + @commands.command( + name="dashboard", + help="!dashboard", + brief="Retourne le lien du dashboard.", + ) + @commands.dm_only() + @prohibit_self_message() + @role_check(DiscordRole.ASETIN, DiscordRole.ADMIN) + async def get_dashboard_url(self, context: Context): + self.__logger.info( + f"Exécution de la commande par {context.message.author}", + method="get_dashboard_url", + ) + + message: Message = context.message + + dashboard_url: str = self.__miscellaneous_service.retrieve_dashboard_url() + await message.channel.send(dashboard_url) + + self.__logger.info( + "La commande a été exécutée avec succès.", method="get_dashboard_url" + ) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 15605cd..d928bf1 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -9,4 +9,8 @@ services: volumes: - /etc/localtime:/etc/localtime:ro - ./logs:/buggybot/log + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + - HOST_IP=host.docker.internal restart: always diff --git a/tests/application/test_student_service.py b/tests/application/test_student_service.py index 9441477..dae719e 100644 --- a/tests/application/test_student_service.py +++ b/tests/application/test_student_service.py @@ -70,11 +70,12 @@ async def test__given_no_students__when_add_student__then_student_is_added( logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) student_repository: StudentRepository = InMemoryStudentRepository([]) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) await student_service.add_student( A_NI, A_STUDENT_FIRSTNAME, A_STUDENT_LASTNAME, A_PROGRAM_CODE @@ -88,14 +89,15 @@ async def test__given_registered_student__when_add_same_student__then_student_al logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) registered_student: Student = given_registered_student(A_NI, A_DISCORD_ID) student_repository: StudentRepository = InMemoryStudentRepository( [registered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyRegisteredException): await student_service.add_student( @@ -110,12 +112,13 @@ async def test__given_a_student__when_add_already_existing_student__then_student logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) a_student: Student = given_unregistered_student(A_NI) student_repository: StudentRepository = InMemoryStudentRepository([a_student]) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyExistsException): await student_service.add_student( @@ -130,14 +133,15 @@ async def test__given_unregistered_student__when_register_student__then_student_ logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) unregistered_student: Student = given_unregistered_student(A_NI) student_repository: StudentRepository = InMemoryStudentRepository( [unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) await student_service.register_student(A_NI, A_DISCORD_ID) @@ -150,14 +154,15 @@ async def test__given_unregistered_student__when_force_register_student__then_st discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = True ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) unregistered_student: Student = given_unregistered_student(A_NI) student_repository: StudentRepository = InMemoryStudentRepository( [unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) await student_service.force_register_student(A_NI, A_DISCORD_ID) @@ -170,14 +175,15 @@ async def test__given_unregistered_student_and_discord_user_id_not_on_server__wh discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = False ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) unregistered_student: Student = given_unregistered_student(A_NI) student_repository: StudentRepository = InMemoryStudentRepository( [unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(UserNotInServerException): await student_service.force_register_student(A_NI, ANOTHER_DISCORD_ID) @@ -191,11 +197,12 @@ async def test__given_no_students__when_force_register_student__then_student_not discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = True ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) student_repository: StudentRepository = InMemoryStudentRepository([]) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentNotFoundException): await student_service.force_register_student(A_NI, A_DISCORD_ID) @@ -209,14 +216,15 @@ async def test__given_already_registered_student__when_force_register_student__t discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = True ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) register_student: Student = given_registered_student(A_NI, A_DISCORD_ID) student_repository: StudentRepository = InMemoryStudentRepository( [register_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyRegisteredException): await student_service.force_register_student(A_NI, A_DISCORD_ID) @@ -230,7 +238,6 @@ async def test__given_already_registered_student__when_force_register_with_same_ discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = True ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) register_student: Student = given_registered_student(A_NI, A_DISCORD_ID) unregistered_student: Student = given_unregistered_student(ANOTHER_NI) @@ -238,7 +245,9 @@ async def test__given_already_registered_student__when_force_register_with_same_ [register_student, unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyRegisteredException): await student_service.force_register_student(ANOTHER_NI, A_DISCORD_ID) @@ -251,7 +260,6 @@ async def test__given_already_registered_student__when_register_with_same_discor logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) registered_student: Student = given_registered_student(A_NI, A_DISCORD_ID) unregistered_student: Student = given_unregistered_student(ANOTHER_NI) @@ -259,7 +267,9 @@ async def test__given_already_registered_student__when_register_with_same_discor [registered_student, unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyRegisteredException): await student_service.register_student(ANOTHER_NI, A_DISCORD_ID) @@ -272,10 +282,11 @@ async def test__given_no_students_and_unregistered_student__when_register_studen logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) student_repository: StudentRepository = InMemoryStudentRepository([]) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentNotFoundException): await student_service.register_student(A_NI, A_DISCORD_ID) @@ -288,7 +299,6 @@ async def test__given_registered_student__when_register_student__then_raise_stud logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) registered_student: Student = given_registered_student(A_NI, A_DISCORD_ID) @@ -296,7 +306,9 @@ async def test__given_registered_student__when_register_student__then_raise_stud [registered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) with pytest.raises(StudentAlreadyRegisteredException): await student_service.register_student(A_NI, A_DISCORD_ID) @@ -309,14 +321,15 @@ async def test__given_registered_student__when_unregister_student__then_student_ logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) registered_student: Student = given_registered_student(A_NI, A_DISCORD_ID) student_repository: StudentRepository = InMemoryStudentRepository( [registered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) student_service.notify_on_student_unregistered = AsyncMock() await student_service.unregister_student(A_DISCORD_ID) @@ -333,14 +346,15 @@ async def test__given_unregistered_student__when_unregister_student__then_studen logger_mock = MagicMock(spec=Logger) discord_client_mock = MagicMock(spec=DiscordClient) ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) unregistered_student: Student = given_unregistered_student(A_NI) student_repository: StudentRepository = InMemoryStudentRepository( [unregistered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) student_service.notify_on_student_unregistered = AsyncMock() with pytest.raises(StudentNotFoundException): @@ -355,14 +369,15 @@ async def test__given_registered_student__when_force_unregister_student__then_st discord_client_mock = MagicMock(spec=DiscordClient) discord_client_mock.does_user_exists.return_value = True ServiceLocator.register_dependency(Logger, logger_mock) - ServiceLocator.register_dependency(DiscordClient, discord_client_mock) registered_student: Student = given_registered_student(A_NI, A_DISCORD_ID) student_repository: StudentRepository = InMemoryStudentRepository( [registered_student] ) - student_service: StudentService = StudentService(student_repository) + student_service: StudentService = StudentService( + discord_client_mock, student_repository + ) student_service.notify_on_student_unregistered = AsyncMock() await student_service.force_unregister_student(A_NI)