From 5f1ef9eb8825b724e67258ce87839a9fe11b64dc Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 9 Dec 2022 19:24:05 +0100
Subject: [PATCH 4/4] toulouse-maelis: use responses in tests (#72205)

---
 tests/data/toulouse_maelis/Q_create_child.xml |  25 -
 .../toulouse_maelis/Q_create_child_person.xml |  56 --
 .../data/toulouse_maelis/Q_create_family.xml  |  59 --
 .../data/toulouse_maelis/Q_create_person.xml  |  44 -
 tests/data/toulouse_maelis/Q_create_rl1.xml   |  31 -
 tests/data/toulouse_maelis/Q_create_rl2.xml   |  35 -
 .../Q_create_update_quotient.xml              |  23 -
 .../toulouse_maelis/Q_delete_child_person.xml |  20 -
 .../data/toulouse_maelis/Q_delete_person.xml  |  21 -
 tests/data/toulouse_maelis/Q_update_child.xml |  50 --
 .../Q_update_child_dietcode.xml               |  16 -
 .../Q_update_child_indicator.xml              |  24 -
 .../Q_update_child_medical_record.xml         |  44 -
 .../toulouse_maelis/Q_update_child_pai.xml    |  18 -
 .../toulouse_maelis/Q_update_child_person.xml |  36 -
 .../toulouse_maelis/Q_update_coordinate.xml   |  42 -
 .../data/toulouse_maelis/Q_update_family.xml  |  80 --
 .../data/toulouse_maelis/Q_update_person.xml  |  33 -
 tests/data/toulouse_maelis/Q_update_rl1.xml   |  35 -
 tests/data/toulouse_maelis/Q_update_rl2.xml   |  35 -
 .../toulouse_maelis/Q_update_rl_indicator.xml |  24 -
 tests/test_toulouse_maelis.py                 | 754 ++++++++----------
 tests/utils.py                                |  20 +-
 23 files changed, 338 insertions(+), 1187 deletions(-)
 delete mode 100644 tests/data/toulouse_maelis/Q_create_child.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_child_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_family.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_rl1.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_rl2.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_create_update_quotient.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_delete_child_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_delete_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child_dietcode.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child_indicator.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child_medical_record.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child_pai.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_child_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_coordinate.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_family.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_person.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_rl1.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_rl2.xml
 delete mode 100644 tests/data/toulouse_maelis/Q_update_rl_indicator.xml

diff --git a/tests/data/toulouse_maelis/Q_create_child.xml b/tests/data/toulouse_maelis/Q_create_child.xml
deleted file mode 100644
index fda5be56..00000000
--- a/tests/data/toulouse_maelis/Q_create_child.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:createChild xmlns:ns0="family.ws.maelis.sigec.com">
-      <numDossier>1312</numDossier>
-      <child>
-        <firstname>JANNIS</firstname>
-        <lastname>DOE</lastname>
-        <sexe>F</sexe>
-        <birth>
-          <dateBirth>1943-01-19</dateBirth>
-          <place>Port Arthur</place>
-        </birth>
-      </child>
-      <isForceCreateChild>false</isForceCreateChild>
-    </ns0:createChild>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_child_person.xml b/tests/data/toulouse_maelis/Q_create_child_person.xml
deleted file mode 100644
index 098a503a..00000000
--- a/tests/data/toulouse_maelis/Q_create_child_person.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateChildAutorization xmlns:ns0="family.ws.maelis.sigec.com">
-      <updateChildAutorizationRequest>
-        <numFamily>1312</numFamily>
-        <numPerson>613880</numPerson>
-        <personList>
-          <personInfo>
-            <num>614719</num>
-            <civility>MME</civility>
-            <lastname>BENT</lastname>
-            <firstname>AMEL</firstname>
-            <dateBirth>1985-06-21T00:00:00+02:00</dateBirth>
-            <sexe>F</sexe>
-            <contact>
-              <phone>0123456789</phone>
-              <mobile>0623456789</mobile>
-              <mail>abent@example.org</mail>
-            </contact>
-          </personInfo>
-          <personQuality>
-            <code>T</code>
-            <libelle>TANTE</libelle>
-          </personQuality>
-        </personList>
-        <personList>
-          <personInfo>
-            <civility>MME</civility>
-            <lastname>Ross</lastname>
-            <firstname>Diana</firstname>
-            <dateBirth>1944-03-26</dateBirth>
-            <sexe>F</sexe>
-            <contact>
-              <phone>0199999999</phone>
-              <mobile>0723456789</mobile>
-              <mail>dross@example.org</mail>
-            </contact>
-          </personInfo>
-          <personQuality>
-            <code>TUTEUR</code>
-          </personQuality>
-        </personList>
-        <bLeaveAlone>false</bLeaveAlone>
-        <bPhoto>true</bPhoto>
-      </updateChildAutorizationRequest>
-    </ns0:updateChildAutorization>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_family.xml b/tests/data/toulouse_maelis/Q_create_family.xml
deleted file mode 100644
index 2c6c285c..00000000
--- a/tests/data/toulouse_maelis/Q_create_family.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:createFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <category>ACCEUI</category>
-      <situation>C</situation>
-      <rl1>
-        <firstname>Jhon</firstname>
-        <lastname>Doe</lastname>
-        <quality>AU</quality>
-        <civility>M.</civility>
-        <birth>
-          <dateBirth>1938-07-26</dateBirth>
-          <place>Rabbat</place>
-          <countryCode>99350</countryCode>
-        </birth>
-        <adresse>
-          <idStreet>AM0330</idStreet>
-          <numComp>B</numComp>
-          <street1>Chateau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-        <profession>
-          <codeCSP>ART</codeCSP>
-        </profession>
-        <CAFInfo>
-          <organ>A10007752822</organ>
-        </CAFInfo>
-      </rl1>
-      <childList>
-        <firstname>Robert</firstname>
-        <lastname>Zimmerman</lastname>
-        <sexe>M</sexe>
-        <birth>
-          <dateBirth>1941-05-24</dateBirth>
-          <place>Saint-louis</place>
-          <communeCode>91122</communeCode>
-          <countryCode>99100</countryCode>
-        </birth>
-        <dietcode>RSV</dietcode>
-        <medicalRecord>
-          <vaccinList>
-            <code>DTC</code>
-            <vaccinationDate>1940-07-26</vaccinationDate>
-          </vaccinList>
-        </medicalRecord>
-      </childList>
-    </ns0:createFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_person.xml b/tests/data/toulouse_maelis/Q_create_person.xml
deleted file mode 100644
index 23619fc3..00000000
--- a/tests/data/toulouse_maelis/Q_create_person.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <emergencyPersonList>
-        <personList>
-          <numPerson>614059</numPerson>
-          <civility>MME</civility>
-          <firstname>KENY</firstname>
-          <lastname>ARKANA</lastname>
-          <dateBirth>1982-12-20T00:00:00+01:00</dateBirth>
-          <quality>T</quality>
-          <contact>
-            <phone>0123456789</phone>
-            <mail>pueblo@example.org</mail>
-          </contact>
-        </personList>
-        <personList>
-          <firstname>Mathias</firstname>
-          <lastname>Cassel</lastname>
-          <dateBirth>1972-01-01</dateBirth>
-          <sexe>M</sexe>
-          <quality>O</quality>
-          <contact>
-            <mobile>0623456789</mobile>
-          </contact>
-        </personList>
-      </emergencyPersonList>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_rl1.xml b/tests/data/toulouse_maelis/Q_create_rl1.xml
deleted file mode 100644
index fcc47161..00000000
--- a/tests/data/toulouse_maelis/Q_create_rl1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:createFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <category>ACCEUI</category>
-      <situation>C</situation>
-      <rl1>
-        <firstname>Jhon</firstname>
-        <lastname>Doe</lastname>
-        <quality>AU</quality>
-        <civility>M.</civility>
-        <birth>
-          <dateBirth>1938-07-26</dateBirth>
-        </birth>
-        <adresse>
-          <street1>Chateau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-      </rl1>
-    </ns0:createFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_rl2.xml b/tests/data/toulouse_maelis/Q_create_rl2.xml
deleted file mode 100644
index 076ce6a2..00000000
--- a/tests/data/toulouse_maelis/Q_create_rl2.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <rl2>
-        <firstname>JANE</firstname>
-        <lastname>DOE</lastname>
-        <maidenName>Smith</maidenName>
-        <quality>MERE</quality>
-        <civility>MME</civility>
-        <birth>
-          <dateBirth>1940-06-22</dateBirth>
-        </birth>
-        <adresse>
-          <num>170</num>
-          <street1>Chateau d'eau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-      </rl2>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_create_update_quotient.xml b/tests/data/toulouse_maelis/Q_create_update_quotient.xml
deleted file mode 100644
index 0d519a11..00000000
--- a/tests/data/toulouse_maelis/Q_create_update_quotient.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:createUpdateQuotient xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <personNumber>613878</personNumber>
-      <quotient>
-        <yearRev>2021</yearRev>
-        <dateStart>2022-10-01</dateStart>
-        <dateEnd>2023-01-31</dateEnd>
-        <mtt>1500.33</mtt>
-        <cdquo>QS</cdquo>
-      </quotient>
-    </ns0:createUpdateQuotient>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_delete_child_person.xml b/tests/data/toulouse_maelis/Q_delete_child_person.xml
deleted file mode 100644
index 165e664b..00000000
--- a/tests/data/toulouse_maelis/Q_delete_child_person.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateChildAutorization xmlns:ns0="family.ws.maelis.sigec.com">
-      <updateChildAutorizationRequest>
-        <numFamily>1312</numFamily>
-        <numPerson>613880</numPerson>
-        <bLeaveAlone>false</bLeaveAlone>
-        <bPhoto>true</bPhoto>
-      </updateChildAutorizationRequest>
-    </ns0:updateChildAutorization>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_delete_person.xml b/tests/data/toulouse_maelis/Q_delete_person.xml
deleted file mode 100644
index 71d80cce..00000000
--- a/tests/data/toulouse_maelis/Q_delete_person.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <emergencyPersonList/>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child.xml b/tests/data/toulouse_maelis/Q_update_child.xml
deleted file mode 100644
index 14ba3a7b..00000000
--- a/tests/data/toulouse_maelis/Q_update_child.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <childList>
-        <num>613880</num>
-        <firstname>JANNIS</firstname>
-        <lastname>DOE</lastname>
-        <sexe>F</sexe>
-        <birth>
-          <dateBirth>1943-01-19</dateBirth>
-          <place>Port Arthur</place>
-        </birth>
-        <bPhoto>true</bPhoto>
-        <bLeaveAlone>false</bLeaveAlone>
-        <authorizedPersonList>
-          <personInfo>
-            <num>614719</num>
-            <lastname>BENT</lastname>
-            <firstname>AMEL</firstname>
-            <dateBirth>1985-06-21T00:00:00+02:00</dateBirth>
-            <civility>MME</civility>
-            <sexe>F</sexe>
-            <contact>
-              <phone>0123456789</phone>
-              <mobile>0623456789</mobile>
-              <mail>abent@example.org</mail>
-            </contact>
-          </personInfo>
-          <personQuality>
-            <code>T</code>
-            <libelle>TANTE</libelle>
-          </personQuality>
-        </authorizedPersonList>
-      </childList>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child_dietcode.xml b/tests/data/toulouse_maelis/Q_update_child_dietcode.xml
deleted file mode 100644
index a38f924e..00000000
--- a/tests/data/toulouse_maelis/Q_update_child_dietcode.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:createOrUpdateChildDiet xmlns:ns0="family.ws.maelis.sigec.com">
-      <personNumber>613878</personNumber>
-      <code>RSV</code>
-    </ns0:createOrUpdateChildDiet>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child_indicator.xml b/tests/data/toulouse_maelis/Q_update_child_indicator.xml
deleted file mode 100644
index 2f4b3e3b..00000000
--- a/tests/data/toulouse_maelis/Q_update_child_indicator.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updatePersonIndicatorList xmlns:ns0="family.ws.maelis.sigec.com">
-      <numPerson>613880</numPerson>
-      <indicatorList>
-        <code>LUNETTE</code>
-        <isActive>true</isActive>
-      </indicatorList>
-      <indicatorList>
-        <code>AUTRE</code>
-        <note>rebellious</note>
-        <isActive>true</isActive>
-      </indicatorList>
-    </ns0:updatePersonIndicatorList>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child_medical_record.xml b/tests/data/toulouse_maelis/Q_update_child_medical_record.xml
deleted file mode 100644
index e51972e7..00000000
--- a/tests/data/toulouse_maelis/Q_update_child_medical_record.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateChildMedicalRecord xmlns:ns0="family.ws.maelis.sigec.com">
-      <updateChildMedicalRecordRequest>
-        <numPerson>613878</numPerson>
-        <medicalRecord>
-          <familyDoctor>
-            <name>Dre</name>
-            <phone>0612341234</phone>
-            <address>
-              <street1>Alameda</street1>
-              <zipcode>90220</zipcode>
-              <town>Compton</town>
-            </address>
-          </familyDoctor>
-          <allergy1>butterscotch, imitation butterscotch, glow-in-the-dark monster make-up, and shrimp</allergy1>
-          <allergy2>cauliflower</allergy2>
-          <comment1>the shrimp allergy isn't fully identified</comment1>
-          <comment2/>
-          <observ1>Ay Caramba!</observ1>
-          <observ2/>
-          <isAuthHospital>true</isAuthHospital>
-          <hospital>Springfield General Hospital</hospital>
-          <vaccinList>
-            <code>DTC</code>
-            <vaccinationDate>2011-01-11</vaccinationDate>
-          </vaccinList>
-          <vaccinList>
-            <code>ROR</code>
-            <vaccinationDate>2022-02-22</vaccinationDate>
-          </vaccinList>
-        </medicalRecord>
-      </updateChildMedicalRecordRequest>
-    </ns0:updateChildMedicalRecord>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child_pai.xml b/tests/data/toulouse_maelis/Q_update_child_pai.xml
deleted file mode 100644
index e0459c5c..00000000
--- a/tests/data/toulouse_maelis/Q_update_child_pai.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateChildPAI xmlns:ns0="family.ws.maelis.sigec.com">
-      <personNumber>613878</personNumber>
-      <code>PAIALI</code>
-      <dateDeb>2022-01-01</dateDeb>
-      <description>some text</description>
-    </ns0:updateChildPAI>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_child_person.xml b/tests/data/toulouse_maelis/Q_update_child_person.xml
deleted file mode 100644
index 1ed460f0..00000000
--- a/tests/data/toulouse_maelis/Q_update_child_person.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateChildAutorization xmlns:ns0="family.ws.maelis.sigec.com">
-      <updateChildAutorizationRequest>
-        <numFamily>1312</numFamily>
-        <numPerson>613880</numPerson>
-        <personList>
-          <personInfo>
-            <num>614719</num>
-            <civility>M.</civility>
-            <lastname>Bent</lastname>
-            <firstname>Angelo</firstname>
-            <dateBirth>1985-06-22</dateBirth>
-            <sexe>M</sexe>
-            <contact>
-              <phone>0102030405</phone>
-            </contact>
-          </personInfo>
-          <personQuality>
-            <code>O</code>
-          </personQuality>
-        </personList>
-        <bLeaveAlone>false</bLeaveAlone>
-        <bPhoto>true</bPhoto>
-      </updateChildAutorizationRequest>
-    </ns0:updateChildAutorization>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_coordinate.xml b/tests/data/toulouse_maelis/Q_update_coordinate.xml
deleted file mode 100644
index e74c3e78..00000000
--- a/tests/data/toulouse_maelis/Q_update_coordinate.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateCoordinate xmlns:ns0="family.ws.maelis.sigec.com">
-      <numDossier>1312</numDossier>
-      <numPerson>613878</numPerson>
-      <adresse>
-        <idStreet>AM0330</idStreet>
-        <num>169</num>
-        <numComp>B</numComp>
-        <street1>Château</street1>
-        <street2/>
-        <town>Paris</town>
-        <zipcode>75014</zipcode>
-      </adresse>
-      <profession>
-        <codeCSP>ART</codeCSP>
-        <profession>informaticien</profession>
-        <employerName>EO</employerName>
-        <phone>0123456789</phone>
-        <addressPro>
-          <num/>
-          <street/>
-          <zipcode/>
-          <town>Orl&#233;ans</town>
-        </addressPro>
-      </profession>
-      <CAFInfo>
-        <number>789</number>
-        <organ>A10007752822</organ>
-      </CAFInfo>
-    </ns0:updateCoordinate>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_family.xml b/tests/data/toulouse_maelis/Q_update_family.xml
deleted file mode 100644
index 4522bab5..00000000
--- a/tests/data/toulouse_maelis/Q_update_family.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>C</situation>
-      <rl1>
-        <firstname>Jhon</firstname>
-        <lastname>Doe</lastname>
-        <quality>AU</quality>
-        <civility>M.</civility>
-        <birth>
-          <dateBirth>1938-07-26</dateBirth>
-          <place>Rabbat</place>
-          <communeCode/>
-          <countryCode>99350</countryCode>
-        </birth>
-        <adresse>
-          <numComp>B</numComp>
-          <street1>Chateau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-        <profession>
-          <codeCSP>ART</codeCSP>
-        </profession>
-        <CAFInfo>
-          <organ>A10007752822</organ>
-        </CAFInfo>
-      </rl1>
-      <childList>
-        <firstname>Robert</firstname>
-        <lastname>Zimmerman</lastname>
-        <sexe>M</sexe>
-        <birth>
-          <dateBirth>1941-05-24</dateBirth>
-          <place>Duluth</place>
-        </birth>
-        <dietcode>RSV</dietcode>
-        <medicalRecord>
-          <vaccinList>
-            <code>DTC</code>
-            <vaccinationDate>1940-07-26</vaccinationDate>
-          </vaccinList>
-        </medicalRecord>
-        <paiInfoBean>
-          <code>PAIALI</code>
-        </paiInfoBean>
-      </childList>
-      <childList>
-        <num>613880</num>
-        <firstname>Brunelle</firstname>
-        <lastname>Doe</lastname>
-        <sexe>F</sexe>
-        <birth>
-          <dateBirth>1943-01-19</dateBirth>
-        </birth>
-      </childList>
-      <emergencyPersonList>
-        <personList>
-          <civility>MME</civility>
-          <firstname>Keny</firstname>
-          <lastname>Arkana</lastname>
-          <dateBirth>1982-12-20</dateBirth>
-          <sexe>F</sexe>
-          <quality>T</quality>
-        </personList>
-      </emergencyPersonList>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_person.xml b/tests/data/toulouse_maelis/Q_update_person.xml
deleted file mode 100644
index 7ccce44c..00000000
--- a/tests/data/toulouse_maelis/Q_update_person.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <emergencyPersonList>
-        <personList>
-          <numPerson>614059</numPerson>
-          <firstname>Mathias</firstname>
-          <lastname>Cassel</lastname>
-          <dateBirth>1972-01-01</dateBirth>
-          <sexe>M</sexe>
-          <quality>O</quality>
-          <contact>
-            <mobile>0623456789</mobile>
-          </contact>
-        </personList>
-      </emergencyPersonList>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_rl1.xml b/tests/data/toulouse_maelis/Q_update_rl1.xml
deleted file mode 100644
index 98d0e824..00000000
--- a/tests/data/toulouse_maelis/Q_update_rl1.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <rl1>
-        <firstname>Jhonny</firstname>
-        <lastname>Doe</lastname>
-        <quality>PERE</quality>
-        <civility>M.</civility>
-        <birth>
-          <dateBirth>1943-06-15</dateBirth>
-        </birth>
-        <adresse>
-          <num>170</num>
-          <street1>Chateau d'eau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-      </rl1>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_rl2.xml b/tests/data/toulouse_maelis/Q_update_rl2.xml
deleted file mode 100644
index 076ce6a2..00000000
--- a/tests/data/toulouse_maelis/Q_update_rl2.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
-      <dossierNumber>1312</dossierNumber>
-      <category>BI</category>
-      <situation>M</situation>
-      <flagCom>true</flagCom>
-      <nbChild>2</nbChild>
-      <rl2>
-        <firstname>JANE</firstname>
-        <lastname>DOE</lastname>
-        <maidenName>Smith</maidenName>
-        <quality>MERE</quality>
-        <civility>MME</civility>
-        <birth>
-          <dateBirth>1940-06-22</dateBirth>
-        </birth>
-        <adresse>
-          <num>170</num>
-          <street1>Chateau d'eau</street1>
-          <town>Paris</town>
-          <zipcode>75014</zipcode>
-        </adresse>
-      </rl2>
-    </ns0:updateFamily>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/Q_update_rl_indicator.xml b/tests/data/toulouse_maelis/Q_update_rl_indicator.xml
deleted file mode 100644
index 94087377..00000000
--- a/tests/data/toulouse_maelis/Q_update_rl_indicator.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
-  <soap-env:Header>
-    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
-      <wsse:UsernameToken>
-        <wsse:Username>maelis-webservice</wsse:Username>
-        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
-      </wsse:UsernameToken>
-    </wsse:Security>
-  </soap-env:Header>
-  <soap-env:Body>
-    <ns0:updatePersonIndicatorList xmlns:ns0="family.ws.maelis.sigec.com">
-      <numPerson>613878</numPerson>
-      <indicatorList>
-        <code>AVL</code>
-        <isActive>true</isActive>
-      </indicatorList>
-      <indicatorList>
-        <code>ETABSPEC</code>
-        <note>SNPP</note>
-        <isActive>true</isActive>
-      </indicatorList>
-    </ns0:updatePersonIndicatorList>
-  </soap-env:Body>
-</soap-env:Envelope>
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index 04b9742f..0f5ef10c 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -14,18 +14,18 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import logging
 import os
 from unittest import mock
 
 import pytest
 import responses
-from lxml import etree
 from requests.exceptions import ConnectionError
+from zeep import Settings
 
 from passerelle.contrib.toulouse_maelis.models import Link, Referential, ToulouseMaelis
 from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.soap import SOAPError
 from tests.utils import FakedResponse, ResponsesSoap, generic_endpoint_url, setup_access_rights
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'toulouse_maelis')
 
