Ejemplo n.º 1
0
def test_aspire_senat_plf2019_1re_partie(app, texte_senat, dossier_plf):
    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession, Lecture

    with transaction.manager:
        texte_senat.numero = 146
        lecture = Lecture.create(
            chambre="senat",
            session="2018-2019",
            texte=texte_senat,
            partie=1,
            titre="Numéro lecture – Titre lecture sénat",
            organe="PO78718",
            dossier=dossier_plf,
        )

    sample_data = read_sample_data("jeu_complet_2018-2019_146.csv")

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2018-2019/146/jeu_complet_2018-2019_146.csv",
        body=sample_data,
        status=200,
    )

    odsen_data = read_sample_data("ODSEN_GENERAL.csv")

    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=odsen_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_103393.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103393.json",
        json=json_data,
        status=200,
    )

    DBSession.add(lecture)

    source = Senat()

    amendements, created, errored = source.fetch(lecture)

    # All amendements from part 1 are fetched
    assert len(amendements) == 1005
Ejemplo n.º 2
0
    def get_remote_source_for_chambre(cls, chambre: str) -> "RemoteSource":
        from zam_repondeur.fetch.an.amendements import AssembleeNationale
        from zam_repondeur.fetch.senat.amendements import Senat

        if chambre == "an":
            return AssembleeNationale()
        elif chambre == "senat":
            return Senat()
        else:
            raise NotImplementedError
