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"
Example #4
0
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)
Example #7
0
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)
Example #8
0
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)
Example #10
0
    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")
Example #11
0
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&#8217;appel.</p>\n<p>Pour couvrir les d&#233;passements attendus de l&#8217;ONDAM pour 2016, cet article pr&#233;voit un pr&#233;l&#232;vement de 200 millions d&#8217;&#8364; sur les fonds de roulement de l&#8217;association nationale pour la formation permanente du personnel hospitalier (ANFH) et du fonds pour l&#8217;emploi hospitalier (FEH) pour financer le <span>fonds pour la modernisation des &#233;tablissements de sant&#233; publics et priv&#233;s</span>(FMESPP) en remplacement de cr&#233;dit de l&#8217;ONDAM. Il participe donc &#224; la pr&#233;sentation insinc&#232;re de la construction de l&#8217;ONDAM, d&#233;nonc&#233;e par le Comit&#233; d&#8217;alerte le 12 octobre dernier.</p>",  # noqa
        resume=None,
        avis=None,
        observations=None,
        reponse=None,
    )
    assert amendement.parent is None
Example #12
0
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 == []
Example #13
0
    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 == ""
Example #14
0
    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 == ""
Example #15
0
    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é",
        }
Example #16
0
    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 == ""
Example #17
0
    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"
Example #18
0
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 == ""
Example #19
0
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 == ""
Example #20
0
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
Example #21
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
Example #22
0
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 == ""
Example #23
0
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"
Example #24
0
    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 == []
Example #25
0
    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&#8217;appel.</p>\n<p>Pour couvrir les d&#233;passements "
            "attendus de l&#8217;ONDAM pour 2016, cet article pr&#233;voit un "
            "pr&#233;l&#232;vement de 200 millions d&#8217;&#8364; sur les fonds de "
            "roulement de l&#8217;association nationale pour la formation permanente "
            "du personnel hospitalier (ANFH) et du fonds pour l&#8217;emploi "
            "hospitalier (FEH) pour financer le <span>fonds pour la modernisation des "
            "&#233;tablissements de sant&#233; publics et priv&#233;s</span>(FMESPP) "
            "en remplacement de cr&#233;dit de l&#8217;ONDAM. Il participe donc &#224; "
            "la pr&#233;sentation insinc&#232;re de la construction de l&#8217;ONDAM, "
            "d&#233;nonc&#233;e par le Comit&#233; d&#8217;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é")