@@ -37,93 +37,102 @@ def get_xml_file(filename):
 
 CONNECTION_ERROR = ConnectionError('No address associated with hostname')
 FAMILY_SERVICE_WSDL = FakedResponse(content=get_xml_file('FamilyService.wsdl'), status_code=200)
 ACTIVITY_SERVICE_WSDL = FakedResponse(content=get_xml_file('ActivityService.wsdl'), status_code=200)
 INVOICE_SERVICE_WSDL = FakedResponse(content=get_xml_file('InvoiceService.wsdl'), status_code=200)
 FAILED_AUTH = FakedResponse(content=get_xml_file('R_failed_authentication.xml'), status_code=500)
 ISWSRUNNING_TRUE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'true', status_code=200)
 ISWSRUNNING_FALSE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'false', status_code=200)
-READ_FAMILY = FakedResponse(content=get_xml_file('R_read_family.xml'), status_code=200)
-READ_FAMILY_LAX = FakedResponse(content=get_xml_file('R_read_family_relax.xml'), status_code=200)
-READ_FAMILY_ORD = FakedResponse(content=get_xml_file('R_read_family_reordered.xml'), status_code=200)
-READ_FAMILY_QUOTIENT = FakedResponse(
-    content=get_xml_file('R_read_family_with_income_year.xml'), status_code=200
-)
-READ_RL1_FAMILY = FakedResponse(content=get_xml_file('R_read_family_with_only_rl1.xml'), status_code=200)
-IS_RL_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'true', status_code=200)
-IS_RL_EXISTS_FALSE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'false', status_code=200)
-IS_CHILD_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_child_exists.xml') % b'true', status_code=200)
-IS_CHILD_EXISTS_FALSE = FakedResponse(
-    content=get_xml_file('R_is_child_exists.xml') % b'false', status_code=200
-)
-CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200)
-CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200)
-CREATE_CHILD = FakedResponse(content=get_xml_file('R_create_child.xml'), status_code=200)
-CREATE_CHILD_ERR = FakedResponse(content=get_xml_file('R_create_child_error.xml'), status_code=200)
-UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200)
-UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200)
-UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500)
-UPDATE_QUOTIENT = FakedResponse(content=get_xml_file('R_create_update_quotient.xml'), status_code=200)
-UPDATE_QUOTIENT_500 = FakedResponse(
-    content=get_xml_file('R_create_update_quotient_soap_error.xml'), status_code=500
-)
-UPDATE_DIETCODE = FakedResponse(content=get_xml_file('R_update_child_dietcode.xml'), status_code=200)
-UPDATE_PAI = FakedResponse(content=get_xml_file('R_update_child_pai.xml'), status_code=200)
-UPDATE_PAI_500 = FakedResponse(content=get_xml_file('R_update_child_pai_soap_error.xml'), status_code=500)
-UPDATE_MEDICAL = FakedResponse(content=get_xml_file('R_update_child_medical_record.xml'), status_code=200)
-UPDATE_MEDICAL_500 = FakedResponse(
-    content=get_xml_file('R_update_child_medical_record_soap_error.xml'), status_code=500
-)
-UPDATE_CHILD_AUTO = FakedResponse(content=get_xml_file('R_update_child_authorization.xml'), status_code=200)
-UPDATE_INDICATOR = FakedResponse(content=get_xml_file('R_update_indicator.xml'), status_code=200)
-
-
-def assert_sent_payload(mocked_post, query_file):
-    soap_sent = etree.tostring(etree.fromstring(mocked_post.call_args.kwargs['data']), pretty_print=True)
-    expected = etree.tostring(etree.fromstring(get_xml_file(query_file)), pretty_print=True)
-    assert soap_sent.decode() == expected.decode()
 
 
 def get_endpoint(name):
     url = generic_endpoint_url('toulouse-maelis', name)
     assert url == '/toulouse-maelis/test/%s' % name
     return url
 
 