Ejemplo n.º 3
0
def test_parse_from_csv(lecture_senat):

    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession

    amend = {
        "Alinéa": " ",
        "Au nom de ": "",
        "Auteur ": "M. FRASSA",
        "Date de dépôt ": "2017-11-13",
        "Dispositif ": '<body><p style="text-align: justify;">Apr&#232;s l&#8217;article&#160;7</p><p style="text-align: justify;">Ins&#233;rer un article&#160;additionnel ainsi r&#233;dig&#233;&#160;:</p><p style="text-align: justify;">I.&#160;&#8211;&#160;Le code de la s&#233;curit&#233; sociale est ainsi modifi&#233;&#160;:</p><p style="text-align: justify;">1&#176;&#160;L&#8217;article&#160;L.&#160;136&#8209;6 est ainsi modifi&#233;&#160;:</p><p style="text-align: justify;">a) Le I&#160;bis&#160;est abrog&#233;&#160;;</p><p style="text-align: justify;">b) &#192; la premi&#232;re phase du premier alin&#233;a du III, la premi&#232;re occurrence du mot&#160;: &#171;&#160;&#224;&#160;&#187; est remplac&#233;e par le mot&#160;: &#171;&#160;et&#160;&#187;&#160;;</p><p style="text-align: justify;">2&#176;&#160;L&#8217;article&#160;L.&#160;136&#8209;7 est ainsi modifi&#233;&#160;:</p><p style="text-align: justify;">a) Le I&#160;bis&#160;est abrog&#233;&#160;;</p><p style="text-align: justify;">b) Le second alin&#233;a du VI est supprim&#233;&#160;;</p><p style="text-align: justify;">3&#176;&#160;L&#8217;article&#160;L.&#160;245&#8209;14 est ainsi modifi&#233;&#160;:</p><p style="text-align: justify;">a) &#192; la premi&#232;re phrase, les r&#233;f&#233;rences&#160;: &#171;&#160;aux I et II de&#160;&#187; sont remplac&#233;es par le mot&#160;: &#171;&#160;&#224;&#160;&#187;&#160;;</p><p style="text-align: justify;">b) La deuxi&#232;me phrase est supprim&#233;e&#160;;</p><p style="text-align: justify;">4&#176;&#160;Au premier alin&#233;a de l&#8217;article&#160;L.&#160;245&#8209;15, la deuxi&#232;me occurrence du mot&#160;: &#171;&#160;&#224;&#160;&#187; est remplac&#233;e par le mot&#160;: &#171;&#160;et&#160;&#187;.</p><p style="text-align: justify;">II.&#160;&#8211;&#160;L&#8217;ordonnance n&#176;&#160;96&#8209;50 du 24&#160;janvier 1996 relative au remboursement de la dette sociale est ainsi modifi&#233;e&#160;:</p><p style="text-align: justify;">1&#176;&#160;La seconde phrase du premier alin&#233;a du I de l&#8217;article&#160;15 est supprim&#233;e&#160;;</p><p style="text-align: justify;">2&#176;&#160;&#192; la premi&#232;re phrase du I de l&#8217;article&#160;16, les r&#233;f&#233;rences&#160;: &#171;&#160;aux I et I&#160;bis&#160;&#187; sont remplac&#233;s par les mots&#160;: &#171;&#160;au I&#160;&#187;.</p><p style="text-align: justify;">III.&#160;&#8211;&#160;1&#176;&#160;Les 1&#176;&#160;et 3&#176;&#160;du I et le 1&#176; du II s&#8217;appliquent aux revenus per&#231;us &#224; compter du 1<sup>er</sup>&#160;janvier 2012&#160;;</p><p style="text-align: justify;">2&#176;&#160;Les 2&#176;&#160;et 4&#176;&#160;du I s&#8217;appliquent aux plus&#8209;values r&#233;alis&#233;es au titre des cessions intervenues &#224; compter de la date de publication de la pr&#233;sente loi&#160;;</p><p style="text-align: justify;">3&#176;&#160;Le 2&#176;&#160;du II s&#8217;applique aux plus&#8209;values r&#233;alis&#233;es au titre des cessions intervenues &#224; compter du 1<sup>er</sup>&#160;janvier 2012.</p><p style="text-align: justify;">IV.&#160;&#8211;&#160;La perte de recettes r&#233;sultant pour les organismes de s&#233;curit&#233; sociale des I &#224; III est compens&#233;e, &#224; due concurrence, par la cr&#233;ation d&#8217;une taxe additionnelle aux droits pr&#233;vus aux articles 575 et 575&#160;A du code g&#233;n&#233;ral des imp&#244;ts.</p></body>          ',  # noqa
        "Fiche Sénateur": "//www.senat.fr/senfic/frassa_christophe_andre08018u.html",  # noqa
        "Nature ": "Amt",
        "Numéro ": "1 rect.",
        "Objet ": '<body><p style="text-align: justify;">Cet amendement vise &#224; rectifier une anomalie, celle de l&#8217;assujettissement des Fran&#231;ais &#233;tablis hors de France au paiement de la contribution sociale g&#233;n&#233;ralis&#233;e et de la contribution pour le remboursement de la dette sociale.</p><p style="text-align: justify;">En effet, la loi de finances rectificatives pour 2012 a &#233;tendu les pr&#233;l&#232;vements sociaux aux revenus immobiliers (revenus fonciers et plus-values immobili&#232;res) de source fran&#231;aise per&#231;us par les personnes physiques fiscalement domicili&#233;es hors de France.</p><p style="text-align: justify;">Par cette mesure, les Fran&#231;ais non-r&#233;sidents contribuent au financement des r&#233;gimes obligatoires de la s&#233;curit&#233; sociale, dont ils ne b&#233;n&#233;ficient pourtant pas dans la majorit&#233; des cas, leur protection sociale relevant soit d&#8217;un r&#233;gime volontaire de la Caisse des Fran&#231;ais de l&#8217;&#233;tranger soit d&#8217;un syst&#232;me de protection sociale de leur pays de r&#233;sidence.</p><p style="text-align: justify;">Il en r&#233;sulte une double imposition pour les contribuables non-r&#233;sidents affili&#233;s &#224; un r&#233;gime de s&#233;curit&#233; sociale dans leur pays de r&#233;sidence et assujettis de fait aux pr&#233;l&#232;vements sociaux &#224; la fois en France et dans le pays o&#249; ils r&#233;sident.</p><p style="text-align: justify;">Cette situation est contraire au droit de l&#8217;Union europ&#233;enne et particuli&#232;rement au R&#232;glement (CEE) n&#176; 1408/71 du Conseil, du 14 juin 1971, relatif &#224; l&#8217;application des r&#233;gimes de s&#233;curit&#233; sociale aux travailleurs salari&#233;s, aux travailleurs non-salari&#233;s et aux membres de leur famille qui se d&#233;placent &#224; l&#8217;int&#233;rieur de la Communaut&#233;, qui subordonne le paiement des cotisations sociales au b&#233;n&#233;fice du r&#233;gime obligatoire de s&#233;curit&#233; sociale.</p></body>',  # noqa
        "Sort ": "Adopté",
        "Subdivision ": "art. add. après Article 7",
        "Url amendement ": "//www.senat.fr/amendements/2017-2018/63/Amdt_1.html",  # noqa
    }

    DBSession.add(lecture_senat)

    source = Senat()
    amendement, created = source.parse_from_csv(amend, lecture_senat)

    assert created
    assert amendement.num == 1
    assert amendement.rectif == 1
    assert amendement.num_disp == "1 rect."
    assert amendement.date_depot == date(2017, 11, 13)
    assert amendement.sort == "Adopté"

    assert (
        amendement.corps
        == "<p>Après l’article 7</p><p>Insérer un article additionnel ainsi rédigé :</p><p>I. – Le code de la sécurité sociale est ainsi modifié :</p><p>1° L’article L. 136‑6 est ainsi modifié :</p><p>a) Le I bis est abrogé ;</p><p>b) À la première phase du premier alinéa du III, la première occurrence du mot : « à » est remplacée par le mot : « et » ;</p><p>2° L’article L. 136‑7 est ainsi modifié :</p><p>a) Le I bis est abrogé ;</p><p>b) Le second alinéa du VI est supprimé ;</p><p>3° L’article L. 245‑14 est ainsi modifié :</p><p>a) À la première phrase, les références : « aux I et II de » sont remplacées par le mot : « à » ;</p><p>b) La deuxième phrase est supprimée ;</p><p>4° Au premier alinéa de l’article L. 245‑15, la deuxième occurrence du mot : « à » est remplacée par le mot : « et ».</p><p>II. – L’ordonnance n° 96‑50 du 24 janvier 1996 relative au remboursement de la dette sociale est ainsi modifiée :</p><p>1° La seconde phrase du premier alinéa du I de l’article 15 est supprimée ;</p><p>2° À la première phrase du I de l’article 16, les références : « aux I et I bis » sont remplacés par les mots : « au I ».</p><p>III. – 1° Les 1° et 3° du I et le 1° du II s’appliquent aux revenus perçus à compter du 1<sup>er</sup> janvier 2012 ;</p><p>2° Les 2° et 4° du I s’appliquent aux plus‑values réalisées au titre des cessions intervenues à compter de la date de publication de la présente loi ;</p><p>3° Le 2° du II s’applique aux plus‑values réalisées au titre des cessions intervenues à compter du 1<sup>er</sup> janvier 2012.</p><p>IV. – La perte de recettes résultant pour les organismes de sécurité sociale des I à III est compensée, à due concurrence, par la création d’une taxe additionnelle aux droits prévus aux articles 575 et 575 A du code général des impôts.</p>"  # noqa
    )
    assert (
        amendement.expose
        == "<p>Cet amendement vise à rectifier une anomalie, celle de l’assujettissement des Français établis hors de France au paiement de la contribution sociale généralisée et de la contribution pour le remboursement de la dette sociale.</p><p>En effet, la loi de finances rectificatives pour 2012 a étendu les prélèvements sociaux aux revenus immobiliers (revenus fonciers et plus-values immobilières) de source française perçus par les personnes physiques fiscalement domiciliées hors de France.</p><p>Par cette mesure, les Français non-résidents contribuent au financement des régimes obligatoires de la sécurité sociale, dont ils ne bénéficient pourtant pas dans la majorité des cas, leur protection sociale relevant soit d’un régime volontaire de la Caisse des Français de l’étranger soit d’un système de protection sociale de leur pays de résidence.</p><p>Il en résulte une double imposition pour les contribuables non-résidents affiliés à un régime de sécurité sociale dans leur pays de résidence et assujettis de fait aux prélèvements sociaux à la fois en France et dans le pays où ils résident.</p><p>Cette situation est contraire au droit de l’Union européenne et particulièrement au Règlement (CEE) n° 1408/71 du Conseil, du 14 juin 1971, relatif à l’application des régimes de sécurité sociale aux travailleurs salariés, aux travailleurs non-salariés et aux membres de leur famille qui se déplacent à l’intérieur de la Communauté, qui subordonne le paiement des cotisations sociales au bénéfice du régime obligatoire de sécurité sociale.</p>"  # noqa
    )
