import json from unittest import mock import pytest from django.urls import reverse import tests.utils from passerelle.apps.arpege_ecp.models import ArpegeECP from passerelle.utils.jsonresponse import APIError FAKE_HELLO_RESPONSE = """{"IsSuccess":true,"CodErreur":null,"LibErreur":null, "Data":"InteropAPI v1 (c) Arpège 2017"}""" FAKE_LOGIN_OIDC_RESPONSE = """{ "IsSuccess": true, "CodErreur": null, "LibErreur": null, "Data": { "AccessToken": "0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3", "RefreshToken": "a547bf4033ee1f00a0b06fc5c60a57700c95193aaf221a4b15e59cef606b748c" } }""" FAKE_USER_DEMANDS_RESPONSE = """{ "IsSuccess": true, "CodErreur": null, "LibErreur": null, "Data": { "Pagination": { "totalCount": 2, "totalPages": 1, "prevPageLink": "https://www.espace-citoyens.net/integration01/interop.api/v1/DemandesUsager?scope=data_administratives", "nextPageLink": "https://www.espace-citoyens.net/integration01/interop.api/v1/DemandesUsager?scope=data_administratives" }, "results": [ { "url": "https://www.espace-citoyens.net/integration01/espace-citoyens/Demande/SuiviDemande/WI", "data_administratives": { "CodeQualificationMetier": "TSTINTEGR", "CodeQualificationTypeDemande": "TST_A", "LibelleQualificationMetier": null, "LibelleQualificationTypeDemande": "Test A", "titre": "Demand A", "libelleFinTraitement": "", "date_depot": "2018-05-11", "heure_depot": "09:50:46", "date_fin_instruction": null, "code_etat": "DEPOSEE", "libelle_etat": "Deposee" }, "data_demandeur": null, "data_formulaire": null, "pieces_jointes": null, "data_etapes": null } ] } }""" @pytest.fixture def connector(db): resource = ArpegeECP.objects.create( slug='test', webservice_base_url='http://arpege.net', hawk_auth_id='id', hawk_auth_key='secret' ) return tests.utils.setup_access_rights(resource) @mock.patch('passerelle.utils.Request.get') def test_check_status(mocked_get, connector): mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_HELLO_RESPONSE, status_code=200) resp = connector.check_status() assert resp['data'] == 'InteropAPI v1 (c) Arpège 2017' @mock.patch('passerelle.utils.Request.get') def test_check_status_error(mocked_get, connector): hello_response = json.loads(FAKE_HELLO_RESPONSE) del hello_response['Data'] mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(hello_response), status_code=200) with pytest.raises(Exception) as error: connector.check_status() assert str(error.value) == 'Invalid credentials' def test_get_access_token(connector): with tests.utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE): token = connector.get_access_token('nameid') assert token == '0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3' with tests.utils.mock_url(response=FAKE_LOGIN_OIDC_RESPONSE, status_code=404): with pytest.raises(APIError) as error: token = connector.get_access_token('nameid') assert ' 404 ' in str(error.value) with tests.utils.mock_url(response='content', status_code=200): with pytest.raises(APIError) as error: token = connector.get_access_token('nameid') assert 'no JSON content' in str(error.value) with tests.utils.mock_url(response='content', status_code=200): with pytest.raises(APIError) as error: token = connector.get_access_token('nameid') assert 'no JSON content' in str(error.value) with tests.utils.mock_url( response='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}', status_code=200 ): with pytest.raises(APIError) as error: token = connector.get_access_token('nameid') assert str(error.value) == 'Auth FAIL (Fail)' @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) assert endpoint == '/arpege-ecp/test/api/users/nameid/forms' mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200) mocked_get.return_value = tests.utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=200) resp = app.get(endpoint) assert mocked_get.call_args[1]['params']['EtatDemande'] == 'DEPOSEE, ENCRSINSTR' assert resp.json['data'] for item in resp.json['data']: assert item['status'] == 'Deposee' assert item['title'] == 'Test A' assert item['name'] == 'Test A' assert ( item['url'] == 'https://www.espace-citoyens.net/integration01/espace-citoyens/Demande/SuiviDemande/WI' ) assert item['form_receipt_datetime'] == '2018-05-11T09:50:46' assert item['form_receipt_time'] == '09:50:46' assert item['readable'] is True assert item['form_status_is_endpoint'] is False resp = app.get(endpoint, params={'status': 'done'}) assert mocked_get.call_args[1]['params']['EtatDemande'] == 'TRAITEEPOS, TRAITEENEG, TRAITEE' @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms_failure(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200) mocked_get.return_value = tests.utils.FakedResponse( content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Failed to get demands"}', status_code=200, ) resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert result['err_desc'] == 'Failed to get demands (Fail)' def test_get_user_forms_failure_404(app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) with tests.utils.mock_url(url='/LoginParSubOIDC', response=FAKE_LOGIN_OIDC_RESPONSE): with tests.utils.mock_url(url='/DemandesUsager', status_code=404): resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert 'Arpege server is down' in result['err_desc'] assert ' 404 ' in result['err_desc'] @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms_failure_no_json(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200) mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200) resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert result['err_desc'] == "No JSON content returned: 'content'" @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms_failure_arpege_error(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) demands_response = json.loads(FAKE_USER_DEMANDS_RESPONSE) demands_response['Data']['results'][0]['data_administratives']['date_depot'] = None mocked_post.return_value = tests.utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200) mocked_get.return_value = tests.utils.FakedResponse(content=json.dumps(demands_response), status_code=200) resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert 'Arpege error: ' in result['err_desc'] @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms_failure_no_token(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) token_response = json.loads(FAKE_LOGIN_OIDC_RESPONSE) del token_response['Data']['AccessToken'] mocked_post.return_value = tests.utils.FakedResponse(content=json.dumps(token_response), status_code=200) mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200) resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert result['err_desc'] == 'Error on LoginParSubOIDC: missing Data/AccessToken' @mock.patch('passerelle.utils.Request.get') @mock.patch('passerelle.utils.Request.post') def test_get_user_forms_failure_wrong_token(mocked_post, mocked_get, app, connector): endpoint = reverse( 'generic-endpoint', kwargs={ 'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms', }, ) token_response = json.loads(FAKE_LOGIN_OIDC_RESPONSE) token_response['Data']['AccessToken'] = None mocked_post.return_value = tests.utils.FakedResponse(content=json.dumps(token_response), status_code=200) mocked_get.return_value = tests.utils.FakedResponse(content='content', status_code=200) resp = app.get(endpoint) result = resp.json assert result['err'] == 1 assert result['err_desc'] == 'Error on LoginParSubOIDC: Data/AccessToken is not string'