+@pytest.fixture()
+def family_service():
+    with ResponsesSoap(
+        wsdl_url='https://example.org/FamilyService?wsdl',
+        wsdl_content=get_xml_file('FamilyService.wsdl'),
+        settings=Settings(strict=False, xsd_ignore_sequence_order=True),
+    )() as mock:
+        yield mock
+
+
+@pytest.fixture()
+def activity_service():
+    with ResponsesSoap(
+        wsdl_url='https://example.org/ActivityService?wsdl',
+        wsdl_content=get_xml_file('ActivityService.wsdl'),
+        settings=Settings(strict=False, xsd_ignore_sequence_order=True),
+    )() as mock:
+        yield mock
+
+
+@pytest.fixture()
+def invoice_service():
+    with ResponsesSoap(
+        wsdl_url='https://example.org/InvoiceService?wsdl',
+        wsdl_content=get_xml_file('InvoiceService.wsdl'),
+        settings=Settings(strict=False, xsd_ignore_sequence_order=True),
+    )() as mock:
+        yield mock
+
+
 @pytest.fixture(scope='module')
 def django_db_setup(django_db_setup, django_db_blocker):
     with django_db_blocker.unblock():
         con = setup_access_rights(
             ToulouseMaelis.objects.get_or_create(
                 slug='test',
+                base_wsdl_url='https://example.org/',
                 zeep_wsse_username='maelis-webservice',
                 zeep_wsse_password='maelis-password',
             )[0]
         )