Ejemplo n.º 4
0
def test_article_changed(lecture_senat):
    """
    The targeted article may change
    """

    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=read_sample_data("jeu_complet_2017-2018_63-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=read_sample_data("jeu_complet_2017-2018_63-short-article.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=read_sample_data("ODSEN_GENERAL-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short.json"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short-article.json"),
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    source.fetch(lecture_senat)

    assert {amdt.num: str(amdt.article) for amdt in lecture_senat.amendements} == {
        31: "Art. 3",
        443: "Art. 4",
    }

    source.fetch(lecture_senat)

    assert {amdt.num: str(amdt.article) for amdt in lecture_senat.amendements} == {
        31: "Art. 3",
        443: "Art. 3",
    }
Ejemplo n.º 5
0
def test_abandoned_before_seance(lecture_senat):
    """
    An amendement that is either withdrawn by its author or declared invalid
    will be removed from the "liste_discussion"
    """

    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=read_sample_data("jeu_complet_2017-2018_63-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=read_sample_data("ODSEN_GENERAL-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short.json"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short-retire.json"),
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    source.fetch(lecture_senat)

    assert {amdt.num: amdt.position for amdt in lecture_senat.amendements} == {
        31: 1,
        443: 2,
    }

    source.fetch(lecture_senat)

    assert {amdt.num: amdt.position for amdt in lecture_senat.amendements} == {
        31: 1,
        443: None,
    }
Ejemplo n.º 6
0
def test_position_changed(lecture_senat):
    """
    The discussion order of amendements may change
    """

    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=read_sample_data("jeu_complet_2017-2018_63-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=read_sample_data("ODSEN_GENERAL-short.csv"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short.json"),
        status=200,
    )
    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        body=read_sample_data("liste_discussion_63-short-position.json"),
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    source.fetch(lecture_senat)

    assert {amdt.num: amdt.position for amdt in lecture_senat.amendements} == {
        31: 1,
        443: 2,
    }

    source.fetch(lecture_senat)

    assert {amdt.num: amdt.position for amdt in lecture_senat.amendements} == {
        31: 2,
        443: 1,
    }
Ejemplo n.º 7
0
def test_aspire_senat(app, lecture_senat):
    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession
    from zam_repondeur.models.events.amendement import (
        AmendementRectifie,
        CorpsAmendementModifie,
        ExposeAmendementModifie,
    )

    sample_data = read_sample_data("jeu_complet_2017-2018_63.csv")

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=sample_data,
        status=200,
    )

    odsen_data = read_sample_data("ODSEN_GENERAL.csv")

    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=odsen_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_63.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        json=json_data,
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    amendements, created, errored = source.fetch(lecture_senat)

    # All amendements are fetched
    assert len(amendements) == 595

    # Check details of #1
    amendement = [
        amendement for amendement in amendements if amendement.num == 1
    ][0]
    assert amendement.num == 1
    assert amendement.rectif == 1
    assert amendement.article.num == "7"
    assert amendement.article.pos == "après"
    assert amendement.parent is None

    events = sorted(amendement.events,
                    key=attrgetter("created_at"),
                    reverse=True)

    assert len(events) == 3
    assert isinstance(events[0], ExposeAmendementModifie)
    assert events[0].created_at is not None
    assert events[0].user is None
    assert events[0].data["old_value"] == ""
    assert events[0].data["new_value"].startswith("<p>Cet amendement vise")
    assert events[0].render_summary(
    ) == "L’exposé de l’amendement a été initialisé"

    assert isinstance(events[1], CorpsAmendementModifie)
    assert events[1].created_at is not None
    assert events[1].user is None
    assert events[1].data["old_value"] == ""
    assert events[1].data["new_value"].startswith("<p>Après l’article")
    assert events[1].render_summary(
    ) == "Le corps de l’amendement a été initialisé"

    assert isinstance(events[2], AmendementRectifie)
    assert events[2].created_at is not None
    assert events[2].user is None
    assert events[2].data["old_value"] == 0
    assert events[2].data["new_value"] == 1
    assert events[2].render_summary() == "L’amendement a été rectifié"

    # Check that #596 has a parent
    sous_amendement = [
        amendement for amendement in amendements if amendement.num == 596
    ][0]
    assert sous_amendement.parent.num == 229
    assert sous_amendement.parent.rectif == 1
