def test_post_form(app): from zam_repondeur.models import Lecture assert not Lecture.exists( chambre="an", session="15", num_texte=269, organe="PO717460" ) # We cannot use form.submit() given the form is dynamic and does not # contain choices for lectures (dynamically loaded via JS). resp = app.post( "/lectures/add", {"dossier": "DLR5L15N36030", "lecture": "PRJLANR5L15B0269-PO717460"}, ) assert resp.status_code == 302 assert resp.location == "http://localhost/lectures/an.15.269.PO717460/" resp = resp.follow() assert resp.status_code == 200 assert "Lecture créée avec succès." in resp.text lecture = Lecture.get(chambre="an", session="15", num_texte=269, organe="PO717460") assert lecture.chambre == "an" assert lecture.titre == "1ère lecture" assert lecture.dossier_legislatif == "Sécurité sociale : loi de financement 2018"
def test_lecture_delete(app, dummy_lecture, dummy_amendements): from zam_repondeur.models import Amendement, DBSession, Lecture assert Lecture.exists( chambre=dummy_lecture.chambre, session=dummy_lecture.session, num_texte=dummy_lecture.num_texte, organe=dummy_lecture.organe, ) assert DBSession.query(Amendement).count() == 2 form = app.get("http://localhost/lectures/an.15.269.PO717460/" ).forms["delete-lecture"] resp = form.submit() assert resp.status_code == 302 assert resp.location == "http://localhost/lectures/" resp = resp.follow() assert resp.status_code == 200 assert "Lecture supprimée avec succès." in resp.text assert not Lecture.exists( chambre=dummy_lecture.chambre, session=dummy_lecture.session, num_texte=dummy_lecture.num_texte, organe=dummy_lecture.organe, ) assert DBSession.query(Amendement).count() == 0
def create_or_update_lecture(dossier: Dossier, lecture_ref: LectureRef, user: Optional[User]) -> bool: changed = False lecture_created = False lecture_updated = False texte = Texte.get_or_create_from_ref(lecture_ref.texte, lecture_ref.chambre) lecture = Lecture.get_from_ref(lecture_ref, dossier) if lecture is not None and lecture.texte is not texte: # We probably created the Lecture before a new Texte was adopted # by the commission. Time to update with the final one! TexteMisAJour.create(lecture=lecture, texte=texte) lecture_updated = True if lecture is None: lecture = Lecture.create_from_ref(lecture_ref, dossier, texte) LectureCreee.create(lecture=lecture, user=user) lecture_created = True if lecture_created or lecture_updated: changed = True # Make sure the lecture gets its primary key. DBSession.flush() # Enqueue tasks to fetch articles and amendements. huey.enqueue_on_transaction_commit(fetch_articles.s(lecture.pk)) huey.enqueue_on_transaction_commit(fetch_amendements.s(lecture.pk)) return changed
def post(self) -> Response: dossier = self._get_dossier() lecture = self._get_lecture(dossier) chambre = lecture.chambre.value num_texte = lecture.texte.numero titre = lecture.titre organe = lecture.organe # FIXME: use date_depot to find the right session? if lecture.chambre == Chambre.AN: session = "15" else: session = "2017-2018" if LectureModel.exists(chambre, session, num_texte, organe): self.request.session.flash( ("warning", "Cette lecture existe déjà...")) else: LectureModel.create(chambre, session, num_texte, titre, organe, dossier.titre) self.request.session.flash( ("success", "Lecture créée avec succès.")) resource = self.context[f"{chambre}.{session}.{num_texte}.{organe}"] return HTTPFound(location=self.request.resource_url(resource))
def test_derouleur_urls_plf2019_2e_partie(texte_senat, dossier_plf): from zam_repondeur.fetch.senat.derouleur import derouleur_urls from zam_repondeur.models import Lecture texte_senat.numero = 146 lecture = Lecture.create( chambre="senat", session="2018-2019", texte=texte_senat, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf, ) urls = list(derouleur_urls(lecture)) assert len(urls) > 1 assert ( urls[0] == "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103427.json" ) assert ( urls[-1] == "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103394.json" )
def fetch_amendements_for_dossier( dossier_ref: DossierRef, chambre: Optional[str], num: Optional[int], settings: Dict[str, Any], ) -> None: dossier, _ = get_one_or_create( Dossier, an_id=dossier_ref.uid, create_kwargs=dict(titre=dossier_ref.titre, slug=dossier_ref.slug), ) for lecture_ref in dossier_ref.lectures: texte_ref = lecture_ref.texte if chambre is not None and texte_ref.chambre.name.lower() != chambre: continue if num is not None and texte_ref.numero != num: continue texte, _ = get_one_or_create( Texte, type_=texte_ref.type_, chambre=texte_ref.chambre, legislature=texte_ref.legislature, session=texte_ref.session, numero=texte_ref.numero, date_depot=texte_ref.date_depot, ) lecture = Lecture.create( phase=lecture_ref.phase, dossier=dossier, texte=texte, partie=lecture_ref.partie, organe=lecture_ref.organe, titre=lecture_ref.titre, ) fetch_amendements_for_lecture(lecture, settings)
def test_post_shared_tables_create_form(app, lecture_an, amendements_an, user_david): from zam_repondeur.models import DBSession, Lecture, SharedTable with transaction.manager: DBSession.add(user_david) resp = app.get( "/dossiers/plfss-2018/lectures/an.15.269.PO717460/boites/add", user=user_david) form = resp.forms["box-upsert"] form["titre"] = "Test table" resp = form.submit() assert resp.status_code == 302 assert resp.location == ("https://zam.test" "/dossiers/plfss-2018" "/lectures/an.15.269.PO717460" "/options#shared-tables") resp = resp.follow() assert resp.status_code == 200 assert "Test table" in resp.text shared_table = (DBSession.query(SharedTable).filter( SharedTable.titre == "Test table").one()) assert shared_table.slug == "test-table" assert shared_table.lecture.pk == lecture_an.pk # A dedicated event should be created. lecture_an = Lecture.get_by_pk(lecture_an.pk) # refresh object assert len(lecture_an.events) == 1 assert lecture_an.events[0].render_summary() == ( "<abbr title='*****@*****.**'>David</abbr> " "a créé la boîte « Test table »")
def apply(self, lecture: Lecture) -> FetchResult: amendement = lecture.find_amendement(self.amendement_num) if amendement is None: return FetchResult.create(errored={self.amendement_num}) article = self._get_article(lecture) parent = self._get_parent(lecture, article) if amendement.location.batch and amendement.article.pk != article.pk: BatchUnset.create(amendement=amendement, request=None) Source.update_rectif(amendement, self.rectif) Source.update_corps(amendement, self.corps) Source.update_expose(amendement, self.expose) Source.update_sort(amendement, self.sort) Source.update_attributes( amendement, article=article, parent=parent, position=self.position, tri_amendement=self.tri_amendement, id_discussion_commune=self.id_discussion_commune, id_identique=self.id_identique, matricule=self.matricule, groupe=self.groupe, auteur=self.auteur, mission_titre=self.mission_titre, mission_titre_court=self.mission_titre_court, date_depot=self.date_depot, ) return FetchResult.create(fetched={self.amendement_num})
def test_upload_liasse_missing_file( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import Lecture resp = app.get( "/dossiers/etat-service-societe-confiance/lectures/an.15.806.PO744107/options", user=user_david, ) form = resp.forms["import-liasse-xml"] resp = form.submit() assert resp.status_code == 302 assert resp.location == ("https://zam.test/" "dossiers/etat-service-societe-confiance/" "lectures/an.15.806.PO744107/" "options") resp = resp.follow() assert "Veuillez d’abord sélectionner un fichier" in resp.text # Check the update timestamp has NOT been updated. lecture = Lecture.get_by_pk( lecture_essoc2018_an_nouvelle_lecture_commission_fond.pk) assert lecture.events == []
def test_upload_liasse_with_table( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import Lecture resp = app.get("/lectures/an.15.806.PO744107/options", user=user_david) form = resp.forms["import-liasse-xml"] form["liasse"] = Upload( "liasse.xml", (SAMPLE_DATA / "liasse_with_table.xml").read_bytes()) resp = form.submit() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/an.15.806.PO744107/amendements" resp = resp.follow() assert "3 nouveaux amendements récupérés (import liasse XML)." in resp.text lecture = Lecture.get( chambre=lecture_essoc2018_an_nouvelle_lecture_commission_fond.chambre, session_or_legislature= lecture_essoc2018_an_nouvelle_lecture_commission_fond.session, # noqa num_texte=lecture_essoc2018_an_nouvelle_lecture_commission_fond.texte. numero, partie=None, organe=lecture_essoc2018_an_nouvelle_lecture_commission_fond.organe, ) assert ("<table>\n<tbody>\n<tr>\n<td>Durée minimale de services" in lecture.amendements[1].corps) assert ("<table>\n<tbody>\n<tr>\n<td>Durée minimale de services" in lecture.amendements[0].expose)
def test_upload_liasse_success( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import DBSession, Lecture with transaction.manager: DBSession.add(user_david) resp = app.get( "/dossiers/etat-service-societe-confiance/lectures/an.15.806.PO744107/options", user=user_david, ) form = resp.forms["import-liasse-xml"] form["liasse"] = Upload("liasse.xml", (SAMPLE_DATA / "liasse.xml").read_bytes()) resp = form.submit() assert resp.status_code == 302 assert resp.location == ("https://zam.test/" "dossiers/etat-service-societe-confiance/" "lectures/an.15.806.PO744107/" "amendements/") resp = resp.follow() assert "3 nouveaux amendements récupérés (import liasse XML)." in resp.text lecture = Lecture.get_by_pk( lecture_essoc2018_an_nouvelle_lecture_commission_fond.pk) assert lecture.events[0].render_summary() == ( "<abbr title='*****@*****.**'>David</abbr> a importé " "une liasse XML : 3 nouveaux amendements récupérés.")
def test_upload_liasse_missing_file( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import Lecture resp = app.get("/lectures/an.15.806.PO744107/options", user=user_david) form = resp.forms["import-liasse-xml"] resp = form.submit() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/an.15.806.PO744107/options" resp = resp.follow() assert "Veuillez d’abord sélectionner un fichier" in resp.text # Check the update timestamp has NOT been updated. lecture = Lecture.get( chambre=lecture_essoc2018_an_nouvelle_lecture_commission_fond.chambre, session_or_legislature= lecture_essoc2018_an_nouvelle_lecture_commission_fond.session, # noqa num_texte=lecture_essoc2018_an_nouvelle_lecture_commission_fond.texte. numero, partie=None, organe=lecture_essoc2018_an_nouvelle_lecture_commission_fond.organe, ) assert lecture.events == []
def test_upload_liasse_success( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import Lecture resp = app.get("/lectures/an.15.806.PO744107/options", user=user_david) form = resp.forms["import-liasse-xml"] form["liasse"] = Upload("liasse.xml", (SAMPLE_DATA / "liasse.xml").read_bytes()) resp = form.submit() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/an.15.806.PO744107/amendements" resp = resp.follow() assert "3 nouveaux amendements récupérés (import liasse XML)." in resp.text lecture = Lecture.get( chambre=lecture_essoc2018_an_nouvelle_lecture_commission_fond.chambre, session_or_legislature= lecture_essoc2018_an_nouvelle_lecture_commission_fond.session, # noqa num_texte=lecture_essoc2018_an_nouvelle_lecture_commission_fond.texte. numero, partie=None, organe=lecture_essoc2018_an_nouvelle_lecture_commission_fond.organe, ) assert lecture.events[0].render_summary() == ( "<abbr title='*****@*****.**'>[email protected]</abbr> a importé " "une liasse XML : 3 nouveaux amendements récupérés.")
def test_post_form_already_exists(app, dummy_lecture): from zam_repondeur.models import Lecture assert Lecture.exists(chambre="an", session="15", num_texte=269, organe="PO717460") # We cannot use form.submit() given the form is dynamic and does not # contain choices for lectures (dynamically loaded via JS). resp = app.post( "/lectures/add", { "dossier": "DLR5L15N36030", "lecture": "PRJLANR5L15B0269-PO717460" }, ) assert resp.status_code == 302 assert resp.location == "http://localhost/lectures/an.15.269.PO717460/" resp = resp.follow() assert resp.status_code == 200 assert "Cette lecture existe déjà..." in resp.text
def test_derouleur_urls_and_mission_refs_plf2019_2e_partie( dossier_plf_2019, texte_plf_2019): from zam_repondeur.models import Lecture, Phase from zam_repondeur.services.fetch.missions import MissionRef from zam_repondeur.services.fetch.senat.derouleur import ( derouleur_urls_and_mission_refs, ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2019, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf_2019, ) urls = list(derouleur_urls_and_mission_refs(lecture)) assert len(urls) == 52 assert urls[0] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103414.json", MissionRef( titre="Mission Action et transformation publiques", titre_court="Action transfo.", ), ) assert urls[1] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103415.json", MissionRef(titre="Mission Action extérieure de l'État", titre_court="Action ext."), ) assert urls[-1] == ( "https://www.senat.fr/enseance/2018-2019/146/liste_discussion_103394.json", MissionRef(titre="", titre_court=""), )
def test_derouleur_urls_and_mission_refs_plf2020_2e_partie( dossier_plf_2020, texte_plf_2020): from zam_repondeur.models import Lecture, Phase from zam_repondeur.services.fetch.missions import MissionRef from zam_repondeur.services.fetch.senat.derouleur import ( derouleur_urls_and_mission_refs, ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2020, partie=2, titre="Première lecture – Séance publique (2e partie)", organe="PO78718", dossier=dossier_plf_2020, ) urls = list(derouleur_urls_and_mission_refs(lecture)) assert len(urls) == 50 assert urls[0] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103930.json", MissionRef(titre="", titre_court=""), ) assert urls[1] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103931.json", MissionRef( titre="Budget annexe - Contrôle et exploitation aériens", titre_court="Contrôle et exploitation aériens", ), ) assert urls[-1] == ( "https://www.senat.fr/enseance/2019-2020/139/liste_discussion_103979.json", MissionRef(titre="Mission Travail et emploi", titre_court="Trav. emploi"), )
def test_post_form_already_exists( app, texte_plfss2018_an_premiere_lecture, lecture_an, user_david ): from zam_repondeur.models import DBSession, Lecture assert Lecture.exists( chambre="an", session="15", texte=texte_plfss2018_an_premiere_lecture, partie=None, organe="PO717460", ) # We cannot use form.submit() given the form is dynamic and does not # contain choices for lectures (dynamically loaded via JS). resp = app.post( "/lectures/add", {"dossier": "DLR5L15N36030", "lecture": "PRJLANR5L15B0269-PO717460-"}, user=user_david, ) assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/" resp = resp.follow() assert resp.status_code == 200 assert "Cette lecture existe déjà…" in resp.text DBSession.add(lecture_an) assert len(lecture_an.events) == 0
def test_upload_liasse_with_table( app, lecture_essoc2018_an_nouvelle_lecture_commission_fond, user_david): from zam_repondeur.models import Lecture resp = app.get( "/dossiers/etat-service-societe-confiance/lectures/an.15.806.PO744107/options", user=user_david, ) form = resp.forms["import-liasse-xml"] form["liasse"] = Upload( "liasse.xml", (SAMPLE_DATA / "liasse_with_table.xml").read_bytes()) resp = form.submit() assert resp.status_code == 302 assert resp.location == ("https://zam.test/" "dossiers/etat-service-societe-confiance/" "lectures/an.15.806.PO744107/" "amendements/") resp = resp.follow() assert "3 nouveaux amendements récupérés (import liasse XML)." in resp.text lecture = Lecture.get_by_pk( lecture_essoc2018_an_nouvelle_lecture_commission_fond.pk) assert ("<table>\n<tbody>\n<tr>\n<td>Durée minimale de services" in lecture.amendements[1].corps) assert ("<table>\n<tbody>\n<tr>\n<td>Durée minimale de services" in lecture.amendements[0].expose)
def test_upload_adds_an_event(self, app, lecture_an, filename, user_david): from zam_repondeur.models import Lecture from zam_repondeur.models.events.lecture import ReponsesImportees self._upload_csv(app, filename, user=user_david) lecture = Lecture.get_by_pk(lecture_an.pk) # refresh object events = {type(event): event for event in lecture.events} assert ReponsesImportees in events
def test_post_form(app, lecture_an, lecture_an_url, article1_an, user_david): from zam_repondeur.models import Amendement, DBSession, Lecture # Initially, we only have one amendement (#135), with a response with transaction.manager: DBSession.add(lecture_an) lecture_an.texte.date_depot = datetime.utcnow().date() - timedelta( days=5) Amendement.create(lecture=lecture_an, article=article1_an, num=135, position=1) assert lecture_an.events == [] # No progress status by default. assert lecture_an.get_fetch_progress() == {} with setup_mock_responses( lecture=lecture_an, liste=read_sample_data("an/269/liste.xml"), amendements=( ("177", read_sample_data("an/269/177.xml")), ("270", read_sample_data("an/269/270.xml")), ("723", read_sample_data("an/269/723.xml")), ("135", read_sample_data("an/269/135.xml")), ("192", read_sample_data("an/269/192.xml")), ), ): # Then we ask for a refresh form = app.get( "/dossiers/plfss-2018/lectures/an.15.269.PO717460/journal/", user=user_david).forms["manual-refresh"] resp = form.submit() assert resp.status_code == 302 assert resp.location == f"https://zam.test{lecture_an_url}/amendements/" resp = resp.follow() assert resp.status_code == 200 lecture_an = Lecture.get_by_pk(lecture_an.pk) # refresh object events = lecture_an.events assert len(events) == 1 assert events[0].render_summary() == "4 nouveaux amendements récupérés." assert "Rafraîchissement des amendements en cours." in resp.text # Default progress status for dummy progress bar is set. assert lecture_an.get_fetch_progress() == {"current": 1, "total": 10} # If we fetch again the journal, the refresh button is not present anymore. resp = app.get("/dossiers/plfss-2018/lectures/an.15.269.PO717460/journal/", user=user_david) assert resp.status_code == 200 assert "manual-refresh" not in resp.forms
def _do_upload_liasse_xml(context: LectureResource, request: Request) -> Response: try: liasse_field = request.POST["liasse"] except KeyError: request.session.flash( ("warning", "Veuillez d’abord sélectionner un fichier")) return if liasse_field == b"": request.session.flash( ("warning", "Veuillez d’abord sélectionner un fichier")) return try: amendements = import_liasse_xml(liasse_field.file) except ValueError: request.session.flash( ("danger", "Le format du fichier n’est pas valide.")) return if len(amendements) == 0: request.session.flash( ("warning", "Aucun amendement n’a été trouvé dans ce fichier.")) return lecture = context.model() filtered_amendements = [ amendement for amendement in amendements if amendement.chambre == lecture.chambre and amendement.session == lecture.session and amendement.num_texte == lecture.num_texte and amendement.organe == lecture.organe ] ignored = len(amendements) - len(filtered_amendements) if len(filtered_amendements) == 0: amendement = amendements[0] other_lecture = Lecture( chambre=amendement.chambre, session=amendement.session, num_texte=amendement.num_texte, organe=amendement.organe, ) request.session.flash( ("danger", f"La liasse correspond à une autre lecture ({other_lecture}).")) return if ignored > 0: request.session.flash( ("warning", f"{ignored} amendements ignorés car non liés à cette lecture.")) added, updated, unchanged = _add_or_update_amendements( filtered_amendements) assert added + updated + unchanged == len(filtered_amendements) _set_flash_messages(request, added, updated, unchanged)
def test_fetch_all_commission(db): from zam_repondeur.models import Chambre, Dossier, Lecture, Phase, Texte, TypeTexte from zam_repondeur.services.fetch.senat.amendements import _fetch_all with transaction.manager: dossier = Dossier.create( senat_id="pjl17-583", titre="Liberté de choisir son avenir professionnel", slug="liberte-choisir-avenir-professionnel", ) texte = Texte.create( type_=TypeTexte.PROJET, chambre=Chambre.SENAT, session=2017, numero=583, date_depot=date(2018, 6, 20), ) lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte, titre="Première lecture – Commissions", organe=None, dossier=dossier, ) sample_data = read_sample_data("jeu_complet_commission_2017-2018_583.csv") responses.add( responses.GET, "https://www.senat.fr/amendements/commissions/2017-2018/583/jeu_complet_commission_2017-2018_583.csv", # noqa body=sample_data, status=200, ) items = _fetch_all(lecture) assert len(items) == 434 assert items[0] == { "Nature ": "Amt", "Numéro ": "COM-1", "Subdivision ": "Article 40", "Alinéa": "36", "Auteur ": "M. FORISSIER, rapporteur", "Au nom de ": "", "Date de dépôt ": "2018-06-21", "Dispositif ": "<body><p>Alinéa 36</p><p>Après le mot :</p><p>services</p><p>Insérer les mots :</p><p>ou à des partenariats</p><p></p></body> ", # noqa "Objet ": "<body><p>Cet amendement vise à inclure parmi les dépenses pouvant être déduites de la contribution financière annuelle, en plus des contrats de sous-traitance et de prestations, les <b>dépenses afférentes à des partenariats</b> avec les entreprises adaptées, les Esat et les travailleurs handicapés indépendants.</p><p>En effet, le nouveau mode de déduction des montants de ces contrats de la contribution annuelle risque de moins inciter les employeurs à leur conclusion. D'où l'intérêt d'élargir cette déduction aux autres actions qu'ils sont susceptibles de mener auprès des EA et des Esat notamment.</p></body> ", # noqa "Sort ": "Adopté", "Url amendement ": "//www.senat.fr/amendements/commissions/2017-2018/583/Amdt_COM-1.html", # noqa "Fiche Sénateur": "//www.senat.fr/senfic/forissier_michel14087w.html", }
def apply_changes(self, lecture: Lecture, changes: CollectedChanges) -> FetchResult: result = FetchResult.create( fetched=changes.unchanged, errored=changes.errored, next_start_index=changes.next_start_index, ) # Build amendement -> position map moved_amendements = { amendement: changes.position_changes[amendement.num] for amendement in lecture.amendements if amendement.num in changes.position_changes } # Reset positions first, so that we never have two with the same position # (which would trigger an integrity error due to the unique constraint) for amendement in moved_amendements: amendement.position = None DBSession.flush() # Create amendements in numerical order, because a "sous-amendement" # must always be created after its parent for create_action in sorted(changes.creates, key=attrgetter("num")): result += create_action.apply(lecture) # Update amendements for update_action in changes.updates: result += update_action.apply(lecture) # Apply new amendement positions for amendement, position in moved_amendements.items(): if amendement.position != position: amendement.position = position DBSession.flush() # Was it the last batch? if changes.next_start_index is None: lecture.reset_fetch_progress() return result
def test_post_form(app, lecture_an, article1_an, user_david): from zam_repondeur.models import Amendement, Lecture # Initially, we only have one amendement (#135), with a response with transaction.manager: Amendement.create(lecture=lecture_an, article=article1_an, num=135, position=1) assert lecture_an.events == [] with setup_mock_responses( lecture=lecture_an, liste=read_sample_data("an/269/liste.xml"), amendements=( ("177", read_sample_data("an/269/177.xml")), ("270", read_sample_data("an/269/270.xml")), ("723", read_sample_data("an/269/723.xml")), ("135", read_sample_data("an/269/135.xml")), ("192", read_sample_data("an/269/192.xml")), ), ) as mock_resp: mock_resp.add( responses.GET, "http://www.assemblee-nationale.fr/15/projets/pl0269.asp", body=(Path(__file__).parent / "sample_data" / "pl0269.html").read_text( "utf-8", "ignore" ), status=200, ) # Then we ask for a refresh form = app.get("/lectures/an.15.269.PO717460/journal/", user=user_david).forms[ "manual-refresh" ] resp = form.submit() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/an.15.269.PO717460/amendements" resp = resp.follow() assert resp.status_code == 200 lecture_an = Lecture.get( chambre=lecture_an.chambre, session_or_legislature=lecture_an.session, num_texte=lecture_an.texte.numero, partie=None, organe=lecture_an.organe, ) events = lecture_an.events assert len(events) == 2 assert events[0].render_summary() == "Le contenu des articles a été récupéré." assert events[1].render_summary() == "4 nouveaux amendements récupérés." assert "Rafraichissement des amendements et des articles en cours." in resp.text
def test_an_commission(self): from zam_repondeur.models import Lecture lecture = Lecture(chambre="an", session="15", num_texte=269, titre="bla bla", organe="PO59048") assert ( str(lecture) == "Assemblée nationale, 15e législature, Commission des finances, texte nº 269" # noqa )
def model(self, *options: Any) -> Lecture: lecture = Lecture.get( self.chambre, self.session_or_legislature, self.num_texte, self.partie, self.organe, *options, ) if lecture is None: raise ResourceNotFound(self) return lecture
def lecture_plf_2e_partie(dossier_plf_2019, texte_plf_2019): from zam_repondeur.models import Lecture, Phase with transaction.manager: return Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plf_2019, partie=2, titre="Numéro lecture – Titre lecture sénat", organe="PO78718", dossier=dossier_plf_2019, )
def test_lecture_delete(app, lecture_an, amendements_an, zam_user): from zam_repondeur.models import Amendement, DBSession, Lecture assert zam_user.email.endswith("@zam.beta.gouv.fr") assert Lecture.exists( chambre=lecture_an.chambre, session=lecture_an.session, texte=lecture_an.texte, partie=None, organe=lecture_an.organe, ) assert DBSession.query(Amendement).count() == 2 resp = app.get("/lectures/an.15.269.PO717460/options", user=zam_user) form = resp.forms["delete-lecture"] resp = form.submit() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/" resp = resp.follow() assert resp.status_code == 302 assert resp.location == "https://zam.test/lectures/add" resp = resp.follow() assert resp.status_code == 200 assert "Lecture supprimée avec succès." in resp.text assert not Lecture.exists( chambre=lecture_an.chambre, session=lecture_an.session, texte=lecture_an.texte, partie=None, organe=lecture_an.organe, ) assert DBSession.query(Amendement).count() == 0
def lecture_an(db, dossier_plfss2018, texte_plfss2018_an_premiere_lecture): from zam_repondeur.models import Lecture, Phase with transaction.manager: lecture = Lecture.create( phase=Phase.PREMIERE_LECTURE, texte=texte_plfss2018_an_premiere_lecture, titre="Numéro lecture – Titre lecture", organe="PO717460", dossier=dossier_plfss2018, ) return lecture
def test_senat_seance_publique(self): from zam_repondeur.models import Lecture lecture = Lecture( chambre="senat", session="2017-2018", num_texte=63, titre="bla bla", organe="PO78718", ) assert str( lecture ) == "Sénat, session 2017-2018, Séance publique, texte nº 63"