"""Network Participant handler tests.""" import json from unittest.mock import MagicMock import pytest from neo4j.time import DateTime as Neo4jDateTime from owsresponse import response from participant.handlers.network_participant import * # noqa from participant.logic import network_participant as network_participant_logic mock_network_participants_by_name_response = { 'items': [ { 'name': 'The A', 'networkId': 123, 'id': 1, 'createdAt': Neo4jDateTime.from_iso_format( '2020-01-01T00:00:00.000000000+00:00' ), 'modifiedAt': Neo4jDateTime.from_iso_format( '2020-02-01T00:00:00.000000000+00:00' ), }, { 'name': 'The B', 'networkId': 123, 'id': 2, 'createdAt': Neo4jDateTime.from_iso_format( '2020-01-01T00:00:00.000000000+00:00' ), 'modifiedAt': Neo4jDateTime.from_iso_format( '2020-02-01T00:00:00.000000000+00:00' ), }, { 'name': 'The C', 'networkId': 123, 'id': 3, 'createdAt': Neo4jDateTime.from_iso_format( '2020-01-01T00:00:00.000000000+00:00' ), 'modifiedAt': Neo4jDateTime.from_iso_format( '2020-02-01T00:00:00.000000000+00:00' ), }, ], 'pagination': {'total_records': 7}, } mock_network_participants_by_name_response_json = { 'items': [ { 'name': 'The A', 'networkId': 123, 'id': 1, 'createdAt': '2020-01-01T00:00:00.000000000+00:00', 'modifiedAt': '2020-02-01T00:00:00.000000000+00:00', }, { 'name': 'The B', 'networkId': 123, 'id': 2, 'createdAt': '2020-01-01T00:00:00.000000000+00:00', 'modifiedAt': '2020-02-01T00:00:00.000000000+00:00', }, { 'name': 'The C', 'networkId': 123, 'id': 3, 'createdAt': '2020-01-01T00:00:00.000000000+00:00', 'modifiedAt': '2020-02-01T00:00:00.000000000+00:00', }, ], 'pagination': {'total_records': 7}, } @pytest.fixture def network_ownership_mock(monkeypatch): """Mock the podcast's network ownership call.""" response_mock = MagicMock() response_mock.return_value = response.Response({'authorized': True}) monkeypatch.setattr( network_participant_logic, 'current_user_owns_network_id', response_mock ) return response_mock def test_network_participants_search(mocker, test_client, network_ownership_mock): """Test network participant search success.""" mock = mocker.patch( 'participant.logic.network_participant.search_network_participant', return_value=response.Response(mock_network_participants_by_name_response), ) name = 'the' network_id = 123 handler_response = test_client.get( f'/network-participants/search?name={name}' + f'&network_id={network_id}' ) result = json.loads(handler_response.data.decode()) mock.assert_called_with(name, network_id) assert handler_response.status_code == 200 assert result == mock_network_participants_by_name_response_json network_ownership_mock.assert_called_once_with(network_id) def test_network_participants_search_bad_name_results_in_400( mocker, test_client, network_ownership_mock ): """Test network participant search with bad name.""" mock = mocker.patch( 'participant.logic.network_participant.search_network_participant' ) name = '' handler_response = test_client.get(f'/network-participants/search?name={name}') result = json.loads(handler_response.data.decode()) mock.assert_not_called() assert handler_response.status_code == 400 assert result['code'] == 'invalid_usage' assert result['message'] == {'network_id': ['Field may not be null.']} network_ownership_mock.assert_not_called() def test_network_participants_search_bad_network_id( mocker, test_client, network_ownership_mock ): """Test network participant search with bad data.""" mock = mocker.patch( 'participant.logic.network_participant.search_network_participant' ) name = 'the' network_id = 'not a valid ID' handler_response = test_client.get( f'/network-participants/search?name={name}&network_id={network_id}' ) result = json.loads(handler_response.data.decode()) mock.assert_not_called() assert handler_response.status_code == 400 assert result['code'] == 'invalid_usage' assert result['message'] == { 'network_id': ['Not a valid integer.'], } network_ownership_mock.assert_not_called() @pytest.mark.parametrize( 'params', [ {'name': 'A name', 'network_id': 123}, {'name': 'B name', 'network_id': 123}, {'name': 'A name', 'network_id': 456}, ], ) def test_network_participant_create_success( mocker, test_client, params, network_ownership_mock ): """Test network participant create success.""" request_params = {key: str(value) for key, value in params.items() if value} create_network_participant_response_mock = {'mock': 'response'} status = 200 mock = mocker.patch( 'participant.logic.network_participant.create_network_participant', return_value=response.Response( create_network_participant_response_mock, status=status ), ) handler_response = test_client.post('/network-participants', json=request_params) result = json.loads(handler_response.data.decode()) mock.assert_called_with(**params) assert handler_response.status_code == status assert result == create_network_participant_response_mock network_ownership_mock.assert_called_once_with(params['network_id']) def test_network_participant_create_400_on_bad_input( mocker, test_client, network_ownership_mock ): """Test network participant create with bad data.""" name = 'A name' network_id = 'non integer' mock_create_network_participant_request = { 'name': f'{name}', 'network_id': f'{network_id}', } mock_create_network_participant_response = { 'code': 'validation_error', 'message': { 'error': { 'network_id': ['Not a valid integer.'], } }, } mock = mocker.patch( 'participant.logic.network_participant.create_network_participant' ) handler_response = test_client.post( '/network-participants', json=mock_create_network_participant_request ) result = json.loads(handler_response.data.decode()) # mock not called since input validator short-circuits on bad data mock.assert_not_called() assert handler_response.status_code == 400 assert result == mock_create_network_participant_response network_ownership_mock.assert_not_called() def test_network_participant_update_success( mocker, test_client, network_ownership_mock ): """Test network participant update success.""" name = 'A name' network_id = 123 mock_update_network_participant_request = { 'name': name, } mock_update_network_participant_request_cleaned = { 'name': name, } mock_update_network_participant_response = { 'name': name, 'networkId': network_id, 'id': 1234, 'createdAt': Neo4jDateTime.from_iso_format( '2020-01-01T00:00:00.000000000+00:00' ), 'modifiedAt': Neo4jDateTime.from_iso_format( '2020-02-01T00:00:00.000000000+00:00' ), } mock_update_network_participant_response_json = { 'name': name, 'networkId': network_id, 'id': 1234, 'createdAt': '2020-01-01T00:00:00.000000000+00:00', 'modifiedAt': '2020-02-01T00:00:00.000000000+00:00', } status = 200 node_id = 1 network_id = 1 mock = mocker.patch( 'participant.logic.network_participant.update_network_participant', return_value=response.Response( mock_update_network_participant_response, status=status ), ) handler_response = test_client.put( f'/network-participants/{node_id}/network/{network_id}', json=mock_update_network_participant_request, ) result = json.loads(handler_response.data.decode()) mock.assert_called_with( node_id, network_id, mock_update_network_participant_request_cleaned ) assert handler_response.status_code == status assert result == mock_update_network_participant_response_json network_ownership_mock.assert_called_once_with(network_id) def test_network_participant_update_400_on_bad_data( mocker, test_client, network_ownership_mock ): """Test network participant update with bad data.""" mock_update_network_participant_request = { 'unknown-key': 'blah blah blah', 'name': 'A name', } expected_response = { 'code': 'validation_error', 'message': {'error': {'unknown-key': ['Unknown field.']}}, } mock = mocker.patch( 'participant.logic.network_participant.update_network_participant', ) node_id = 9090 network_id = 1 handler_response = test_client.put( f'/network-participants/{node_id}/network/{network_id}', json=mock_update_network_participant_request, ) result = json.loads(handler_response.data.decode()) mock.assert_not_called() assert handler_response.status_code == 400 assert result == expected_response network_ownership_mock.assert_not_called() def test_get_label_participant_by_id_success(mocker, test_client): """Test get network participant by id success.""" mock = mocker.patch( 'participant.logic.network_participant.get_network_participant_by_id', return_value=response.Response( mock_network_participants_by_name_response['items'][0] ), ) network_participant_id = 1 handler_response = test_client.get( f'/network-participants/{network_participant_id}' ) result = json.loads(handler_response.data.decode()) mock.assert_called_with(network_participant_id) assert handler_response.status_code == 200 assert result == mock_network_participants_by_name_response_json['items'][0] def test_get_label_participant_by_id_error(mocker, test_client): """Test get network participant by id error.""" mock = mocker.patch( 'participant.logic.network_participant.get_network_participant_by_id', return_value=response.create_fatal_response('fatal_error'), ) network_participant_id = 1 handler_response = test_client.get( f'/network-participants/{network_participant_id}' ) json.loads(handler_response.data.decode()) mock.assert_called_with(network_participant_id) assert handler_response.status_code == 500