Ejemplo n.º 8
0
def test_aspire_senat_plf2019_2e_partie(app, texte_senat, dossier_plf):
    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession, Lecture

    with transaction.manager:
        texte_senat.numero = 146
        lecture = Lecture.create(
            chambre="senat",
            session="2018-2019",
            texte=texte_senat,
            partie=2,
            titre="Numéro lecture – Titre lecture sénat",
            organe="PO78718",
            dossier=dossier_plf,
        )

    sample_data = read_sample_data("jeu_complet_2018-2019_146.csv")

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2018-2019/146/jeu_complet_2018-2019_146.csv",
        body=sample_data,
        status=200,
    )

    odsen_data = read_sample_data("ODSEN_GENERAL.csv")

    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=odsen_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_103394.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103394.json",
        json=json_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_103395.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103395.json",
        json=json_data,
        status=200,
    )

    for i in range(103396, 103445 + 1):
        responses.add(
            responses.GET,
            f"https://www.senat.fr/enseance/2018-2019/146/liste_discussion_{i}.json",
            status=404,
        )

    DBSession.add(lecture)

    source = Senat()

    amendements, created, errored = source.fetch(lecture)

    # All amendements from part 2 are fetched
    assert len(amendements) == 35

    # Positions are unique
    positions = [
        amdt.position for amdt in amendements if amdt.position is not None
    ]
    assert len(set(positions)) == len(positions) == 12
