"""Test user_devices model.""" import textwrap from unittest.mock import call from owsresponse import response import pytest from tests.unit.conftest import get_session_mock from users.constants import SONY_BRAND from users.models import devices from users.utils import api_utils @pytest.mark.parametrize( ('data', 'query_arguments'), [ # without device_id ( { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123'}, 'identity_data': {}, }, { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123'}, 'identity_data': {}, }, ), # with optional device_id param ( { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': { 'endpointArn': 'test123', 'deviceId': 'B0088190-D7C8-45B5-A02C-7C4D4657D5FC', }, 'identity_data': {}, }, { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': { 'endpointArn': 'test123', 'deviceId': 'B0088190-D7C8-45B5-A02C-7C4D4657D5FC', }, 'identity_data': {}, }, ), # with optional localization ( { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123'}, 'identity_data': {'localization': 'en'}, }, { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123'}, 'identity_data': {'localization': 'en'}, }, ), # with optional brand awal ( { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123', 'brand': 'awal'}, 'identity_data': {}, }, { 'identity_id': 'abcde1234', 'push_token': 'foo-2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123', 'brand': 'awal'}, 'identity_data': {}, }, ), # with optional brand sme ( { 'identity_id': 'abcde1234', 'push_token': 'token_2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123', 'brand': SONY_BRAND}, 'identity_data': {}, }, { 'identity_id': 'abcde1234', 'push_token': 'token_2345', 'platform_type': 'ios', 'device_data': {'endpointArn': 'test123', 'brand': SONY_BRAND}, 'identity_data': {}, }, ), ], ) def test_create_push_notification_device(data, query_arguments, make_graph_node, mocker): """Test create_push_notification_device when a new node is created.""" db_response = [ {'device': make_graph_node(node_id=11, labels=('Device'), data=api_utils.to_camel(data))} ] session_mock = get_session_mock(db_response) with mocker.patch('users.models.devices.get_session', return_value=session_mock): devices.create_push_notification_device(**data) assert session_mock.run.call_count == 2 assert session_mock.run.call_args[0] == ( 'MATCH (i: Identity)\n WHERE i.id = $identity_id\n MERGE (d:Device {\n pushToken: $push_token,\n platformType: $platform_type\n })\n SET d += $device_data, i += $identity_data\n MERGE (i)-[r:HAS_DEVICE]->(d)\n SET r.dateCreated = localdatetime()\n RETURN d as device', # noqa: E501 ) assert session_mock.run.call_args[1] == query_arguments @pytest.mark.parametrize( ('node_data', 'expected_result', 'brand'), [ # no nodes match ([], response.Response([]), None), # one node ( [{'d': {'deviceId': 'xyz', 'id': 1}, 'i': {'id': 'abc', 'auth0UserId': 'def'}}], response.Response( [({'device_id': 'xyz', 'id': 1}, {'id': 'abc', 'auth0_user_id': 'def'})] ), None, ), # one node and sme brand ( [{'d': {'deviceId': 'xyz', 'id': 1}, 'i': {'id': 'abc', 'auth0UserId': 'def'}}], response.Response( [({'device_id': 'xyz', 'id': 1}, {'id': 'abc', 'auth0_user_id': 'def'})] ), 'sme', ), ], ) def test_get_registrations(node_data, expected_result, brand, make_graph_node, mocker): """Test listing device registrations by id.""" device_id = 'xyz' platform_type = 'ios' expected_query = textwrap.dedent( f""" MATCH(i:Identity)-[:HAS_DEVICE]-(d:Device) WHERE d.deviceId = $device_id AND d.platformType = $platform_type{" AND d.brand = $brand" if brand else ""} RETURN i,d """ ) db_response = [] for data in node_data: db_response.append( { 'd': make_graph_node(node_id=data['d']['id'], data=data['d']), 'i': make_graph_node(node_id=data['i']['id'], data=data['i']), } ) session_mock = get_session_mock(db_response) with mocker.patch('users.models.devices.get_session', return_value=session_mock): result = devices.get_registrations(device_id, platform_type, brand) assert result.status == expected_result.status assert result.message == expected_result.message assert session_mock.run.call_args_list == [ call( expected_query, device_id='xyz', brand=brand, platform_type='ios', ) ] def test_get_push_notification_device(make_graph_node, mocker): """Test get_push_notification_device.""" identity_id = 'abcde1234' data = {'push_token': 'foo-2345', 'platform_type': 'ios'} db_response = [ {'device': make_graph_node(node_id=11, labels=('Device'), data=api_utils.to_camel(data))} ] session_mock = get_session_mock(db_response) with mocker.patch('users.models.devices.get_session', return_value=session_mock): devices.get_push_notification_device(identity_id) session_mock.run.assert_called_once() query, params = session_mock.run.call_args assert query == ( 'MATCH (i:Identity)-[:HAS_DEVICE]->(d:Device)\n WHERE i.id = $identity_id\n RETURN d as device', # noqa: E501 ) assert params == {'identity_id': identity_id} @pytest.mark.parametrize( ('identity_id', 'device_id', 'brand'), [('abcde1234', 'token_2345', None), ('abcde1234', 'token_2345', 'sme')], ) def test_delete_push_notification_device(identity_id, device_id, brand, make_graph_node, mocker): """Test delete_push_notification_device.""" session_mock = get_session_mock() expected_query = ( f"""MATCH (i:Identity)-[r:HAS_DEVICE]->(d:Device)\n WHERE i.id = $identity_id\n AND d.deviceId = $device_id {"AND d.brand = $brand" if brand else ""}\n SET r.dateDeleted = localdatetime()\n WITH r\n CALL apoc.refactor.setType(r, 'DELETED_HAS_DEVICE')\n YIELD input, output\n RETURN input, output""", # noqa: E501 ) with mocker.patch('users.models.devices.get_session', return_value=session_mock): devices.delete_push_notification_device(identity_id, device_id, brand) session_mock.run.assert_called_once() assert session_mock.run.call_args[0] == expected_query assert session_mock.run.call_args[1] == { 'identity_id': identity_id, 'device_id': device_id, 'brand': brand, } def test_get_device_by_push_token(make_graph_node, mocker, context): """Test get_device_by_push_token.""" identity_id = 'abcde1234' data = {'push_token': 'foo-2345', 'platform_type': 'ios'} db_response = [ {'d': make_graph_node(node_id=12, labels=('Device'), data=api_utils.to_camel(data))} ] session_mock = get_session_mock(db_response) with context: with mocker.patch('users.models.devices.get_session', return_value=session_mock): devices.get_device_by_push_token(identity_id, data['push_token'], data['platform_type']) session_mock.run.assert_called_once() query, params = session_mock.run.call_args assert query == ( 'MATCH(i:Identity)-[:HAS_DEVICE]-(d:Device)\n WHERE i.id = $identity_id AND\n d.pushToken = $push_token AND d.platformType = $platform_type\n RETURN d\n ', # noqa: E501 ) assert params == { 'push_token': data['push_token'], 'identity_id': identity_id, 'platform_type': data['platform_type'], }