-        with mock.patch('passerelle.utils.Request.get') as mocked_get:
-            mocked_get.return_value = FAMILY_SERVICE_WSDL
-            with mock.patch('passerelle.utils.Request.post') as mocked_post:
-                mocked_post.side_effect = [
-                    FakedResponse(content=get_xml_file('R_read_category_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_child_indicator_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_civility_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_country_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_csp_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_dietcode_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_organ_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_pai_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_quality_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_quotient_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_rl_indicator_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_situation_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_street_list.xml'), status_code=200),
-                    FakedResponse(content=get_xml_file('R_read_vaccin_list.xml'), status_code=200),
-                ]
-                con.daily()
+
+        with responses.RequestsMock() as mock:
+            family_service = ResponsesSoap(
+                wsdl_url='https://example.org/FamilyService?wsdl',
+                wsdl_content=get_xml_file('FamilyService.wsdl'),
+                settings=Settings(strict=False, xsd_ignore_sequence_order=True),
+            )
+            mock.add(responses.GET, family_service.wsdl_url, body=family_service.wsdl_content, status=200)
+            family_service.add_soap_response(
+                mock, 'readCategoryList', get_xml_file('R_read_category_list.xml')
+            )
+            family_service.add_soap_response(
+                mock, 'readChildIndicatorList', get_xml_file('R_read_child_indicator_list.xml')
+            )
+            family_service.add_soap_response(
+                mock, 'readCivilityList', get_xml_file('R_read_civility_list.xml')
+            )
+            family_service.add_soap_response(mock, 'readCountryList', get_xml_file('R_read_country_list.xml'))
+            family_service.add_soap_response(mock, 'readCSPList', get_xml_file('R_read_csp_list.xml'))
+            family_service.add_soap_response(
+                mock, 'readDietCodeList', get_xml_file('R_read_dietcode_list.xml')
+            )
+            family_service.add_soap_response(mock, 'readOrganList', get_xml_file('R_read_organ_list.xml'))
+            family_service.add_soap_response(mock, 'readPAIList', get_xml_file('R_read_pai_list.xml'))
+            family_service.add_soap_response(mock, 'readQualityList', get_xml_file('R_read_quality_list.xml'))
+            family_service.add_soap_response(
+                mock, 'readQuotientList', get_xml_file('R_read_quotient_list.xml')
+            )
+            family_service.add_soap_response(
+                mock, 'readRLIndicatorList', get_xml_file('R_read_rl_indicator_list.xml')
+            )
+            family_service.add_soap_response(
+                mock, 'readSituationList', get_xml_file('R_read_situation_list.xml')
+            )
+            family_service.add_soap_response(mock, 'readStreetList', get_xml_file('R_read_street_list.xml'))
+            family_service.add_soap_response(mock, 'readVaccinList', get_xml_file('R_read_vaccin_list.xml'))
+            con.daily()
 
     # reset change in zeep private interface to bypass clear_cache fixture
     from zeep.cache import InMemoryCache
 
     InMemoryCache._cache = {}
 
 
 @pytest.fixture()
@@ -136,42 +145,36 @@ def test_call_with_wrong_wsdl_url(mocked_get, con):
     mocked_get.side_effect = CONNECTION_ERROR
     with pytest.raises(
         SOAPError,
         match='cannot be loaded: No address associated with hostname',
     ) as e:
         con.call('Family', 'isWSRunning')
     assert e.value.err == 1
     assert e.value.http_status == 200
-    assert e.value.url == 'https://demo-toulouse.sigec.fr/maelisws-toulouse/services/FamilyService?wsdl'
+    assert e.value.url == 'https://example.org/FamilyService?wsdl'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_call_with_wrong_credentials(mocked_post, mocked_get, con):
-    mocked_get.side_effect = [FAMILY_SERVICE_WSDL]
-    mocked_post.side_effect = [FAILED_AUTH]
+def test_call_with_wrong_credentials(family_service, con):
+    family_service.add_soap_response('isWSRunning', get_xml_file('R_failed_authentication.xml'), status=500)
     with pytest.raises(
         APIError,
         match='The security token could not be authenticated or authorized',
     ) as e:
         con.call('Family', 'isWSRunning')
     assert e.value.__dict__ == {
         'err': 1,
         'log_error': False,
         'http_status': 200,
         'err_code': 'Family-isWSRunning-ns1:FailedAuthentication',
     }
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_call(mocked_post, mocked_get, con):
-    mocked_get.side_effect = [FAMILY_SERVICE_WSDL]
-    mocked_post.side_effect = [ISWSRUNNING_TRUE]
+def test_call(family_service, con):
+    family_service.add_soap_response('isWSRunning', get_xml_file('R_is_ws_running.xml') % b'true')
     resp = con.call('Family', 'isWSRunning')
     assert resp is True
 
 
 @pytest.mark.parametrize(
     'get_responses, post_responses, exception',
     [
         (
@@ -290,66 +293,54 @@ def test_cron(db):
         'Sex',
         'Situation',
         'Street',
         'Vaccin',
     ]
     assert Referential.objects.count() == 230
 
 
-@pytest.fixture
-def family_service():
-    from zeep import Settings
-
-    with ResponsesSoap(
-        wsdl_url='https://demo-toulouse.sigec.fr/maelisws-toulouse/services/FamilyService?wsdl',
-        wsdl_content=get_xml_file('FamilyService.wsdl'),
-        settings=Settings(strict=False, xsd_ignore_sequence_order=True),
-    )() as mock:
-        yield mock
-
-
 def test_link(family_service, con, app):
     def request_check(request):
-        assert request.dossierNumber == 1313
+        assert request.dossierNumber == 1312
 
     family_service.add_soap_response(
         'readFamily', get_xml_file('R_read_family.xml'), request_check=request_check
     )
     url = get_endpoint('link')
     assert Link.objects.count() == 0
 
     params = {
         'family_id': '1312',
         'firstname': 'Jhon',
         'lastname': 'Doe',
         'dateBirth': '1938-07-26',
     }
-    resp = app.post_json(url + '?NameID=local&raise=1', params=params)
+    resp = app.post_json(url + '?NameID=local', params=params)
     assert Link.objects.count() == 1
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
     params['lastname'] = 'John'
     resp = app.post_json(url + '?NameID=local', params=params)
     assert Link.objects.count() == 1
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "RL1 does not match '1312' family"
 
 
 def test_link_additional_properties_error(con, app):
     url = get_endpoint('link')
-
     params = {
         'family_id': '1312',
         'firstname': 'Jhon',
         'lastname': 'Doe',
         'dateBirth': '1938-07-26',
         'plop': 42,
     }
+
     resp = app.post_json(url + '?NameID=local', params=params, status=400)
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == "Additional properties are not allowed ('plop' was unexpected)"
 
 
 def test_unlink(con, app):
     url = get_endpoint('unlink')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
@@ -381,29 +372,27 @@ def test_get_referential_value_not_found(con, caplog):
     assert con.get_referential_value('Civility', 'MR') == 'MR'
     assert len(caplog.records) == 1
     assert caplog.records[0].levelno == logging.WARNING
     assert caplog.records[0].message == "No 'MR' key into Maelis 'Civility' referential"
 
 
 def test_read_category_list(con, app):
     url = get_endpoint('read-category-list')
-
     resp = app.get(url)
     assert resp.json['err'] == 0
     assert resp.json['data'] == [
         {'id': 'BI', 'text': 'BIPARENTALE', 'code': 'BI', 'libelle': 'BIPARENTALE'},
         {'id': 'ACCEUI', 'text': "FAMILLE D'ACCUEIL", 'code': 'ACCEUI', 'libelle': "FAMILLE D'ACCUEIL"},
         {'id': 'MONO', 'text': 'MONOPARENTALE', 'code': 'MONO', 'libelle': 'MONOPARENTALE'},
     ]
 
 
 def test_read_country_list(con, app):
     url = get_endpoint('read-country-list')
-
     resp = app.get(url)
     assert resp.json['err'] == 0
     assert len(resp.json['data']) == 3
     assert resp.json['data'] == [
         {'id': '212', 'code': '212', 'text': 'AFGHANISTAN', 'libelle': 'AFGHANISTAN'},
         {'id': '303', 'code': '303', 'text': 'AFRIQUE DU SUD', 'libelle': 'AFRIQUE DU SUD'},
         {'id': '125', 'code': '125', 'text': 'ALBANIE', 'libelle': 'ALBANIE'},
     ]
@@ -581,17 +570,16 @@ def test_read_rl_indicator_list(con, app):
             'label': 'Etablissement spécialisé',
             'typeDesc': 'NOTE',
         },
     ]
 
 
 def test_read_sex_list(con, app):
     url = get_endpoint('read-sex-list')
-
     resp = app.get(url)
     assert resp.json['err'] == 0
     assert resp.json['data'] == [
         {'id': 'F', 'text': 'Féminin'},
         {'id': 'M', 'text': 'Masculin'},
     ]
 
 
@@ -673,22 +661,21 @@ def test_read_vaccin_list(con, app):
             'id': 'DTC',
             'code': 'DTC',
             'text': 'DIPHTERIE TETANOS COQUELUCHE',
             'libelle': 'DIPHTERIE TETANOS COQUELUCHE',
         },
     ]
 
 
-@pytest.mark.parametrize("read_family", [READ_FAMILY, READ_FAMILY_LAX, READ_FAMILY_ORD])
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_family(mocked_post, mocked_get, read_family, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = read_family
+@pytest.mark.parametrize(
+    "xml", ['R_read_family.xml', 'R_read_family_relax.xml', 'R_read_family_reordered.xml']
+)
+def test_read_family(family_service, xml, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file(xml))
     url = get_endpoint('read-family')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local')
     assert resp.json['err'] == 0
     data = resp.json['data']
     del data['RL1']
     del data['RL2']
@@ -805,17 +792,17 @@ def test_read_family(mocked_post, mocked_get, read_family, con, app):
         'bLeaveAlone': False,
         'insurance': None,
         'subscribeSchoolList': [],
         'mother': {'num': 613963, 'civility': 'MME', 'firstname': 'JANE', 'lastname': 'DOE'},
         'father': {'num': 613878, 'civility': 'M.', 'firstname': 'JHON', 'lastname': 'DOE'},
         'rl': None,
         'subscribeActivityList': [],
     }
