# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2020  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import base64
import json
import os
from unittest import mock

import pytest
from django.utils.encoding import force_str

import tests.utils
from passerelle.contrib.solis_afi_mss.models import SolisAfiMss
from passerelle.utils.jsonresponse import APIError


@pytest.fixture
def connector(db):
    return tests.utils.setup_access_rights(
        SolisAfiMss.objects.create(
            slug='test',
            base_url='https://solis-afi-mss.example.net/',
            ged_url='https://solis-ged-mss.example.net/',
            ged_basic_auth_username='jdoe',
            ged_basic_auth_password='xxx',
        )
    )


TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'solis_afi_mss')


def json_get_data(filename):
    with open(os.path.join(TEST_BASE_DIR, "%s.json" % filename)) as fd:
        return json.dumps(json.load(fd))


def get_media_file(filename):
    with open(os.path.join(TEST_BASE_DIR, "%s" % filename), 'rb') as desc:
        return desc.read()


def response(status_code, content):
    return tests.utils.FakedResponse(content=content, status_code=status_code)


IS_ALIVE = response(200, json_get_data('isAlive'))

RECHERCHE_PAR_EMAIL_1 = response(200, json_get_data('rechercherParEmail_389227'))
RECHERCHE_PAR_EMAIL_2 = response(200, json_get_data('rechercherParEmail_388412'))
RECHERCHE_PAR_EMAIL_3 = response(200, json_get_data('rechercherParEmail_388420'))
RECHERCHE_PAR_EMAIL_4 = response(200, json_get_data('rechercherParEmail_388405'))
RECHERCHE_PAR_EMAIL_NONE = response(200, json_get_data('rechercherParEmail_none'))

GET_IMPOSITION_PAR_AGENT_4 = response(200, json_get_data('getImpositionsParAgent_388405'))
GET_IMPOSITION_4 = response(200, json_get_data('getImposition_388405_2019'))
GET_IMPOSITION_NONE = response(200, "")
GET_IMPOSITION_204 = response(204, "")

DECLARER_IMPOT_1 = response(200, json_get_data('declarerImpot_389227'))
DECLARER_IMPOT_500 = response(500, json_get_data('declarerImpot_error'))

CALCULER = response(200, json_get_data('calculer'))
CALCULER_500 = response(500, json_get_data('calculer_error'))

DEPOSER_4 = response(200, json_get_data('deposer_388405'))

GET_AIDES_PAR_AGENT_1 = response(200, json_get_data('getAidesParAgent_389227'))
GET_AIDES_PAR_AGENT_4 = response(200, json_get_data('getAidesParAgent_388405'))


def get_endpoint(name):
    return tests.utils.generic_endpoint_url('solis-afi-mss', name)


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'status_code, json_content, a_dict',
    [
        (200, 'not json', None),
        (500, '{"message": "help"}', {'message': 'help'}),
        (500, 'not json', None),
    ],
)
def test_request_error(mocked_get, app, connector, status_code, json_content, a_dict):
    mocked_get.side_effect = [response(status_code, json_content)]
    with pytest.raises(APIError) as exc:
        connector.request('some-url')
    assert exc.value.err
    if status_code == 200:
        assert exc.value.http_status == 200
        assert exc.value.args[0] == "invalid JSON content:'%s'" % json_content
    else:
        assert exc.value.data['status_code'] == status_code
        assert exc.value.data['json_content'] == a_dict


@mock.patch('passerelle.utils.Request.get')
def test_check_status(mocked_get, app, connector):
    mocked_get.side_effect = [IS_ALIVE]
    connector.check_status()
    assert mocked_get.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/main/isAlive/',
            headers={'Accept': 'application/json'},
            params=None,
        )
    ]


