from __future__ import absolute_import, division, print_function, annotations import types from copy import deepcopy import pytest from _pytest.monkeypatch import MonkeyPatch from ansible_collections.famedly.matrix.plugins.module_utils import matrix from ansible_collections.famedly.matrix.plugins.modules import matrix_state from ansible_collections.famedly.matrix.tests.unit.mock_nio.MatrixNioBase import ( MatrixNioBase, ) from ansible_collections.famedly.matrix.tests.unit.mock_nio.MatrixNioSuccess import ( MatrixNioSuccess, ) from ansible_collections.famedly.matrix.tests.unit.mock_nio.room import failure from ansible_collections.famedly.matrix.tests.unit.mock_nio.utils.RoomSimulator import ( RoomSimulator, RoomEvents, ) from ansible_collections.famedly.matrix.tests.unit.mock_nio.utils.ClientSimulator import ( ClientSimulator, ) from ansible_collections.famedly.matrix.tests.unit.utils import ( AnsibleExitJson, AnsibleFailJson, set_module_args, exit_json, fail_json, assert_expression, ) class TestAnsibleModuleMatrixState: @staticmethod def patchAnsibleNioModule( monkeypatch: MonkeyPatch, mock_class: type(MatrixNioBase) ): # Mock ansible functions monkeypatch.setattr(matrix.AnsibleModule, "exit_json", exit_json) monkeypatch.setattr(matrix.AnsibleModule, "fail_json", fail_json) # Mock MatrixNio for method in MatrixNioBase.__dict__: if isinstance( getattr(mock_class, method), (types.FunctionType, types.BuiltinFunctionType), ): monkeypatch.setattr( matrix.AsyncClient, method, getattr(mock_class, method) ) monkeypatch.setattr(matrix.AsyncClient, "logged_in", False) # Setup RoomSimulator room_simulator = RoomSimulator() room_simulator.add_room( "!existingroomid:matrix.example.tld", "#existingroom:matrix.example.tld" ) room_simulator.add_room( "!otherroomid:matrix.example.tld", "#otherroom:matrix.example.tld" ) dummy_event = deepcopy(RoomEvents.M_ROOM_DUMMY) dummy_event["sender"] = "myuser" dummy_event["state_key"] = "mystatekey" room_simulator.send_event( room_id="!existingroomid:matrix.example.tld", event=dummy_event ) room_simulator.send_event( room_id="!otherroomid:matrix.example.tld", event=dummy_event ) monkeypatch.setenv("ROOM_SIMULATOR", room_simulator.export()) # Setup ClientSimulator client_simulator = ClientSimulator() client_simulator.join("!existingroomid:matrix.example.tld") monkeypatch.setenv("CLIENT_SIMULATOR", client_simulator.export()) # In room; Event already sent def test_no_changes(self, monkeypatch): self.patchAnsibleNioModule(monkeypatch, MatrixNioSuccess) set_module_args( { "hs_url": "matrix.example.tld", "user_id": "myuser", "password": "supersecretpassword", "room_id": "!existingroomid:matrix.example.tld", "event_type": "m.room.dummy", "state_key": "mystatekey", "content": RoomEvents.M_ROOM_DUMMY["content"], } ) with pytest.raises(AnsibleExitJson) as result: matrix_state.main() ansible_result = result.value.result assert_expression(ansible_result["changed"] is False) # Not in room; Event already sent def test_not_in_room_fail(self, monkeypatch): self.patchAnsibleNioModule(monkeypatch, MatrixNioSuccess) set_module_args( { "hs_url": "matrix.example.tld", "user_id": "myuser", "password": "supersecretpassword", "room_id": "!otherroomid:matrix.example.tld", "event_type": "m.room.dummy", "state_key": "mystatekey", "content": RoomEvents.M_ROOM_DUMMY["content"], } ) with pytest.raises(AnsibleFailJson) as result: matrix_state.main() ansible_result = result.value.result assert_expression( ansible_result["msg"] == "Not in the room you're trying to set state for." ) # Not in room; Event already sent def test_joined_rooms_fail(self, monkeypatch): class TestClass(failure.RoomJoinedRooms, MatrixNioSuccess): pass self.patchAnsibleNioModule(monkeypatch, TestClass) set_module_args( { "hs_url": "matrix.example.tld", "user_id": "myuser", "password": "supersecretpassword", "room_id": "!otherroomid:matrix.example.tld", "event_type": "m.room.dummy", "state_key": "mystatekey", "content": RoomEvents.M_ROOM_DUMMY["content"], } ) with pytest.raises(AnsibleFailJson) as result: matrix_state.main() ansible_result = result.value.result assert_expression(ansible_result["msg"] == "Couldn't get joined rooms.") # In room; Event not send yet def test_send_event(self, monkeypatch): self.patchAnsibleNioModule(monkeypatch, MatrixNioSuccess) set_module_args( { "hs_url": "matrix.example.tld", "user_id": "myuser", "password": "supersecretpassword", "room_id": "!existingroomid:matrix.example.tld", "event_type": "m.room.dummy", "state_key": "myotherstatekey", "content": RoomEvents.M_ROOM_DUMMY["content"], } ) with pytest.raises(AnsibleExitJson) as result: matrix_state.main() ansible_result = result.value.result assert_expression(ansible_result["changed"] is True) # In room; send Event def test_send_event_fail(self, monkeypatch): class TestClass(failure.RoomPutState, MatrixNioSuccess): pass self.patchAnsibleNioModule(monkeypatch, TestClass) set_module_args( { "hs_url": "matrix.example.tld", "user_id": "myuser", "password": "supersecretpassword", "room_id": "!existingroomid:matrix.example.tld", "event_type": "m.room.dummy", "state_key": "myotherstatekey", "content": RoomEvents.M_ROOM_DUMMY["content"], } ) with pytest.raises(AnsibleFailJson) as result: matrix_state.main() ansible_result = result.value.result assert_expression("Couldn't set state" in ansible_result["msg"])