-    if read_family != READ_FAMILY_LAX:
+    if xml != 'R_read_family_relax.xml':
         assert resp.json['data']['childList'][0]['paiInfoBean'] == {
             'code': 'PAIALI',
             'code_text': 'ALIMENTAIRE',
             'dateDeb': '2022-01-01T00:00:00+01:00',
             'dateFin': '2022-12-31T00:00:00+01:00',
             'description': 'bla bla PAI',
         }
     else:
@@ -902,34 +889,28 @@ def test_read_family(mocked_post, mocked_get, read_family, con, app):
 def test_read_family_not_linked_error(con, app):
     url = get_endpoint('read-family')
 
     resp = app.get(url + '?NameID=')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_rl1(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_rl1(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613878')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'JHON'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_rl1_with_income_year(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY_QUOTIENT
+def test_read_rl1_with_income_year(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_income_year.xml'))
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613878&income_year=2020')
     assert resp.json['err'] == 0
     assert resp.json['data']['quotientList'] == [
         {
             'yearRev': 2020,
@@ -938,21 +919,18 @@ def test_read_rl1_with_income_year(mocked_post, mocked_get, con, app):
             'mtt': 1500.33,
             'cdquo': 'QS',
             'cdquo_text': 'QUOTIENT SCOLAIRE',
             'codeUti': None,
         }
     ]
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_rl2(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_rl2(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613879')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {
         'num': '613879',
         'lastname': 'DOE',
@@ -1007,210 +985,170 @@ def test_read_rl2(mocked_post, mocked_get, con, app):
 def test_read_rl_not_linked_error(con, app):
     url = get_endpoint('read-rl')
 
     resp = app.get(url + '?NameID=local&rl_id=613879')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_rl_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_rl_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' RL on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_person(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&person_id=614059')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'KENY'
 
 
 def test_read_person_not_linked_error(con, app):
     url = get_endpoint('read-person')
 
     resp = app.get(url + '?NameID=local&person_id=614059')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_person_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_person_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&person_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' emergency person on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_child(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_child(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-child')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&child_id=613880')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'JANNIS'
 
 
 def test_read_child_not_linked_error(con, app):
     url = get_endpoint('read-child')
 
     resp = app.get(url + '?NameID=local&child_id=613880')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_child_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_child_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-child')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&child_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' child on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_child_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_child_person(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-child-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&child_id=613880&person_id=614719')
     assert resp.json['err'] == 0
     assert resp.json['data']['personInfo']['firstname'] == 'AMEL'
 
 
 def test_read_child_person_not_linked_error(con, app):
     url = get_endpoint('read-child-person')
 
     resp = app.get(url + '?NameID=local&child_id=613880&person_id=614719')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_child_person_no_child_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_child_person_no_child_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-child-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&child_id=42&person_id=614719')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '42' child on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_read_child_person_no_person_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_read_child_person_no_person_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('read-child-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&child_id=613880&person_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' authorized person on '613880' child"
 
 
-@pytest.mark.parametrize(
-    'post_response, result',
-    [
-        (IS_RL_EXISTS_TRUE, True),
-        (IS_RL_EXISTS_FALSE, False),
-    ],
-)
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_is_rl_exists(mocked_post, mocked_get, post_response, result, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = post_response
+@pytest.mark.parametrize('string, result', [(b'true', True), (b'false', False)])
+def test_is_rl_exists(string, result, family_service, con, app):
+    family_service.add_soap_response('isRLExists', get_xml_file('R_is_rl_exists.xml') % string)
     url = get_endpoint('is-rl-exists')
-
     params = {
         'firstname': 'Jhon',
         'lastname': 'Doe',
         'dateBirth': '1938-07-26',
     }
+
     resp = app.post_json(url, params=params)
     assert resp.json['err'] == 0
     assert resp.json['data'] == result
 
 
 def test_is_rl_exists_schema_error(con, app):
     url = get_endpoint('is-rl-exists')
-
     params = {
         'firstname': 'Jhon',
         'lastname': 'Doe',
         'dateBirth': '1938-07-26 more text',
     }
+
     resp = app.post_json(url, params=params, status=400)
     assert resp.json['err'] == 1
     assert "does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'" in resp.json['err_desc']
 
 
-@pytest.mark.parametrize(
-    'post_response, result',
-    [
-        (IS_CHILD_EXISTS_TRUE, True),
-        (IS_CHILD_EXISTS_FALSE, False),
-    ],
-)
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_is_child_exists(mocked_post, mocked_get, post_response, result, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = post_response
+@pytest.mark.parametrize('string, result', [(b'true', True), (b'false', False)])
+def test_is_child_exists(family_service, string, result, con, app):
+    family_service.add_soap_response('isChildExists', get_xml_file('R_is_rl_exists.xml') % string)
     url = get_endpoint('is-child-exists')
-
     params = {
         'firstname': 'Doe',
         'lastname': 'Jhonny allen',
         'dateBirth': '1942-11-27',
     }
+
     resp = app.post_json(url, params=params)
     assert resp.json['err'] == 0
     assert resp.json['data'] == result
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_family(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_FAMILY
+def test_create_family(family_service, con, app):
+    def request_check(request):
+        assert request.emergencyPersonList[0]['firstname'] == 'Keny'
+
+    family_service.add_soap_response(
+        'createFamily', get_xml_file('R_create_family.xml'), request_check=request_check
+    )
     url = get_endpoint('create-family')
     params = {
         'category': 'ACCEUI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
         'rl1/quality': 'AU',
@@ -1220,30 +1158,35 @@ def test_create_family(mocked_post, mocked_get, con, app):
         'rl1/birth/place': 'Rabbat',
         'rl1/adresse/idStreet': 'AM0330',
         'rl1/adresse/street1': 'Chateau',
         'rl1/adresse/town': 'Paris',
         'rl1/adresse/zipcode': '75014',
         'rl1/adresse/numComp': 'B',
         'rl1/profession/codeCSP': 'ART',
         'rl1/CAFInfo/organ': 'A10007752822',
+        'emergencyPersonList/0/civility': 'MME',
+        'emergencyPersonList/0/firstname': 'Keny',
+        'emergencyPersonList/0/lastname': 'Arkana',
+        'emergencyPersonList/0/sexe': 'F',
+        'emergencyPersonList/0/dateBirth': '1982-12-20',
+        'emergencyPersonList/0/quality': 'T',
         'childList/0/lastname': 'Zimmerman',
         'childList/0/firstname': 'Robert',
         'childList/0/sexe': 'M',
         'childList/0/birth/dateBirth': '1941-05-24',
         'childList/0/birth/place': 'Saint-louis',
         'childList/0/birth/communeCode': '91122',
         'childList/0/birth/countryCode': '99100',
         'childList/0/dietcode': 'RSV',
         'childList/0/medicalRecord/vaccinList/0/code': 'DTC',
         'childList/0/medicalRecord/vaccinList/0/vaccinationDate': '1940-07-26',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_family.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {
         'number': 196545,
         'password': '394634V2',
         'rl1ErrorList': [],
         'childErrorList': [],
     }
     assert Link.objects.get(resource=con, family_id='196545', name_id='local')
@@ -1285,21 +1228,18 @@ def test_create_family_already_linked_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'already-linked'
     assert resp.json['err_desc'] == 'User already linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_family_maelis_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_FAMILY_ERR
+def test_create_family_maelis_error(family_service, con, app):
+    family_service.add_soap_response('createFamily', get_xml_file('R_create_family_error.xml'))
     url = get_endpoint('create-family')
     params = {
         'category': 'ACCEUI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
         'rl1/quality': 'AU',
@@ -1348,21 +1288,23 @@ def test_create_family_wrong_referential_key_error(con, app):
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc']
         == "childList/0/medicalRecord/vaccinList/0/code key value 'plop' do not belong to 'Vaccin' referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_family(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_FAMILY
+def test_update_family(family_service, con, app):
+    def request_check(request):
+        assert request.emergencyPersonList['personList'][0]['firstname'] == 'Keny'
+
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('update-family')
     params = {
         'category': 'BI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
         'rl1/quality': 'AU',
@@ -1395,17 +1337,16 @@ def test_update_family(mocked_post, mocked_get, con, app):
         'childList/1/firstname': 'Brunelle',
         'childList/1/lastname': 'Doe',
         'childList/1/birth/dateBirth': '1943-01-19',
         'childList/1/sexe': 'F',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_family.xml')
     assert resp.json['err'] == 0
     assert resp.json['data']['number'] == 196544
     assert not resp.json['data']['childErrorList']
 
 
 def test_update_family_not_linked_error(con, app):
     url = get_endpoint('update-family')
     params = {
@@ -1421,21 +1362,18 @@ def test_update_family_not_linked_error(con, app):
         'rl1/adresse/zipcode': '75014',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_family_maelis_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_FAMILY_ERR
+def test_update_family_maelis_error(family_service, con, app):
+    family_service.add_soap_response('updateFamily', get_xml_file('R_update_family_error.xml'))
     url = get_endpoint('update-family')
     params = {
         'category': 'ACCEUI',
         'situation': 'C',
         'childList/0/lastname': 'Zimmerman',
         'childList/0/firstname': 'Robert',
         'childList/0/sexe': 'M',
         'childList/0/birth/dateBirth': '1941-05-24',
@@ -1443,21 +1381,20 @@ def test_update_family_maelis_error(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'E65a'
     assert "E65a : Il existe déjà un enfant" in resp.json['err_desc']
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_family_soap_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_FAMILY_500
+def test_update_family_soap_error(family_service, con, app):
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family_soap_error.xml'), status=500
+    )
     url = get_endpoint('update-family')
     params = {
         'nbChild': '100',
         'category': 'BI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
@@ -1514,37 +1451,33 @@ def test_update_family_wrong_referential_key_error(con, app):
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc']
         == "childList/0/medicalRecord/vaccinList/0/code key value 'plop' do not belong to 'Vaccin' referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_rl1(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_FAMILY
+def test_create_rl1(family_service, con, app):
+    family_service.add_soap_response('createFamily', get_xml_file('R_create_family.xml'))
     url = get_endpoint('create-rl1')
     params = {
         'category': 'ACCEUI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
         'rl1/quality': 'AU',
         'rl1/birth/dateBirth': '1938-07-26',
         'rl1/adresse/street1': 'Chateau',
         'rl1/adresse/town': 'Paris',
         'rl1/adresse/zipcode': '75014',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_rl1.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {'family_id': 196545}
     assert Link.objects.get(resource=con, family_id='196545', name_id='local')
 
 
 def test_create_rl1_empty_referential_key_error(con, app):
     url = get_endpoint('create-rl1')
     params = {
@@ -1605,21 +1538,18 @@ def test_create_rl1_wrong_referential_key_error(con, app):
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc']
         == "rl1/adresse/numComp key value 'plop' do not belong to 'Complement' referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_rl1_maelis_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_FAMILY_ERR
+def test_create_rl1_maelis_error(family_service, con, app):
+    family_service.add_soap_response('createFamily', get_xml_file('R_create_family_error.xml'))
     url = get_endpoint('create-rl1')
     params = {
         'category': 'ACCEUI',
         'situation': 'C',
         'rl1/civility': 'M.',
         'rl1/firstname': 'Jhon',
         'rl1/lastname': 'Doe',
         'rl1/quality': 'AU',
@@ -1629,33 +1559,36 @@ def test_create_rl1_maelis_error(mocked_post, mocked_get, con, app):
         'rl1/adresse/zipcode': '75014',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'already-rl1'
     assert 'Il existe déjà' in resp.json['err_desc']
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl1(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_RL1_FAMILY, UPDATE_FAMILY]
+def test_update_rl1(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+        assert request.rl1['adresse']['street1'] == "Chateau d'eau"
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('update-rl1')
     params = {
         'civility': 'M.',
         'firstname': 'Jhonny',
         'lastname': 'Doe',
         'quality': 'PERE',
         'birth/dateBirth': '1943-06-15',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_rl1.xml')
     assert resp.json['err'] == 0
 
 
 def test_update_rl1_not_linked_error(con, app):
     url = get_endpoint('update-rl1')
     params = {
         'civility': 'M.',
         'firstname': 'Jhonny',
@@ -1664,21 +1597,19 @@ def test_update_rl1_not_linked_error(con, app):
         'birth/dateBirth': '1943-06-15',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl1_connection_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = CONNECTION_ERROR
+def test_update_rl1_connection_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
+    family_service.add_soap_response('updateFamily', ConnectionError('No address associated with hostname'))
     url = get_endpoint('update-rl1')
     params = {
         'civility': 'M.',
         'firstname': 'Jhonny',
         'lastname': 'Doe',
         'quality': 'PERE',
         'birth/dateBirth': '1943-06-15',
     }
@@ -1700,38 +1631,40 @@ def test_update_rl1_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "quality key value 'plop' do not belong to 'Quality' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_rl2(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_RL1_FAMILY, UPDATE_FAMILY]
+def test_create_rl2(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('create-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
         'adresse/num': '170',
         'adresse/street1': "Chateau d'eau",
         'adresse/town': 'Paris',
         'adresse/zipcode': '75014',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_rl2.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {'id': '614062'}
 
 
 def test_create_rl2_not_linked_error(con, app):
     url = get_endpoint('create-rl2')
     params = {
         'civility': 'MME',
@@ -1746,21 +1679,19 @@ def test_create_rl2_not_linked_error(con, app):
         'adresse/zipcode': '75014',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_rl2_connection_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = CONNECTION_ERROR
+def test_create_rl2_connection_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
+    family_service.add_soap_response('updateFamily', ConnectionError('No address associated with hostname'))
     url = get_endpoint('create-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
@@ -1771,21 +1702,18 @@ def test_create_rl2_connection_error(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params, status=500)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'No address associated with hostname'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_rl2_already_exists_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, READ_FAMILY]
+def test_create_rl2_already_exists_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('create-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
@@ -1817,34 +1745,37 @@ def test_create_rl2_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "quality key value 'plop' do not belong to 'Quality' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl2(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_update_rl2(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+        assert request.rl2['adresse']['street1'] == "Chateau d'eau"
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('update-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_rl2.xml')
     assert resp.json['err'] == 0
 
 
 def test_update_rl2_not_linked_error(con, app):
     url = get_endpoint('update-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
@@ -1854,42 +1785,37 @@ def test_update_rl2_not_linked_error(con, app):
         'birth/dateBirth': '1940-06-22',
     }
 
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl2_connection_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = CONNECTION_ERROR
+def test_update_rl2_connection_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response('updateFamily', ConnectionError('No address associated with hostname'))
     url = get_endpoint('update-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params, status=500)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'No address associated with hostname'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl2_not_exists_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_RL1_FAMILY
+def test_update_rl2_not_exists_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
     url = get_endpoint('update-rl2')
     params = {
         'civility': 'MME',
         'firstname': 'JANE',
         'lastname': 'DOE',
         'maidenName': 'Smith',
         'quality': 'MERE',
         'birth/dateBirth': '1940-06-22',
@@ -1913,33 +1839,29 @@ def test_update_rl2_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "quality key value 'plop' do not belong to 'Quality' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_child(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_CHILD
+def test_create_child(family_service, con, app):
+    family_service.add_soap_response('createChild', get_xml_file('R_create_child.xml'))
     url = get_endpoint('create-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_child.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {'child_id': 613880}
 
 
 def test_create_child_empty_referential_key_error(con, app):
     url = get_endpoint('create-child')
     params = {
         'lastname': 'DOE',
@@ -1980,75 +1902,72 @@ def test_create_child_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "sexe key value 'plop' do not belong to 'Sex' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_child_connection_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = CONNECTION_ERROR
+def test_create_child_connection_error(family_service, con, app):
+    family_service.add_soap_response('createChild', ConnectionError('No address associated with hostname'))
     url = get_endpoint('create-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params, status=500)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'No address associated with hostname'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_child_maelis_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = CREATE_CHILD_ERR
+def test_create_child_maelis_error(family_service, con, app):
+    family_service.add_soap_response('createChild', get_xml_file('R_create_child_error.xml'))
     url = get_endpoint('create-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'already-child'
     assert 'Il existe déjà' in resp.json['err_desc']
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_update_child(family_service, con, app):
+    def request_check(request):
+        assert request.childList[0]['num'] == '613880'
+        assert request.childList[0]['authorizedPersonList'][0]['personInfo']['firstname'] == 'AMEL'
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('update-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
         'bPhoto': True,
         'bLeaveAlone': False,
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_child.xml')
     assert resp.json['err'] == 0
 
 
 def test_update_child_not_linked_error(con, app):
     url = get_endpoint('update-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
@@ -2073,61 +1992,52 @@ def test_update_child_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "sexe key value 'plop' do not belong to 'Sex' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_connection_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = CONNECTION_ERROR
+def test_update_child_connection_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', ConnectionError('No address associated with hostname'))
     url = get_endpoint('update-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880', params=params, status=500)
     assert resp.json['err']
     assert resp.json['err_desc'] == 'No address associated with hostname'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_not_exists_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_RL1_FAMILY
+def test_update_child_not_exists_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family_with_only_rl1.xml'))
     url = get_endpoint('update-child')
     params = {
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'birth/dateBirth': '1943-01-19',
         'birth/place': 'Port Arthur',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=42', params=params)
     assert resp.json['err'] == 'no-child'
     assert resp.json['err_desc'] == 'No child 42 to update on family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_coordinate(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_FAMILY
+def test_update_coordinate(family_service, con, app):
+    family_service.add_soap_response('updateCoordinate', get_xml_file('R_update_family.xml'))
     url = get_endpoint('update-coordinate')
     params = {
         'adresse/num': '169',
         'adresse/numComp': 'B',
         'adresse/idStreet': 'AM0330',
         'adresse/street1': 'Château',
         'adresse/street2': None,
         'adresse/town': 'Paris',
@@ -2138,17 +2048,16 @@ def test_update_coordinate(mocked_post, mocked_get, con, app):
         'profession/phone': '0123456789',
         'profession/addressPro': {'num': None, 'street': None, 'zipcode': None, 'town': 'Orléans'},
         'CAFInfo/number': '789',
         'CAFInfo/organ': 'A10007752822',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_coordinate.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
 def test_update_coordinate_schema_error(con, app):
     url = get_endpoint('update-coordinate')
     params = {
         'contact/isContactMail': 'true more text',
@@ -2164,21 +2073,17 @@ def test_update_coordinate_schema_error(con, app):
         'adresse/town': 'Paris',
         'adresse/zipcode': '75014',
     }
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params, status=400)
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == "'true more text' is not of type 'boolean'"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_coordinate_wrong_referential_key_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_FAMILY
+def test_update_coordinate_wrong_referential_key_error(con, app):
     url = get_endpoint('update-coordinate')
     params = {
         'adresse/num': '169',
         'adresse/numComp': 'plop',
         'adresse/street1': 'Château',
         'adresse/street2': None,
         'adresse/town': 'Paris',
         'adresse/zipcode': '75014',
@@ -2187,33 +2092,29 @@ def test_update_coordinate_wrong_referential_key_error(mocked_post, mocked_get,
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc'] == "adresse/numComp key value 'plop' do not belong to 'Complement' referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_quotient(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_QUOTIENT
+def test_update_quotient(family_service, con, app):
+    family_service.add_soap_response('createUpdateQuotient', get_xml_file('R_create_update_quotient.xml'))
     url = get_endpoint('update-quotient')
     params = {
         'yearRev': '2021',
         'dateStart': '2022-10-01',
         'dateEnd': '2023-01-31',
         'mtt': '1500.33',
         'cdquo': 'QS',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_update_quotient.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
 def test_update_quotient_schema_error(con, app):
     url = get_endpoint('update-quotient')
     params = {
         'yearRev': '2021',
@@ -2224,21 +2125,20 @@ def test_update_quotient_schema_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params, status=400)
     assert resp.json['err'] == 1
     assert resp.json['err_desc'] == "mtt: '1500,33' does not match '^[0-9]+\\\\.?[0-9]*$'"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_quotient_soap_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_QUOTIENT_500
+def test_update_quotient_soap_error(family_service, con, app):
+    family_service.add_soap_response(
+        'createUpdateQuotient', get_xml_file('R_create_update_quotient_soap_error.xml'), status=500
+    )
     url = get_endpoint('update-quotient')
     params = {
         'yearRev': '2021',
         'dateStart': '2022-10-01',
         'dateEnd': '2023-01-31',
         'mtt': '1500.33',
         'cdquo': 'QS',
     }
@@ -2260,37 +2160,44 @@ def test_update_quotient_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "cdquo key value 'plop' do not belong to 'Quotient' required referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_create_person(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+        assert len(request.emergencyPersonList['personList']) == 2
+        assert request.emergencyPersonList['personList'][0]['numPerson'] == 614059
+        assert request.emergencyPersonList['personList'][0]['firstname'] == 'KENY'
+        assert request.emergencyPersonList['personList'][1]['numPerson'] is None
+        assert request.emergencyPersonList['personList'][1]['firstname'] == 'Mathias'
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('create-person')
     params = {
         'civility': None,
         'firstname': 'Mathias',
         'lastname': 'Cassel',
         'quality': 'O',
         'sexe': 'M',
         'dateBirth': '1972-01-01',
         'contact/phone': None,
         'contact/mobile': '0623456789',
         'contact/mail': None,
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_create_person_required_field_error(con, app):
     url = get_endpoint('create-person')
     params = {
         'civility': None,
         'firstname': 'Mathias',
@@ -2360,37 +2267,42 @@ def test_create_person_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "sexe key value 'plop' do not belong to 'Sex' referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_update_person(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+        assert len(request.emergencyPersonList['personList']) == 1
+        assert request.emergencyPersonList['personList'][0]['numPerson'] == 614059
+        assert request.emergencyPersonList['personList'][0]['firstname'] == 'Mathias'
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('update-person')
     params = {
         'civility': None,
         'firstname': 'Mathias',
         'lastname': 'Cassel',
         'quality': 'O',
         'sexe': 'M',
         'dateBirth': '1972-01-01',
         'contact/phone': None,
         'contact/mobile': '0623456789',
         'contact/mail': None,
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&person_id=614059', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_update_person_not_linked_error(con, app):
     url = get_endpoint('update-person')
     params = {
         'civility': None,
         'firstname': 'Mathias',
@@ -2403,21 +2315,18 @@ def test_update_person_not_linked_error(con, app):
         'contact/mail': None,
     }
 
     resp = app.post_json(url + '?NameID=local&person_id=614059', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_person_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_update_person_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('update-person')
     params = {
         'civility': None,
         'firstname': 'Mathias',
         'lastname': 'Cassel',
         'quality': 'O',
         'sexe': 'M',
         'dateBirth': '1972-01-01',
@@ -2426,71 +2335,81 @@ def test_update_person_not_found(mocked_post, mocked_get, con, app):
         'contact/mail': None,
     }
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&person_id=000000', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' authorized person on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_delete_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_delete_person(family_service, con, app):
+    def request_check(request):
+        assert request.dossierNumber == 1312
+        assert request.emergencyPersonList is None
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateFamily', get_xml_file('R_update_family.xml'), request_check=request_check
+    )
     url = get_endpoint('delete-person')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&person_id=614059')
-    assert_sent_payload(mocked_post, 'Q_delete_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_delete_person_not_linked_error(con, app):
     url = get_endpoint('delete-person')
 
     resp = app.post_json(url + '?NameID=local&person_id=614059')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_delete_person_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_delete_person_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('delete-person')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&person_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' authorized person on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_child_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_CHILD_AUTO]
+def test_create_child_person(family_service, con, app):
+    def request_check(request):
+        assert request.numFamily == '1312'
+        assert request.numPerson == 613880
+        assert len(request.personList) == 2
+        assert request.personList[0]['personInfo']['num'] == 614719
+        assert request.personList[0]['personInfo']['firstname'] == 'AMEL'
+        assert request.personList[1]['personInfo']['num'] is None
+        assert request.personList[1]['personInfo']['firstname'] == 'Diana'
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateChildAutorization',
+        get_xml_file('R_update_child_authorization.xml'),
+        request_check=request_check,
+    )
     url = get_endpoint('create-child-person')
     params = {
         'personInfo/civility': 'MME',
         'personInfo/firstname': 'Diana',
         'personInfo/lastname': 'Ross',
         'personInfo/sexe': 'F',
         'personInfo/dateBirth': '1944-03-26',
         'personInfo/contact/phone': '0199999999',
         'personInfo/contact/mobile': '0723456789',
         'personInfo/contact/mail': 'dross@example.org',
         'personQuality/code': 'TUTEUR',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
-    assert_sent_payload(mocked_post, 'Q_create_child_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_create_child_person_empty_referential_key_error(con, app):
     url = get_endpoint('create-child-person')
     params = {
         'personInfo/civility': 'MME',
         'personInfo/firstname': 'Diana',
@@ -2542,21 +2461,18 @@ def test_create_child_person_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "personInfo/sexe key value 'plop' do not belong to 'Sex' referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_create_child_person_no_child_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_create_child_person_no_child_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('create-child-person')
     params = {
         'personInfo/civility': 'MME',
         'personInfo/firstname': 'Diana',
         'personInfo/lastname': 'Ross',
         'personInfo/sexe': 'F',
         'personInfo/dateBirth': '1944-03-26',
         'personInfo/contact/phone': '01999999999',
@@ -2566,37 +2482,45 @@ def test_create_child_person_no_child_error(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=42', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '42' child on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_update_child_person(family_service, con, app):
+    def request_check(request):
+        assert request.numFamily == '1312'
+        assert request.numPerson == 613880
+        assert len(request.personList) == 1
+        assert request.personList[0]['personInfo']['num'] == 614719
+        assert request.personList[0]['personInfo']['firstname'] == 'Angelo'
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateChildAutorization',
+        get_xml_file('R_update_child_authorization.xml'),
+        request_check=request_check,
+    )
     url = get_endpoint('update-child-person')
     params = {
         'personInfo/civility': 'M.',
         'personInfo/firstname': 'Angelo',
         'personInfo/lastname': 'Bent',
         'personInfo/sexe': 'M',
         'personInfo/dateBirth': '1985-06-22',
         'personInfo/contact/phone': '0102030405',
         'personInfo/contact/mobile': None,
         'personInfo/contact/mail': None,
         'personQuality/code': 'O',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_child_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_update_child_person_not_linked_error(con, app):
     url = get_endpoint('update-child-person')
     params = {
         'personInfo/civility': 'M.',
         'personInfo/firstname': 'Angelo',
@@ -2628,21 +2552,18 @@ def test_update_child_person_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "personInfo/sexe key value 'plop' do not belong to 'Sex' referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_person_no_child_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_update_child_person_no_child_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('update-child-person')
     params = {
         'personInfo/civility': 'M.',
         'personInfo/firstname': 'Angelo',
         'personInfo/lastname': 'Bent',
         'personInfo/dateBirth': '1985-06-22',
         'personInfo/contact/phone': '0102030405',
         'personInfo/contact/mobile': None,
@@ -2651,21 +2572,18 @@ def test_update_child_person_no_child_error(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=42&person_id=614719', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '42' child on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_person_not_found(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_update_child_person_not_found(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('update-child-person')
     params = {
         'personInfo/civility': 'M.',
         'personInfo/firstname': 'Angelo',
         'personInfo/lastname': 'Bent',
         'personInfo/dateBirth': '1985-06-22',
         'personInfo/contact/phone': '0102030405',
         'personInfo/contact/mobile': None,
@@ -2674,73 +2592,69 @@ def test_update_child_person_not_found(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=000000', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "No '000000' authorized person on '613880' child"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_delete_child_person(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+def test_delete_child_person(family_service, con, app):
+    def request_check(request):
+        assert request.numFamily == '1312'
+        assert request.numPerson == 613880
+        assert len(request.personList) == 0
+
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    family_service.add_soap_response(
+        'updateChildAutorization',
+        get_xml_file('R_update_child_authorization.xml'),
+        request_check=request_check,
+    )
     url = get_endpoint('delete-child-person')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719')
-    assert_sent_payload(mocked_post, 'Q_delete_child_person.xml')
     assert resp.json['err'] == 0
 
 
 def test_delete_child_person_not_linked_error(con, app):
     url = get_endpoint('delete-child-person')
 
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719')
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_delete_child_person_no_child_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_delete_child_person_no_child_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('delete-child-person')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=42&person_id=614719')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '42' child on '1312' family"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_delete_child_person_no_person_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = READ_FAMILY
+def test_delete_child_person_no_person_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     url = get_endpoint('delete-child-person')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "No '000000' authorized person on '613880' child"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_dietcode(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_DIETCODE
+def test_update_child_dietcode(family_service, con, app):
+    family_service.add_soap_response('createOrUpdateChildDiet', get_xml_file('R_update_child_dietcode.xml'))
     url = get_endpoint('update-child-dietcode')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878&dietcode=RSV')
-    assert_sent_payload(mocked_post, 'Q_update_child_dietcode.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
 def test_update_child_dietcode_not_linked_error(con, app):
     url = get_endpoint('update-child-dietcode')
 
     resp = app.post_json(url + '?NameID=local&child_id=613878&dietcode=RVS')
@@ -2754,21 +2668,18 @@ def test_update_child_dietcode_wrong_referential_key_error(con, app):
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878&dietcode=plop')
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc'] == "dietcode parameter key value 'plop' do not belong to 'DietCode' referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_pai(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_PAI
+def test_update_child_pai(family_service, con, app):
+    family_service.add_soap_response('updateChildPAI', get_xml_file('R_update_child_pai.xml'))
     url = get_endpoint('update-child-pai')
     params = {
         'code': 'PAIALI',
         'dateDeb': '2022-01-01',
         'dateFin': '',
         'description': 'some text',
     }
 
@@ -2822,42 +2733,40 @@ def test_update_child_pai_not_linked_error(con, app):
         'description': 'some text',
     }
 
     resp = app.post_json(url + '?NameID=local&child_id=613878', params=params)
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_pai_soap_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_PAI_500
+def test_update_child_pai_soap_error(family_service, con, app):
+    family_service.add_soap_response(
+        'updateChildPAI', get_xml_file('R_update_child_pai_soap_error.xml'), status=500
+    )
     url = get_endpoint('update-child-pai')
     params = {
         'code': 'PAIALI',
         'dateDeb': '2022-01-01',
         'dateFin': '',
         'description': 'a' * 501,
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878', params=params)
     assert resp.json['err'] == 'Family-updateChildPAI-soap:Server'
     assert 'Une erreur est survenue' in resp.json['err_desc']
     assert 'valeur trop grande' in resp.json['err_desc']
     assert 'maximum : 500' in resp.json['err_desc']
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_medical_record(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_MEDICAL
+def test_update_child_medical_record(family_service, con, app):
+    family_service.add_soap_response(
+        'updateChildMedicalRecord', get_xml_file('R_update_child_medical_record.xml')
+    )
     url = get_endpoint('update-child-medical-record')
     params = {
         'familyDoctor/name': 'Dre',
         'familyDoctor/phone': '0612341234',
         'familyDoctor/address/street1': 'Alameda',
         'familyDoctor/address/zipcode': '90220',
         'familyDoctor/address/town': 'Compton',
         'allergy1': 'butterscotch, imitation butterscotch, glow-in-the-dark monster make-up, and shrimp',
@@ -2871,26 +2780,24 @@ def test_update_child_medical_record(mocked_post, mocked_get, con, app):
         'vaccinList/0/code': 'DTC',
         'vaccinList/0/vaccinationDate': '2011-01-11',
         'vaccinList/1/code': 'ROR',
         'vaccinList/1/vaccinationDate': '2022-02-22',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_child_medical_record.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_medical_record_with_empty_vaccin_list(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_MEDICAL
+def test_update_child_medical_record_with_empty_vaccin_list(family_service, con, app):
+    family_service.add_soap_response(
+        'updateChildMedicalRecord', get_xml_file('R_update_child_medical_record.xml')
+    )
     url = get_endpoint('update-child-medical-record')
     params = {
         'familyDoctor/name': 'Dre',
         'familyDoctor/phone': '0612341234',
         'familyDoctor/address/street1': 'Alameda',
         'familyDoctor/address/zipcode': '90220',
         'familyDoctor/address/town': 'Compton',
         'allergy1': 'butterscotch, imitation butterscotch, glow-in-the-dark monster make-up, and shrimp',
@@ -2912,21 +2819,20 @@ def test_update_child_medical_record_with_empty_vaccin_list(mocked_post, mocked_
 def test_update_child_medical_record_not_linked_error(con, app):
     url = get_endpoint('update-child-medical-record')
 
     resp = app.post_json(url + '?NameID=local&child_id=613878', params={})
     assert resp.json['err'] == 'not-linked'
     assert resp.json['err_desc'] == 'User not linked to family'
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_medical_record_soap_error(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_MEDICAL_500
+def test_update_child_medical_record_soap_error(family_service, con, app):
+    family_service.add_soap_response(
+        'updateChildMedicalRecord', get_xml_file('R_update_child_medical_record_soap_error.xml'), status=500
+    )
     url = get_endpoint('update-child-medical-record')
     params = {
         'vaccinList/0/code': 'DTC',
         'vaccinList/0/vaccinationDate': '2022-02-31',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878', params=params)
@@ -2950,21 +2856,18 @@ def test_update_child_medical_record_wrong_referential_key_error(con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613878', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert resp.json['err_desc'] == "vaccinList/1/code key value 'plop' do not belong to 'Vaccin' referential"
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_rl_indicator(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_INDICATOR
+def test_update_rl_indicator(family_service, con, app):
+    family_service.add_soap_response('updatePersonIndicatorList', get_xml_file('R_update_indicator.xml'))
     url = get_endpoint('update-rl-indicator')
     params = {
         'indicatorList': [
             {
                 'code': 'AVL',
                 'isActive': True,
             },
             {
@@ -2972,17 +2875,16 @@ def test_update_rl_indicator(mocked_post, mocked_get, con, app):
                 'note': 'SNPP',
                 'isActive': True,
             },
         ],
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_rl_indicator.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
 def test_update_rl_indicator_not_linked_error(con, app):
     url = get_endpoint('update-rl-indicator')
     params = {
         'indicatorList': [
@@ -3040,21 +2942,18 @@ def test_update_rl_indicator_wrong_referential_key_error(con, app):
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc']
         == "indicatorList/0/code key value 'plop' do not belong to 'RLIndicator' required referential"
     )
 
 
-@mock.patch('passerelle.utils.Request.get')
-@mock.patch('passerelle.utils.Request.post')
-def test_update_child_indicator(mocked_post, mocked_get, con, app):
-    mocked_get.return_value = FAMILY_SERVICE_WSDL
-    mocked_post.return_value = UPDATE_INDICATOR
+def test_update_child_indicator(family_service, con, app):
+    family_service.add_soap_response('updatePersonIndicatorList', get_xml_file('R_update_indicator.xml'))
     url = get_endpoint('update-child-indicator')
     params = {
         'indicatorList': [
             {
                 'code': 'LUNETTE',
                 'isActive': True,
             },
             {
@@ -3062,17 +2961,16 @@ def test_update_child_indicator(mocked_post, mocked_get, con, app):
                 'note': 'rebellious',
                 'isActive': True,
             },
         ],
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
-    assert_sent_payload(mocked_post, 'Q_update_child_indicator.xml')
     assert resp.json['err'] == 0
     assert resp.json['data'] == 'ok'
 
 
 def test_update_child_indicator_not_linked_error(con, app):
     url = get_endpoint('update-child-indicator')
     params = {
         'indicatorList': [
diff --git a/tests/utils.py b/tests/utils.py
index 605b167b..a6f32a9e 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -102,36 +102,40 @@ class ResponsesSoap:
                 finally:
                     if request_check:
                         request = operation.input.deserialize(doc.getroot())
                         request_check(request)
             return False, None
 
         return matcher
 
-    def add_soap_response(self, mock, operation_name, response_content, request_check=None):
+    def add_soap_response(self, mock, operation_name, response_content, status=200, request_check=None):
         operation = self.binding.get(operation_name)
-        doc = ET.parse(io.BytesIO(response_content))
-        try:
-            operation.output.deserialize(doc.getroot())
-        except Exception as e:
-            raise AssertionError(f'response_content did not match operation "{operation_name}" schema') from e
+        if not isinstance(response_content, Exception):
+            doc = ET.parse(io.BytesIO(response_content))
+            try:
+                operation.output.deserialize(doc.getroot())
+            except Exception as e:
+                raise AssertionError(
+                    f'response_content did not match operation "{operation_name}" schema'
+                ) from e
         mock.add(
             responses.POST,
             self.address,
             body=response_content,
-            status=200,
+            status=status,
             match=(self.soap_matcher(operation_name, request_check),),
         )
 
     @contextlib.contextmanager
     def __call__(self):
         with responses.RequestsMock() as mock:
             mock.add(responses.GET, self.wsdl_url, body=self.wsdl_content, status=200)
             mock.add_soap_response = (
-                lambda operation, response_content, request_check=None: self.add_soap_response(
+                lambda operation, response_content, status=200, request_check=None: self.add_soap_response(
                     mock,
                     operation,
                     response_content,
+                    status=status,
                     request_check=request_check,
                 )
             )
             yield mock
-- 
2.30.2