@mock.patch('passerelle.utils.Request.get')
def test_check_status_error(mocked_get, app, connector):
    mocked_get.side_effect = [response(500, '')]
    with pytest.raises(APIError):
        connector.check_status()


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, adults, children',
    [
        (
            RECHERCHE_PAR_EMAIL_1,
            [
                (389227, 'Jacques ROUSSEAU'),
                (434729, 'Rina DI MARINO'),
            ],
            [
                (389229, 'Lola ROUSSEAU'),
                (389230, 'Nicolas ROUSSEAU'),
                (389231, 'Mélina ROUSSEAU'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_2,
            [
                (388412, 'Louise PIED'),
            ],
            [
                (388413, 'KEVIN PIED'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_3,
            [
                (388420, 'Marie-Noëlle BASDEVANT'),
                (434728, 'PIETRO BARTOLOMEO'),
            ],
            [],
        ),
        (
            RECHERCHE_PAR_EMAIL_4,
            [
                (388405, 'Jean-Christophe HUREL'),
                (434727, 'CAROLE HUREL'),
            ],
            [
                (388407, 'Camille HUREL'),
                (388408, 'Valentin HUREL'),
            ],
        ),
    ],
)
def test_search_from_email(mocked_get, app, connector, response1, adults, children):
    mocked_get.side_effect = [response1]
    result = connector.search_from_email('foo@dummy.org')
    assert mocked_get.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/agent/rechercherParEmail/',
            headers={'Accept': 'application/json'},
            params={'adresseMail': 'foo@dummy.org'},
        )
    ]
    assert result['index'] == adults[0][0]
    assert [(x['id'], x['text']) for x in result['adults']] == adults
    assert [(x['id'], x['text']) for x in result['children']] == children


@mock.patch('passerelle.utils.Request.get')
def test_search_from_email_error(mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_NONE]
    with pytest.raises(APIError) as exc:
        connector.search_from_email('foo@dummy.org')
    assert str(exc.value) == "L'adresse mail n'appartient à aucun agent"
    assert mocked_get.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/agent/rechercherParEmail/',
            headers={'Accept': 'application/json'},
            params={'adresseMail': 'foo@dummy.org'},
        )
    ]


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, family',
    [
        (
            RECHERCHE_PAR_EMAIL_1,
            [
                (389227, 'Jacques ROUSSEAU'),
                (434729, 'Rina DI MARINO'),
                (389229, 'Lola ROUSSEAU'),
                (389230, 'Nicolas ROUSSEAU'),
                (389231, 'Mélina ROUSSEAU'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_2,
            [
                (388412, 'Louise PIED'),
                (388413, 'KEVIN PIED'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_3,
            [
                (388420, 'Marie-Noëlle BASDEVANT'),
                (434728, 'PIETRO BARTOLOMEO'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_4,
            [
                (388405, 'Jean-Christophe HUREL'),
                (434727, 'CAROLE HUREL'),
                (388407, 'Camille HUREL'),
                (388408, 'Valentin HUREL'),
            ],
        ),
    ],
)
def test_family(mocked_get, app, connector, response1, family):
    mocked_get.side_effect = [response1]
    endpoint = get_endpoint('family') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert not resp.json['err']
    assert [(x['id'], x['text']) for x in resp.json['data']] == family


@mock.patch('passerelle.utils.Request.get')
def test_family_error(mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_NONE]
    endpoint = get_endpoint('family') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert resp.json['err']
    assert resp.json['err_desc'] == "L'adresse mail n'appartient à aucun agent"


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, index, name',
    [
        (RECHERCHE_PAR_EMAIL_1, 389227, 'Jacques ROUSSEAU'),
        (RECHERCHE_PAR_EMAIL_2, 388412, 'Louise PIED'),
        (RECHERCHE_PAR_EMAIL_3, 388420, 'Marie-Noëlle BASDEVANT'),
        (RECHERCHE_PAR_EMAIL_4, 388405, 'Jean-Christophe HUREL'),
    ],
)
def test_agent(mocked_get, app, connector, response1, index, name):
    mocked_get.side_effect = [response1]
    endpoint = get_endpoint('agent') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert not resp.json['err']
    assert resp.json['data']['id'] == index
    assert resp.json['data']['text'] == name


@mock.patch('passerelle.utils.Request.get')
def test_agent_contacts(mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_1]
    endpoint = get_endpoint('agent') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert not resp.json['err']
    assert resp.json['data']['id'] == 389227
    assert resp.json['data']['text'] == "Jacques ROUSSEAU"
    assert resp.json['data']['adresse']['codePostal'] == 75014
    assert resp.json['data']['coordonnees']['numeroPortable'] == "0688888888"
    assert resp.json['data']['coordonnees']['adresseMailPerso'] == "jr@example.org"


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, adults',
    [
        (
            RECHERCHE_PAR_EMAIL_1,
            [
                (389227, 'Jacques ROUSSEAU'),
                (434729, 'Rina DI MARINO'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_2,
            [
                (388412, 'Louise PIED'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_3,
            [
                (388420, 'Marie-Noëlle BASDEVANT'),
                (434728, 'PIETRO BARTOLOMEO'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_4,
            [
                (388405, 'Jean-Christophe HUREL'),
                (434727, 'CAROLE HUREL'),
            ],
        ),
    ],
)
def test_adults(mocked_get, app, connector, response1, adults):
    mocked_get.side_effect = [response1]
    endpoint = get_endpoint('adults') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert not resp.json['err']
    assert [(x['id'], x['text']) for x in resp.json['data']] == adults


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, children',
    [
        (
            RECHERCHE_PAR_EMAIL_1,
            [
                (389229, 'Lola ROUSSEAU'),
                (389230, 'Nicolas ROUSSEAU'),
                (389231, 'Mélina ROUSSEAU'),
            ],
        ),
        (
            RECHERCHE_PAR_EMAIL_2,
            [
                (388413, 'KEVIN PIED'),
            ],
        ),
        (RECHERCHE_PAR_EMAIL_3, []),
        (
            RECHERCHE_PAR_EMAIL_4,
            [
                (388407, 'Camille HUREL'),
                (388408, 'Valentin HUREL'),
            ],
        ),
    ],
)
def test_children(mocked_get, app, connector, response1, children):
    mocked_get.side_effect = [response1]
    endpoint = get_endpoint('children') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert not resp.json['err']
    assert [(x['id'], x['text']) for x in resp.json['data']] == children


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_update_contacts(mocked_post, mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_1]
    mocked_post.side_effect = [RECHERCHE_PAR_EMAIL_1]
    endpoint = get_endpoint('update-contact')
    payload = {
        'adresseMailPerso': 'jdoe@example.org',
        'numeroPortable': '0611111111',
        'numeroTelephonePerso': '0122222222',
        'numeroTelephoneTravail': '033333333',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert mocked_post.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/agent/updateCoordonnees/',
            headers={'Accept': 'application/json'},
            json={
                'indexAgent': '389227',
                'adresseMailPerso': 'jdoe@example.org',
                'numeroPortable': '0611111111',
                'numeroTelephonePerso': '0122222222',
                'numeroTelephoneTravail': '033333333',
            },
        )
    ]
    assert not resp.json['err']


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_update_contacts_partial(mocked_post, mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_1]
    mocked_post.side_effect = [RECHERCHE_PAR_EMAIL_1]
    endpoint = get_endpoint('update-contact')

    # fields not provided are not updated
    payload = {
        'numeroPortable': '0611111111',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert mocked_post.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/agent/updateCoordonnees/',
            headers={'Accept': 'application/json'},
            json={
                'indexAgent': '389227',
                'numeroPortable': '0611111111',
            },
        )
    ]
    assert not resp.json['err']


@mock.patch('passerelle.utils.Request.get')
def test_update_error(mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_1]
    endpoint = get_endpoint('update-contact')
    resp = app.post_json(endpoint, params={}, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "missing parameters: 'email'."


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, response2, taxes',
    [(RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_PAR_AGENT_4, [(2018, '2018: 15000'), (2019, '2019: 1000')])],
)
def test_taxes(mocked_get, app, connector, response1, response2, taxes):
    mocked_get.side_effect = [response1, response2]
    endpoint = get_endpoint('taxes') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert mocked_get.mock_calls[1] == mock.call(
        'https://solis-afi-mss.example.net/afi/budget/getImpositionsParAgent/',
        headers={'Accept': 'application/json'},
        params={'indexAgent': str(json.loads(response1.content)['indexAgent'])},
    )
    assert not resp.json['err']
    assert [(x['id'], x['text']) for x in resp.json['data']] == taxes


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, response2, tax',
    [
        (RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_4, 1000),
        (RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_NONE, None),
        (RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_204, None),
    ],
)
def test_taxes_for_year(mocked_get, app, connector, response1, response2, tax):
    mocked_get.side_effect = [response1, response2]
    endpoint = get_endpoint('taxes') + '?email=foo@dummy.org&year=2019'
    resp = app.get(endpoint)
    assert mocked_get.mock_calls[1] == mock.call(
        'https://solis-afi-mss.example.net/afi/budget/getImposition/',
        headers={'Accept': 'application/json'},
        params={'indexAgent': str(json.loads(response1.content)['indexAgent']), 'anneeImposition': '2019'},
    )
    assert not resp.json['err']
    if tax:
        assert len(resp.json['data']) == 1
        assert resp.json['data'][0]['montantImposition'] == tax
    else:
        assert resp.json['data'] == []


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize('response1, response2', [(RECHERCHE_PAR_EMAIL_NONE, None)])
def test_taxes_error(mocked_get, app, connector, response1, response2):
    mocked_get.side_effect = [response1, response2]
    endpoint = get_endpoint('taxes') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert resp.json['err']
    assert resp.json['err_desc'] == "L'adresse mail n'appartient à aucun agent"


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
@pytest.mark.parametrize(
    'response1, response2',
    [
        (RECHERCHE_PAR_EMAIL_1, DECLARER_IMPOT_1),
    ],
)
def test_declare_tax(mocked_post, mocked_get, app, connector, response1, response2):
    mocked_get.side_effect = [response1]
    mocked_post.side_effect = [response2]
    endpoint = get_endpoint('declare-tax')
    payload = {
        'indexImposition': '368',
        'anneeImposition': '2011',
        'nombrePartImposition': '3.2',
        'montantImposition': '777.77',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert mocked_post.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/budget/declarerImpot/',
            headers={'Accept': 'application/json'},
            json={
                'indexAgent': '389227',
                'indexImposition': '368',
                'anneeImposition': '2011',
                'nombrePartImposition': '3.2',
                'montantImposition': '777.77',
            },
        )
    ]
    data = json.loads(response2.content)
    data.pop('err')
    data.pop('err_desc')
    assert resp.json == {'err': 0, 'data': data}


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
@pytest.mark.parametrize(
    'response1, response2',
    [
        (RECHERCHE_PAR_EMAIL_NONE, None),
        (RECHERCHE_PAR_EMAIL_4, DECLARER_IMPOT_500),
    ],
)
def test_declare_tax_error(mocked_post, mocked_get, app, connector, response1, response2):
    mocked_get.side_effect = [response1]
    mocked_post.side_effect = [response2]
    endpoint = get_endpoint('declare-tax')
    payload = {
        'indexImposition': '368',
        'anneeImposition': '3000 BC',
        'nombrePartImposition': '3.2',
        'montantImposition': '777.77',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert resp.json['err']
    if not response2:
        assert resp.json['err_desc'] == "L'adresse mail n'appartient à aucun agent"
    else:
        assert 'error status:500' in resp.json['err_desc']

    resp = app.post_json(endpoint, params={}, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "missing parameters: 'email'."


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, ratio',
    [
        (CALCULER, 52.33),
    ],
)
def test_simulate_quotient(mocked_get, app, connector, response1, ratio):
    mocked_get.side_effect = [response1]
    endpoint = get_endpoint('simulate-quotient') + '?code=2&nb_parts=2.2&amount=222.22'
    resp = app.get(endpoint)
    assert mocked_get.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/budget/calculer/',
            headers={'Accept': 'application/json'},
            params={'codeCalcul': '2', 'nbrPartImposition': '2.2', 'mntImposition': '222.22'},
        )
    ]
    data = json.loads(response1.content)
    data.pop('err')
    data.pop('err_desc')
    assert resp.json == {'err': 0, 'data': data}
    assert resp.json['data']['resultatCalcul'] == ratio


@mock.patch('passerelle.utils.Request.get')
def test_simulate_quotient_error(mocked_get, app, connector):
    mocked_get.side_effect = [CALCULER_500]
    endpoint = get_endpoint('simulate-quotient') + '?code=2&nb_parts=2.2&amount=222.22'
    resp = app.get(endpoint)
    assert resp.json['err']
    assert 'error status:500' in resp.json['err_desc']


@mock.patch('passerelle.utils.Request.get')
@pytest.mark.parametrize(
    'response1, response2, helps',
    [
        (RECHERCHE_PAR_EMAIL_4, GET_AIDES_PAR_AGENT_1, []),
        (
            RECHERCHE_PAR_EMAIL_4,
            GET_AIDES_PAR_AGENT_4,
            [
                (37145, '2020-05-26 (En attente)'),
                (37146, '2020-05-26 (En attente)'),
                (37149, '2020-06-11 (En attente)'),
                (37152, '2020-09-29 (En attente)'),
                (37153, '2020-09-29 (En attente)'),
                (37154, '2020-09-29 (En attente)'),
                (37155, '2020-09-29 (En attente)'),
            ],
        ),
    ],
)
def test_helps(mocked_get, app, connector, response1, response2, helps):
    mocked_get.side_effect = [response1, response2]
    endpoint = get_endpoint('helps') + '?email=foo@dummy.org'
    resp = app.get(endpoint)
    assert mocked_get.mock_calls[1] == mock.call(
        'https://solis-afi-mss.example.net/afi/aide/getAidesParAgent/',
        headers={'Accept': 'application/json'},
        params={'indexAgent': str(json.loads(response1.content)['indexAgent'])},
    )
    assert not resp.json['err']
    assert [(x['id'], x['text']) for x in resp.json['data']] == helps


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
@pytest.mark.parametrize(
    'response1, response2',
    [
        (RECHERCHE_PAR_EMAIL_4, DEPOSER_4),
    ],
)
def test_demand_help(mocked_post, mocked_get, app, connector, response1, response2):
    mocked_get.side_effect = [response1]
    mocked_post.side_effect = [response2]
    endpoint = get_endpoint('demand-help')

    payload = {
        'codeTypeAide': '24',
        'natureTypeAide': 'A',
        'individusConcernes': '388407:388408',
        'dateDebut': '2020-07-15',
        'dateFin': '2020-07-31',
        'montantFacture': '2222.22',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert mocked_post.mock_calls == [
        mock.call(
            'https://solis-afi-mss.example.net/afi/aide/deposer/',
            headers={'Accept': 'application/json'},
            json={
                'indexAgent': '388405',
                'codeTypeAide': '24',
                'natureTypeAide': 'A',
                'individusConcernes': [{'indexIndividu': '388407'}, {'indexIndividu': '388408'}],
                'dateDebut': '2020-07-15',
                'dateFin': '2020-07-31',
                'montantFacture': '2222.22',
            },
        )
    ]
    data = json.loads(response2.content)
    data.pop('err')
    data.pop('err_desc')
    assert resp.json == {'err': 0, 'data': data}


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
@pytest.mark.parametrize(
    'response1, response2',
    [
        (RECHERCHE_PAR_EMAIL_NONE, None),
    ],
)
def test_demand_help_error(mocked_post, mocked_get, app, connector, response1, response2):
    mocked_get.side_effect = [response1]
    mocked_post.side_effect = [response2]
    endpoint = get_endpoint('demand-help')

    payload = {
        'email': 'foo@dummy.org',
        'codeTypeAide': '24',
        'natureTypeAide': 'A',
        'individusConcernes': '388407:388408',
        'dateDebut': '2020-07-15',
        'dateFin': '2020-07-31',
        'montantFacture': '2222.22',
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert resp.json['err']
    assert resp.json['err_desc'] == "L'adresse mail n'appartient à aucun agent"

    resp = app.post_json(endpoint, params={}, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "missing parameters: 'email'."


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_add_document(mocked_post, mocked_get, app, connector):
    mocked_get.return_value = RECHERCHE_PAR_EMAIL_1
    mocked_post.return_value = response(200, json.dumps({'toto': 'polp le poulpe'}))
    endpoint = get_endpoint('add-document')

    payload = {
        'codeGedDocument': 9,
        'document': {
            'filename': '201x201.jpg',
            'content_type': 'image/jpeg',
            'content': force_str(base64.b64encode(get_media_file('201x201.jpg'))),
        },
    }

    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert mocked_post.mock_calls[0][1][0] == 'https://solis-ged-mss.example.net/ged/web/document/deposer'
    assert mocked_post.mock_calls[0][2]['auth'] == ('jdoe', 'xxx')
    assert mocked_post.mock_calls[0][2]['files']['document'][1] == get_media_file('201x201.jpg')
    assert mocked_post.mock_calls[0][2]['params'] == {
        'codeGedDocument': 9,
        'typeIdMetierClassement': 'INDIVIDU',
        'idMetierClassement': '389227',
    }
    assert not resp.json['err']

    payload['codeGedDocument'] = 16
    resp = app.post_json(endpoint + '?indexAideFinanciere=37191', params=payload)
    assert mocked_post.mock_calls[1][2]['files']['document'][1] == get_media_file('201x201.jpg')
    assert mocked_post.mock_calls[1][2]['params'] == {
        'codeGedDocument': 16,
        'typeIdMetierClassement': 'AIDEFINANCIERE',
        'idMetierClassement': '37191',
    }
    assert not resp.json['err']


@mock.patch('passerelle.utils.Request.get')
def test_add_document_error(mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_NONE]
    endpoint = get_endpoint('add-document')

    resp = app.post_json(endpoint + '?email=foo@dummy.org', params={}, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "'codeGedDocument' is a required property"

    payload = {'codeGedDocument': 9}
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "'document' is a required property"

    payload['document'] = 'plop'
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "document: 'plop' is not of type 'object'"

    payload['document'] = {}
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "document: 'filename' is a required property"

    payload['document'] = {'filename': 'foo.jpg', 'content_type': 'foo/bar', 'content': '42'}
    resp = app.post_json(endpoint, params=payload, status=400)
    assert resp.json['err']
    assert resp.json['err_desc'] == "'email' or 'indexAideFinanciere' is a required property"

    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert resp.json['err']
    assert resp.json['err_desc'] == "L'adresse mail n'appartient à aucun agent"


@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_add_document_wrong_code_ged(mocked_post, mocked_get, app, connector):
    mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_1]
    mocked_post.side_effect = [
        response(
            500,
            json.dumps(
                {
                    "logref": "2ee75216-7bec-4040-9d91-c67565bc6f88",
                    "message": "Erreur non g\u00e9r\u00e9e par une application cliente: Le document n'existe pas",
                }
            ),
        )
    ]
    endpoint = get_endpoint('add-document')

    payload = {
        'codeGedDocument': 42,
        'document': {
            'filename': '201x201.jpg',
            'content_type': 'image/jpeg',
            'content': force_str(base64.b64encode(get_media_file('201x201.jpg'))),
        },
    }
    resp = app.post_json(endpoint + '?email=foo@dummy.org', params=payload)
    assert resp.json['err']
    assert "Le document n'existe pas" in resp.json['data']['json_content']['message']
