def test_fetch_sous_amendement(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 155), body=read_sample_data("an/269/155.xml"), status=200, ) responses.add( responses.GET, build_url(lecture_an, 941), body=read_sample_data("an/269/941.xml"), status=200, ) amendement1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="155", position=1) assert created amendement2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="941", position=2) assert created assert amendement2.parent is amendement1
def test_parent_has_changed(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url from zam_repondeur.models import DBSession responses.add( responses.GET, build_url(lecture_an, 155), body=read_sample_data("an/269/155.xml"), status=200, ) responses.add( responses.GET, build_url(lecture_an, 941), body=read_sample_data("an/269/941.xml"), status=200, ) parent1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="155", position=1) assert created child1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="941", position=2) assert created assert child1.parent is parent1 assert child1.parent_pk == parent1.pk child1.parent = None # let's change the parent amendement DBSession.flush() parent2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="155", position=1) assert not created assert parent2 is parent1 child2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="941", position=2) assert not created assert child2 is child1 assert child2.parent_pk == parent2.pk assert child2.parent is parent2
def test_response_is_preserved(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 177), body=read_sample_data("an/269/177.xml"), status=200, ) # Let's fetch a new amendement amendement1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) assert created # Now let's add a response amendement1.user_content.avis = "Favorable" amendement1.user_content.objet = "Objet" amendement1.user_content.reponse = "Réponse" # And fetch the same amendement again amendement2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) assert not created assert amendement2 is amendement1 # The response has been preserved assert amendement2.user_content.avis == "Favorable" assert amendement2.user_content.objet == "Objet" assert amendement2.user_content.reponse == "Réponse"
def test_fetch_amendements(): from zam_repondeur.fetch.an.amendements import fetch_amendements responses.add( responses.GET, build_url(14, 4072), body=read_sample_data("an_liste.xml"), status=200, ) title, items = fetch_amendements(legislature=14, texte=4072, organe="PO717460", groups_folder=SAMPLE_DATA_DIR) assert title == "PLFSS 2017" assert len(items) == 5 assert items[0] == { "@alineaLabel": "S", "@auteurGroupe": "Les Républicains", "@auteurLabel": "M. DOOR", "@auteurLabelFull": "M. DOOR Jean-Pierre", "@discussionCommune": "", "@discussionCommuneAmdtPositon": "", "@discussionCommuneSsAmdtPositon": "", "@discussionIdentique": "20386", "@discussionIdentiqueAmdtPositon": "debut", "@discussionIdentiqueSsAmdtPositon": "", "@missionLabel": "", "@numero": "177", "@parentNumero": "", "@place": "Article 3", "@position": "001/772", "@sort": "Rejeté", }
def test_simple_amendements(self, lecture_an, app): from zam_repondeur.fetch.an.amendements import build_url, fetch_discussion_list responses.add( responses.GET, build_url(lecture_an), body=read_sample_data("an/269/liste.xml"), status=200, ) items = fetch_discussion_list(lecture=lecture_an) assert len(items) == 5 assert items[0] == { "@alineaLabel": "S", "@auteurGroupe": "Les Républicains", "@auteurLabel": "M. DOOR", "@auteurLabelFull": "M. DOOR Jean-Pierre", "@discussionCommune": "", "@discussionCommuneAmdtPositon": "", "@discussionCommuneSsAmdtPositon": "", "@discussionIdentique": "20386", "@discussionIdentiqueAmdtPositon": "debut", "@discussionIdentiqueSsAmdtPositon": "", "@missionLabel": "", "@numero": "177", "@parentNumero": "", "@place": "Article 3", "@position": "001/772", "@sort": "Rejeté", }
def test_fetch_amendement_not_found(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import NotFound, build_url responses.add(responses.GET, build_url(lecture_an, 177), status=404) with pytest.raises(NotFound): source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1)
def test_fetch_amendements_not_found(): from zam_repondeur.fetch.an.amendements import fetch_amendements, NotFound responses.add(responses.GET, build_url(14, 4072), status=404) with pytest.raises(NotFound): fetch_amendements(legislature=14, texte=4072, organe="PO717460", groups_folder=SAMPLE_DATA_DIR)
def setup_mock_responses(lecture, liste, amendements): from zam_repondeur.fetch.an.amendements import build_url with responses.RequestsMock(assert_all_requests_are_fired=False) as mock_resp: # Add response for list of discussed amendements mock_resp.add(responses.GET, build_url(lecture), body=liste, status=200) # Add responses for known amendements for number, data in amendements: mock_resp.add( responses.GET, build_url(lecture, number), body=data, status=200 ) # Other amendements will return a 404 url_pattern = re.escape(build_url(lecture, "X")).replace("X", r"[A-Z]*\d+") mock_resp.add(responses.GET, re.compile(url_pattern), status=404) yield mock_resp
def test_list_not_found(self, lecture_an, app): from zam_repondeur.fetch.an.amendements import ( build_url, fetch_discussion_list, NotFound, ) responses.add(responses.GET, build_url(lecture_an), status=404) with pytest.raises(NotFound): fetch_discussion_list(lecture=lecture_an)
def test_sort_turn_irrecevable(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url from zam_repondeur.models.events.amendement import AmendementIrrecevable sample_data = read_sample_data("an/269/177.xml") responses.add(responses.GET, build_url(lecture_an, 177), body=sample_data, status=200) # On second call we want an irrecevable. responses.add( responses.GET, build_url(lecture_an, 177), body=sample_data.replace( "<sortEnSeance>Rejeté</sortEnSeance>", "<sortEnSeance>Irrecevable</sortEnSeance>", ), status=200, ) # Let's fetch a new amendement amendement1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) # And fetch the same amendement again amendement2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) # An irrecevable event has been created assert len(amendement1.events) == 3 assert isinstance(amendement1.events[0], AmendementIrrecevable) assert amendement1.events[0].created_at is not None assert amendement1.events[0].user is None assert amendement1.events[0].data["old_value"] == "rejeté" assert amendement1.events[0].data["new_value"] == "irrecevable" assert amendement1.events[0].render_summary() == ( "L’amendement a été déclaré irrecevable par les services " "de l’Asssemblée nationale")
def test_fetch_amendement(app): from zam_repondeur.fetch.an.amendements import fetch_amendement from zam_repondeur.fetch.models import Amendement responses.add( responses.GET, build_url(14, 4072, 177), body=read_sample_data("an_177.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=177, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement == Amendement( chambre="an", session="14", num_texte=4072, organe="PO717460", subdiv_type="article", subdiv_num="3", subdiv_mult="", subdiv_pos="", alinea="", num=177, rectif=0, auteur="Door Jean-Pierre", matricule="267289", groupe="Les Républicains", date_depot=None, sort="rejeté", position=1, discussion_commune=None, identique=None, parent_num=0, parent_rectif=0, dispositif="<p>Supprimer cet article.</p>", objet= "<p>Amendement d’appel.</p>\n<p>Pour couvrir les dépassements attendus de l’ONDAM pour 2016, cet article prévoit un prélèvement de 200 millions d’€ sur les fonds de roulement de l’association nationale pour la formation permanente du personnel hospitalier (ANFH) et du fonds pour l’emploi hospitalier (FEH) pour financer le <span>fonds pour la modernisation des établissements de santé publics et privés</span>(FMESPP) en remplacement de crédit de l’ONDAM. Il participe donc à la présentation insincère de la construction de l’ONDAM, dénoncée par le Comité d’alerte le 12 octobre dernier.</p>", # noqa resume=None, avis=None, observations=None, reponse=None, ) assert amendement.parent is None
def test_fetch_and_parse_all(): from zam_repondeur.fetch.an.amendements import fetch_and_parse_all responses.add( responses.GET, build_url(14, 4072), body=read_sample_data("an_liste.xml"), status=200, ) responses.add( responses.GET, build_url(14, 4072, 177), body=read_sample_data("an_177.xml"), status=200, ) responses.add( responses.GET, build_url(14, 4072, 270), body=read_sample_data("an_270.xml"), status=200, ) responses.add( responses.GET, build_url(14, 4072, 723), body=read_sample_data("an_723.xml"), status=200, ) responses.add( responses.GET, build_url(14, 4072, 135), body=read_sample_data("an_135.xml"), status=200, ) responses.add( responses.GET, build_url(14, 4072, 192), body=read_sample_data("an_192.xml"), status=200, ) title, amendements, errored = fetch_and_parse_all( legislature=14, texte=4072, organe="PO717460", groups_folder=SAMPLE_DATA_DIR) assert title == "PLFSS 2017" assert len(amendements) == 5 assert amendements[0].num == 177 assert amendements[1].num == 270 assert amendements[2].num == 723 assert amendements[3].num == 135 assert amendements[4].num == 192 assert [amdt.position for amdt in amendements] == list(range(1, 6)) assert errored == []
def test_fetch_amendement_sort_nil(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 38), body=read_sample_data("an/269/38.xml"), status=200, ) amendement, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="38", position=1) assert amendement.sort == ""
def test_fetch_amendement_gouvernement(self, lecture_an, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 723), body=read_sample_data("an/269/723.xml"), status=200, ) amendement, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="723", position=1) assert amendement.gouvernemental is True assert amendement.groupe == ""
def test_only_one_amendement(self, lecture_an, app): from zam_repondeur.fetch.an.amendements import build_url, fetch_discussion_list responses.add( responses.GET, build_url(lecture_an), body=dedent("""\ <?xml version="1.0" encoding="UTF-8"?> <amdtsParOrdreDeDiscussion bibard="4072" bibardSuffixe="" organe="AN" legislature="14" titre="PLFSS 2017" type="projet de loi de financement de la sécurité sociale"> <amendements> <amendement place="Article 3" numero="177" sort="Rejeté" parentNumero="" auteurLabel="M. DOOR" auteurLabelFull="M. DOOR Jean-Pierre" auteurGroupe="Les Républicains" alineaLabel="S" missionLabel="" discussionCommune="" discussionCommuneAmdtPositon="" discussionCommuneSsAmdtPositon="" discussionIdentique="20386" discussionIdentiqueAmdtPositon="debut" discussionIdentiqueSsAmdtPositon="" position="001/772" /> </amendements> </amdtsParOrdreDeDiscussion> """), status=200, ) items = fetch_discussion_list(lecture=lecture_an) assert isinstance(items, list) assert items[0] == { "@alineaLabel": "S", "@auteurGroupe": "Les Républicains", "@auteurLabel": "M. DOOR", "@auteurLabelFull": "M. DOOR Jean-Pierre", "@discussionCommune": "", "@discussionCommuneAmdtPositon": "", "@discussionCommuneSsAmdtPositon": "", "@discussionIdentique": "20386", "@discussionIdentiqueAmdtPositon": "debut", "@discussionIdentiqueSsAmdtPositon": "", "@missionLabel": "", "@numero": "177", "@parentNumero": "", "@place": "Article 3", "@position": "001/772", "@sort": "Rejeté", }
def test_fetch_amendement_commission(self, lecture_an, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 135), body=read_sample_data("an/269/135.xml"), status=200, ) amendement, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="135", position=1) assert amendement.gouvernemental is False assert amendement.auteur == "Bapt Gérard" assert amendement.groupe == ""
def test_fetch_amendement_apres(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 192), body=read_sample_data("an/269/192.xml"), status=200, ) amendement, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="192", position=1) assert amendement.article.type == "article" assert amendement.article.num == "8" assert amendement.article.mult == "" assert amendement.article.pos == "après"
def test_fetch_amendement_sort_nil(): from zam_repondeur.fetch.an.amendements import fetch_amendement responses.add( responses.GET, build_url(14, 4072, 38), body=read_sample_data("an_38.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=38, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement.sort == ""
def test_fetch_amendement_gouvernement(): from zam_repondeur.fetch.an.amendements import fetch_amendement responses.add( responses.GET, build_url(14, 4072, 723), body=read_sample_data("an_723.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=723, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement.gouvernemental is True assert amendement.groupe == ""
def test_fetch_sous_amendement(app): from zam_repondeur.fetch.an.amendements import fetch_amendement responses.add( responses.GET, build_url(14, 4072, 941), body=read_sample_data("an_941.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=941, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement.parent_num == 155 assert amendement.parent_rectif == 0
def test_article_has_changed(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url responses.add( responses.GET, build_url(lecture_an, 177), body=read_sample_data("an/269/177.xml"), status=200, ) amendement1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) assert created amendement1.article = None # let's change the article amendement2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=2) assert not created assert amendement2 is amendement1
def test_fetch_amendement_commission(): from zam_repondeur.fetch.an.amendements import fetch_amendement responses.add( responses.GET, build_url(14, 4072, 135), body=read_sample_data("an_135.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=135, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement.gouvernemental is False assert amendement.auteur == "Bapt Gérard" assert amendement.groupe == ""
def test_fetch_amendement_apres(): from zam_repondeur.fetch.an.amendements import fetch_amendement responses.add( responses.GET, build_url(14, 4072, 192), body=read_sample_data("an_192.xml"), status=200, ) amendement = fetch_amendement( legislature=14, texte=4072, numero=192, organe="PO717460", groups_folder=SAMPLE_DATA_DIR, position=1, ) assert amendement.subdiv_type == "article" assert amendement.subdiv_num == "8" assert amendement.subdiv_mult == "" assert amendement.subdiv_pos == "apres"
def test_sort_turn_irrecevable_transfers_to_index(self, lecture_an, app, source, user_david, user_david_table_an): from zam_repondeur.fetch.an.amendements import build_url from zam_repondeur.models import DBSession from zam_repondeur.models.events.amendement import ( AmendementIrrecevable, AmendementTransfere, ) sample_data = read_sample_data("an/269/177.xml") responses.add(responses.GET, build_url(lecture_an, 177), body=sample_data, status=200) # On second call we want an irrecevable. responses.add( responses.GET, build_url(lecture_an, 177), body=sample_data.replace( "<sortEnSeance>Rejeté</sortEnSeance>", "<sortEnSeance>Irrecevable</sortEnSeance>", ), status=200, ) # Let's fetch a new amendement amendement1, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) # Put it on a user table DBSession.add(user_david_table_an) user_david_table_an.amendements.append(amendement1) assert user_david_table_an.amendements == [amendement1] assert amendement1.user_table == user_david_table_an # Now fetch the same amendement again (now irrecevable) amendement2, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) # An irrecevable event has been created assert any( isinstance(event, AmendementIrrecevable) for event in amendement2.events) # An automatic transfer event has been created assert any( isinstance(event, AmendementTransfere) for event in amendement2.events) transfer_event = next(event for event in amendement2.events if isinstance(event, AmendementTransfere)) assert transfer_event.user is None assert transfer_event.data["old_value"] == "David ([email protected])" assert transfer_event.data["new_value"] == "" assert transfer_event.render_summary() == ( "L’amendement a été remis automatiquement sur l’index") # And the amendement is now on the index assert amendement2.user_table is None assert user_david_table_an.amendements == []
def test_simple_amendement(self, lecture_an, app, source): from zam_repondeur.fetch.an.amendements import build_url from zam_repondeur.models.events.amendement import ( CorpsAmendementModifie, ExposeAmendementModifie, ) responses.add( responses.GET, build_url(lecture_an, 177), body=read_sample_data("an/269/177.xml"), status=200, ) amendement, created = source.fetch_amendement(lecture=lecture_an, numero_prefixe="177", position=1) assert amendement.lecture == lecture_an assert amendement.num == 177 assert amendement.rectif == 0 assert amendement.auteur == "Door Jean-Pierre" assert amendement.matricule == "267289" assert amendement.date_depot is None assert amendement.sort == "rejeté" assert amendement.position == 1 assert amendement.id_discussion_commune is None assert amendement.id_identique is None assert amendement.parent is None assert amendement.corps == "<p>Supprimer cet article.</p>" assert amendement.expose == ( "<p>Amendement d’appel.</p>\n<p>Pour couvrir les dépassements " "attendus de l’ONDAM pour 2016, cet article prévoit un " "prélèvement de 200 millions d’€ sur les fonds de " "roulement de l’association nationale pour la formation permanente " "du personnel hospitalier (ANFH) et du fonds pour l’emploi " "hospitalier (FEH) pour financer le <span>fonds pour la modernisation des " "établissements de santé publics et privés</span>(FMESPP) " "en remplacement de crédit de l’ONDAM. Il participe donc à " "la présentation insincère de la construction de l’ONDAM, " "dénoncée par le Comité d’alerte le 12 octobre " "dernier.</p>") assert amendement.resume is None assert amendement.user_content.avis is None assert amendement.user_content.objet is None assert amendement.user_content.reponse is None assert len(amendement.events) == 2 assert isinstance(amendement.events[0], ExposeAmendementModifie) assert amendement.events[0].created_at is not None assert amendement.events[0].user is None assert amendement.events[0].data["old_value"] == "" assert amendement.events[0].data["new_value"].startswith( "<p>Amendement") assert amendement.events[0].render_summary() == ( "L’exposé de l’amendement a été initialisé") assert isinstance(amendement.events[1], CorpsAmendementModifie) assert amendement.events[1].created_at is not None assert amendement.events[1].user is None assert amendement.events[1].data["old_value"] == "" assert amendement.events[1].data["new_value"].startswith( "<p>Supprimer") assert amendement.events[1].render_summary() == ( "Le corps de l’amendement a été initialisé")