Ejemplo n.º 9
0
def test_aspire_senat_again_with_irrecevable_transfers_to_index(
        app, lecture_senat, user_david_table_an):
    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession
    from zam_repondeur.models.events.amendement import (
        AmendementIrrecevable,
        AmendementTransfere,
    )

    sample_data = read_sample_data("jeu_complet_2017-2018_63.csv")

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=sample_data,
        status=200,
    )
    # On second call we want an irrecevable.
    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=sample_data.decode("latin-1").replace(
            "Adopté\t//www.senat.fr/amendements/2017-2018/63/Amdt_1.html",
            "Irrecevable\t//www.senat.fr/amendements/2017-2018/63/Amdt_1.html",
        ).encode("latin-1"),
        status=200,
    )

    odsen_data = read_sample_data("ODSEN_GENERAL.csv")

    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=odsen_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_63.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        json=json_data,
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    # Let's fetch a new amendement
    amendements, created, errored = source.fetch(lecture_senat)
    amendement = [
        amendement for amendement in amendements if amendement.num == 1
    ][0]
    assert len(amendement.events) == 3

    # Put it on a user table
    DBSession.add(user_david_table_an)
    user_david_table_an.amendements.append(amendement)
    assert user_david_table_an.amendements == [amendement]
    assert amendement.user_table == user_david_table_an

    # Now fetch the same amendement again (now irrecevable)
    amendements, created, errored = source.fetch(lecture_senat)
    amendement = [
        amendement for amendement in amendements if amendement.num == 1
    ][0]
    assert len(amendement.events) == 5  # two more

    # An irrecevable event has been created
    assert any(
        isinstance(event, AmendementIrrecevable)
        for event in amendement.events)

    # An automatic transfer event has been created
    assert any(
        isinstance(event, AmendementTransfere) for event in amendement.events)
    transfer_event = next(event for event in amendement.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")

    # The amendement is now on the index
    assert amendement.user_table is None
    assert user_david_table_an.amendements == []
Ejemplo n.º 10
0
def test_aspire_senat_again_with_irrecevable(app, lecture_senat):
    from zam_repondeur.fetch.senat.amendements import Senat
    from zam_repondeur.models import DBSession
    from zam_repondeur.models.events.amendement import AmendementIrrecevable

    sample_data = read_sample_data("jeu_complet_2017-2018_63.csv")

    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=sample_data,
        status=200,
    )
    # On second call we want an irrecevable.
    responses.add(
        responses.GET,
        "https://www.senat.fr/amendements/2017-2018/63/jeu_complet_2017-2018_63.csv",
        body=sample_data.decode("latin-1").replace(
            "Adopté\t//www.senat.fr/amendements/2017-2018/63/Amdt_1.html",
            "Irrecevable\t//www.senat.fr/amendements/2017-2018/63/Amdt_1.html",
        ).encode("latin-1"),
        status=200,
    )

    odsen_data = read_sample_data("ODSEN_GENERAL.csv")

    responses.add(
        responses.GET,
        "https://data.senat.fr/data/senateurs/ODSEN_GENERAL.csv",
        body=odsen_data,
        status=200,
    )

    json_data = json.loads(read_sample_data("liste_discussion_63.json"))

    responses.add(
        responses.GET,
        "https://www.senat.fr/enseance/2017-2018/63/liste_discussion.json",
        json=json_data,
        status=200,
    )

    DBSession.add(lecture_senat)

    source = Senat()

    amendements, created, errored = source.fetch(lecture_senat)
    amendement = [
        amendement for amendement in amendements if amendement.num == 1
    ][0]
    assert len(amendement.events) == 3

    amendements, created, errored = source.fetch(lecture_senat)
    amendement = [
        amendement for amendement in amendements if amendement.num == 1
    ][0]
    assert len(amendement.events) == 4

    assert isinstance(amendement.events[3], AmendementIrrecevable)
    assert amendement.events[3].created_at is not None
    assert amendement.events[3].user is None
    assert amendement.events[3].data["old_value"] == "Adopté"
    assert amendement.events[3].data["new_value"] == "Irrecevable"
    assert (amendement.events[3].render_summary() ==
            "L’amendement a été déclaré irrecevable par les services du Sénat")