From 6627a9c6b299257a3bf9de33d96c10eec5bd093b Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 3 Dec 2021 14:13:49 +0100 Subject: [PATCH] traitement exceptions imports xml --- app/but/import_refcomp.py | 36 +- app/models/but_refcomp.py | 5 + app/scodoc/sco_apogee_csv.py | 32 +- app/scodoc/sco_exceptions.py | 2 +- app/scodoc/sco_formations.py | 8 +- app/scodoc/sco_import_etuds.py | 8 +- app/views/refcomp.py | 12 +- tests/data/but-RT-refcomp-exemple.xml | 544 ++++++++++++++++++++++++++ tests/unit/test_refcomp.py | 39 +- 9 files changed, 619 insertions(+), 67 deletions(-) create mode 100644 tests/data/but-RT-refcomp-exemple.xml diff --git a/app/but/import_refcomp.py b/app/but/import_refcomp.py index 6d871175..e0e59ca8 100644 --- a/app/but/import_refcomp.py +++ b/app/but/import_refcomp.py @@ -1,3 +1,8 @@ +############################################################################## +# ScoDoc +# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved. +# See LICENSE +############################################################################## from xml.etree import ElementTree from typing import TextIO @@ -14,14 +19,20 @@ from app.models.but_refcomp import ( ApcAnneeParcours, ApcParcoursNiveauCompetence, ) -from app.scodoc.sco_exceptions import FormatError +from app.scodoc.sco_exceptions import ScoFormatError -def orebut_import_refcomp(xml_file: TextIO, dept_id: int, orig_filename=None): - tree = ElementTree.parse(xml_file) - root = tree.getroot() +def orebut_import_refcomp(xml_data: str, dept_id: int, orig_filename=None): + """Importation XML Orébut + peut lever TypeError ou ScoFormatError + Résultat: instance de ApcReferentielCompetences + """ + try: + root = ElementTree.XML(xml_data) + except ElementTree.ParseError: + raise ScoFormatError("fichier XML Orébut invalide") if root.tag != "referentiel_competence": - raise FormatError("élément racine 'referentiel_competence' manquant") + raise ScoFormatError("élément racine 'referentiel_competence' manquant") args = ApcReferentielCompetences.attr_from_xml(root.attrib) args["dept_id"] = dept_id args["scodoc_orig_filename"] = orig_filename @@ -29,7 +40,7 @@ def orebut_import_refcomp(xml_file: TextIO, dept_id: int, orig_filename=None): db.session.add(ref) competences = root.find("competences") if not competences: - raise FormatError("élément 'competences' manquant") + raise ScoFormatError("élément 'competences' manquant") for competence in competences.findall("competence"): c = ApcCompetence(**ApcCompetence.attr_from_xml(competence.attrib)) ref.competences.append(c) @@ -58,7 +69,7 @@ def orebut_import_refcomp(xml_file: TextIO, dept_id: int, orig_filename=None): # --- PARCOURS parcours = root.find("parcours") if not parcours: - raise FormatError("élément 'parcours' manquant") + raise ScoFormatError("élément 'parcours' manquant") for parcour in parcours.findall("parcour"): parc = ApcParcours(**ApcParcours.attr_from_xml(parcour.attrib)) ref.parcours.append(parc) @@ -71,9 +82,9 @@ def orebut_import_refcomp(xml_file: TextIO, dept_id: int, orig_filename=None): # Retrouve la competence comp = ref.competences.filter_by(titre=nom).all() if len(comp) == 0: - raise FormatError(f"competence {nom} référencée mais on définie") + raise ScoFormatError(f"competence {nom} référencée mais on définie") elif len(comp) > 1: - raise FormatError(f"competence {nom} ambigüe") + raise ScoFormatError(f"competence {nom} ambigüe") ass = ApcParcoursNiveauCompetence( niveau=niveau, annee_parcours=a, competence=comp[0] ) @@ -94,13 +105,14 @@ ref = ApcReferentielCompetences(**ApcReferentielCompetences.attr_from_xml(root.a competences = root.find("competences") if not competences: - raise FormatError("élément 'competences' manquant") + raise ScoFormatError("élément 'competences' manquant") competence = competences.findall("competence")[0] # XXX from app.but.import_refcomp import * -f = open("but-RT-refcomp-30112021.xml") -ref = orebut_import_refcomp(f, 0) +dept_id = models.Departement.query.first().id +data = open("tests/data/but-RT-refcomp-exemple.xml").read() +ref = orebut_import_refcomp(data, dept_id) #------ from app.but.import_refcomp import * ref = ApcReferentielCompetences.query.first() diff --git a/app/models/but_refcomp.py b/app/models/but_refcomp.py index e2a57849..50fbf1e9 100644 --- a/app/models/but_refcomp.py +++ b/app/models/but_refcomp.py @@ -1,3 +1,8 @@ +############################################################################## +# ScoDoc +# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved. +# See LICENSE +############################################################################## """ScoDoc 9 models : Référentiel Compétence BUT 2021 """ from datetime import datetime diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index b23c2215..57f6f441 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -98,7 +98,7 @@ from chardet import detect as chardet_detect import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb from app import log -from app.scodoc.sco_exceptions import ScoValueError, FormatError +from app.scodoc.sco_exceptions import ScoValueError, ScoFormatError from app.scodoc.gen_tables import GenTable from app.scodoc.sco_vdi import ApoEtapeVDI from app.scodoc.sco_codes_parcours import code_semestre_validant @@ -681,7 +681,7 @@ class ApoData(object): self.periode = periode # try: self.read_csv(data) - except FormatError as e: + except ScoFormatError as e: # essaie de retrouver le nom du fichier pour enrichir le message d'erreur filename = "" if self.orig_filename is None: @@ -689,7 +689,7 @@ class ApoData(object): filename = self.titles.get("apoC_Fichier_Exp", filename) else: filename = self.orig_filename - raise FormatError( + raise ScoFormatError( "

Erreur lecture du fichier Apogée %s

" % filename + e.args[0] + "

" @@ -759,13 +759,13 @@ class ApoData(object): def read_csv(self, data: str): if not data: - raise FormatError("Fichier Apogée vide !") + raise ScoFormatError("Fichier Apogée vide !") f = StringIOFileLineWrapper(data) # pour traiter comme un fichier # check that we are at the begining of Apogee CSV line = f.readline().strip() if line != "XX-APO_TITRES-XX": - raise FormatError("format incorrect: pas de XX-APO_TITRES-XX") + raise ScoFormatError("format incorrect: pas de XX-APO_TITRES-XX") # 1-- En-tête: du début jusqu'à la balise XX-APO_VALEURS-XX idx = data.index("XX-APO_VALEURS-XX") @@ -779,13 +779,13 @@ class ApoData(object): # 3-- La section XX-APO_TYP_RES-XX est ignorée: line = f.readline().strip() if line != "XX-APO_TYP_RES-XX": - raise FormatError("format incorrect: pas de XX-APO_TYP_RES-XX") + raise ScoFormatError("format incorrect: pas de XX-APO_TYP_RES-XX") _apo_skip_section(f) # 4-- Définition de colonnes: (on y trouve aussi l'étape) line = f.readline().strip() if line != "XX-APO_COLONNES-XX": - raise FormatError("format incorrect: pas de XX-APO_COLONNES-XX") + raise ScoFormatError("format incorrect: pas de XX-APO_COLONNES-XX") self.cols = _apo_read_cols(f) self.apo_elts = self._group_elt_cols(self.cols) @@ -794,7 +794,7 @@ class ApoData(object): while True: # skip line = f.readline() if not line: - raise FormatError("format incorrect: pas de XX-APO_VALEURS-XX") + raise ScoFormatError("format incorrect: pas de XX-APO_VALEURS-XX") if line.strip() == "XX-APO_VALEURS-XX": break self.column_titles = f.readline() @@ -885,7 +885,7 @@ class ApoData(object): """ m = re.match("[12][0-9]{3}", self.titles["apoC_annee"]) if not m: - raise FormatError( + raise ScoFormatError( 'Annee scolaire (apoC_annee) invalide: "%s"' % self.titles["apoC_annee"] ) return int(m.group(0)) @@ -943,7 +943,7 @@ class ApoData(object): log("Fichier Apogee invalide:") log("Colonnes declarees: %s" % declared) log("Colonnes presentes: %s" % present) - raise FormatError( + raise ScoFormatError( """Fichier Apogee invalide
Colonnes declarees: %s
Colonnes presentes: %s""" % (declared, present) @@ -1032,7 +1032,7 @@ def _apo_read_cols(f): line = f.readline().strip(" " + APO_NEWLINE) fs = line.split(APO_SEP) if fs[0] != "apoL_a01_code": - raise FormatError("invalid line: %s (expecting apoL_a01_code)" % line) + raise ScoFormatError("invalid line: %s (expecting apoL_a01_code)" % line) col_keys = fs while True: # skip premiere partie (apoL_a02_nom, ...) @@ -1052,14 +1052,14 @@ def _apo_read_cols(f): # sanity check col_id = fs[0] # apoL_c0001, ... if col_id in cols: - raise FormatError("duplicate column definition: %s" % col_id) + raise ScoFormatError("duplicate column definition: %s" % col_id) m = re.match(r"^apoL_c([0-9]{4})$", col_id) if not m: - raise FormatError( + raise ScoFormatError( "invalid column id: %s (expecting apoL_c%04d)" % (line, col_id) ) if int(m.group(1)) != i: - raise FormatError("invalid column id: %s for index %s" % (col_id, i)) + raise ScoFormatError("invalid column id: %s for index %s" % (col_id, i)) cols[col_id] = DictCol(list(zip(col_keys, fs))) cols[col_id].lineno = f.lineno # for debuging purpose @@ -1083,14 +1083,14 @@ def _apo_read_TITRES(f): else: log("Error read CSV: \nline=%s\nfields=%s" % (line, fields)) log(dir(f)) - raise FormatError( + raise ScoFormatError( "Fichier Apogee incorrect (section titres, %d champs au lieu de 2)" % len(fields) ) d[k] = v # if not d.get("apoC_Fichier_Exp", None): - raise FormatError("Fichier Apogee incorrect: pas de titre apoC_Fichier_Exp") + raise ScoFormatError("Fichier Apogee incorrect: pas de titre apoC_Fichier_Exp") # keep only basename: may be a windows or unix pathname s = d["apoC_Fichier_Exp"].split("/")[-1] s = s.split("\\")[-1] # for DOS paths, eg C:\TEMP\VL4RT_V3ASR.TXT diff --git a/app/scodoc/sco_exceptions.py b/app/scodoc/sco_exceptions.py index 1ae86e65..ddb7f674 100644 --- a/app/scodoc/sco_exceptions.py +++ b/app/scodoc/sco_exceptions.py @@ -56,7 +56,7 @@ class ScoValueError(ScoException): self.dest_url = dest_url -class FormatError(ScoValueError): +class ScoFormatError(ScoValueError): pass diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py index b5744cc3..81dede63 100644 --- a/app/scodoc/sco_formations.py +++ b/app/scodoc/sco_formations.py @@ -50,7 +50,7 @@ from app.scodoc import sco_tag_module from app.scodoc import sco_xml import sco_version from app.scodoc.gen_tables import GenTable -from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_exceptions import ScoValueError, ScoFormatError from app.scodoc.sco_permissions import Permission _formationEditor = ndb.EditableTable( @@ -184,9 +184,9 @@ def formation_import_xml(doc: str, import_tags=True): f = dom.getElementsByTagName("formation")[0] # or dom.documentElement D = sco_xml.xml_to_dicts(f) except: - raise ScoValueError( - "Le document xml ne correspond pas à un programme BUT. (élément 'formation' inexistant " - "par exemple)." + raise ScoFormatError( + """Ce document xml ne correspond pas à un programme exporté par ScoDoc. + (élément 'formation' inexistant par exemple).""" ) assert D[0] == "formation" F = D[1] diff --git a/app/scodoc/sco_import_etuds.py b/app/scodoc/sco_import_etuds.py index 657e3acc..786d8c44 100644 --- a/app/scodoc/sco_import_etuds.py +++ b/app/scodoc/sco_import_etuds.py @@ -47,7 +47,7 @@ from app.scodoc.sco_formsemestre_inscriptions import ( from app.scodoc.gen_tables import GenTable from app.scodoc.sco_exceptions import ( AccessDenied, - FormatError, + ScoFormatError, ScoException, ScoValueError, ScoInvalidDateError, @@ -640,7 +640,7 @@ def scolars_import_admission(datafile, formsemestre_id=None, type_admission=None if (idx_nom is None) or (idx_prenom is None): log("fields indices=" + ", ".join([str(x) for x in fields])) log("fields titles =" + ", ".join([fields[x][0] for x in fields])) - raise FormatError( + raise ScoFormatError( "scolars_import_admission: colonnes nom et prenom requises", dest_url=url_for( "scolar.form_students_import_infos_admissions", @@ -672,7 +672,7 @@ def scolars_import_admission(datafile, formsemestre_id=None, type_admission=None try: val = convertor(line[idx]) except ValueError: - raise FormatError( + raise ScoFormatError( 'scolars_import_admission: valeur invalide, ligne %d colonne %s: "%s"' % (nline, field_name, line[idx]), dest_url=url_for( @@ -758,7 +758,7 @@ def adm_get_fields(titles, formsemestre_id): convertor = adm_convert_text # doublons ? if k in [x[0] for x in fields.values()]: - raise FormatError( + raise ScoFormatError( 'scolars_import_admission: titre "%s" en double (ligne 1)' % (title), dest_url=url_for( diff --git a/app/views/refcomp.py b/app/views/refcomp.py index 0d32b8a0..7f0bdb8f 100644 --- a/app/views/refcomp.py +++ b/app/views/refcomp.py @@ -22,6 +22,7 @@ from app.models.formations import Formation from app.models.but_refcomp import ApcReferentielCompetences from app.but.import_refcomp import orebut_import_refcomp from app.but.forms.refcomp_forms import FormationRefCompForm, RefCompLoadForm +from app.scodoc.sco_exceptions import ScoFormatError from app.scodoc.sco_permissions import Permission from app.views import notes_bp as bp @@ -86,7 +87,16 @@ def refcomp_load(formation_id=None): if form.validate_on_submit(): f = form.upload.data filename = secure_filename(f.filename) - ref = orebut_import_refcomp(f, dept_id=g.scodoc_dept_id, orig_filename=filename) + try: + xml_data = f.read() + ref = orebut_import_refcomp( + xml_data, dept_id=g.scodoc_dept_id, orig_filename=filename + ) + except TypeError as exc: + raise ScoFormatError("fichier XML Orébut invalide") from exc + except ScoFormatError: + raise + if formation is not None: return redirect( url_for( diff --git a/tests/data/but-RT-refcomp-exemple.xml b/tests/data/but-RT-refcomp-exemple.xml new file mode 100644 index 00000000..40cd8ba3 --- /dev/null +++ b/tests/data/but-RT-refcomp-exemple.xml @@ -0,0 +1,544 @@ + + + + + + Conception et administration de l’infrastructure du réseau informatique d’une entreprise + Installation et administration des services réseau informatique d’une entreprise + Déploiement et administration des solutions fixes pour les clients d’un opérateur de télécommunication + + + en choisissant les solutions et technologies réseaux adaptées + en respectant les principes fondamentaux de la sécurité informatique + en utilisant une approche rigoureuse pour la résolution des dysfonctionnements + en respectant les règles métiers + en assurant une veille technologique + + + + + Maîtriser les lois fondamentales de l’électricité afin d’intervenir sur des équipements de réseaux et télécommunications + Comprendre l'architecture et les fondements des systèmes numériques, les principes du codage de l'information, des communications et de l'Internet + Configurer les fonctions de base du réseau local + Maîtriser les rôles et les principes fondamentaux des systèmes d’exploitation afin d’interagir avec ceux-ci pour la configuration et l'administration des réseaux et services fournis + Identifier les dysfonctionnements du réseau local et savoir les signaler + Installer un poste client, expliquer la procédure mise en place + + + + + Configurer et dépanner le routage dynamique dans un réseau + Configurer et expliquer une politique simple de QoS et les fonctions de base de la sécurité d’un réseau + Déployer des postes clients et des solutions virtualisées adaptées à une situation donnée + Déployer des services réseaux avancés + Identifier les réseaux opérateurs et l’architecture d’Internet + Travailler en équipe pour développer ses compétences professionnelles + + + + + Concevoir un projet de réseau informatique d’une entreprise en intégrant les problématiques de haute disponibilité, de QoS, de sécurité et de supervision + Réaliser la documentation technique de ce projet + Réaliser une maquette de démonstration du projet + Défendre/argumenter un projet + Communiquer avec les acteurs du projet + Gérer le projet et les différentes étapes de sa mise en œuvre en respectant les délais + + + + + + + Déploiement des supports et systèmes de transmission + Mise en service et administration des équipements d’accès fixe ou mobile d’un opérateur de télécommunications + Déploiement et administration des accès sans fil pour l'entreprise + Déploiement des systèmes de communications + + + en communiquant avec le client et les différents acteurs impliqués, parfois en anglais + en faisant preuve d’une démarche scientifique + en choisissant les solutions et technologies adaptées + en proposant des solutions respectueuses de l'environnement + + + + + Mesurer, analyser et commenter les signaux + Caractériser des systèmes de transmissions élémentaires et découvrir la modélisation mathématique de leur fonctionnement + Déployer des supports de transmission + Connecter les systèmes de ToIP + Communiquer avec un tiers (client, collaborateur...) et adapter son discours et sa langue à son interlocuteur + + + + + Déployer et caractériser des systèmes de transmissions complexes + Mettre en place un accès distant sécurisé + Mettre en place une connexion multi-site via un réseau opérateur + Déployer des réseaux d’accès des opérateurs + Capacité à questionner un cahier des charges RT + + + + + Déployer un système de communication pour l’entreprise + Déployer un réseau d’accès sans fil pour le réseau d’entreprise en intégrant les enjeux de la sécurité + Déployer un réseau d’accès fixe ou mobile pour un opérateur de télécommunications en intégrant la sécurité + Permettre aux collaborateurs de se connecter de manière sécurisée au système d’information de l’entreprise + Collaborer en mode projet en français et en anglais + + + + + + + Conception, déploiement et maintenance du système d’information d’une entreprise + Automatisation du déploiement et de la maintenance des outils logiciels + Développement d’outils informatiques à usage interne d'une équipe + + + en étant à l’écoute des besoins du client + en documentant le travail réalisé + en utilisant les outils numériques à bon escient + en choisissant les outils de développement adaptés + en intégrant les problématiques de sécurité + + + + + Utiliser un système informatique et ses outils + Lire, exécuter, corriger et modifier un programme + Traduire un algorithme, dans un langage et pour un environnement donné + Connaître l’architecture et les technologies d’un site Web + Choisir les mécanismes de gestion de données adaptés au développement de l’outil et argumenter ses choix + S’intégrer dans un environnement propice au développement et au travail collaboratif + + + + + Automatiser l’administration système avec des scripts + Développer une application à partir d’un cahier des charges donné, pour le Web ou les périphériques mobiles + Utiliser un protocole réseau pour programmer une application client/serveur + Installer, administrer un système de gestion de données + Accéder à un ensemble de données depuis une application et/ou un site web + + + + + Élaborer les spécifications techniques et le cahier des charges d’une application informatique + Mettre en place un environnement de travail collaboratif + Participer à la formation des utilisateurs + Déployer et maintenir une solution informatique + S’informer sur les évolutions et les nouveautés technologiques + Sécuriser l'environnement numérique d'une application + + + + + + + Analyse de l’existant et étude des besoins de sécurité d’une petite structure + Évolution et mise en conformité du système d’information d’une entreprise + + + en visant un juste compromis entre exigences de sécurité et contraintes d’utilisation + en respectant les normes et le cadre juridique + en intégrant les dernières technologies + en travaillant en équipe + en sensibilisant efficacement des utilisateurs + + + + + Connaître et utiliser les bonnes pratiques et les recommandations de cybersécurité + Mettre en œuvre les outils fondamentaux de sécurisation d’une infrastructure du réseau + Sécuriser les services + Choisir les outils cryptographiques adaptés au besoin fonctionnel du système d’information + Connaître les différents types d’attaque + Comprendre des documents techniques en anglais + + + + + Participer activement à une analyse de risque pour définir une politique de sécurité pour une petite structure + Mettre en œuvre des outils avancés de sécurisation d’une infrastructure du réseau + Sécuriser les systèmes d’exploitation + Proposer une architecture sécurisée de système d'information pour une petite structure + + + + + + + Industrialisation du déploiement des infrastructures systèmes, réseaux et sécurité en sauvegardant et en restaurant ses configurations + Maintenance des outils pour l’intégration et la mise en production du code logiciel + Administration d’un cluster de containers + Analyse des performances d’un système pour améliorer les processus de production + + + en respectant un cahier des charges + en documentant le travail réalisé + en intégrant les problématiques de sécurité + en assurant une veille technologique + en respectant les pratiques d’équipes et des méthodes de production + + + + + Proposer une solution Cloud adaptée à l’entreprise + Virtualiser un environnement + Utiliser les services du Cloud + Analyser un service Cloud au travers des métriques + + + + + Concevoir, administrer et superviser une infrastructure Cloud + Orchestrer les ressources Cloud + Investiguer sur les incidents et les résoudre afin d’améliorer la qualité et la fiabilité des infrastructures + + + + + + + Gestion des infrastructures d’un opérateur de réseaux mobiles et d’Internet des Objets + Gestion des infrastructures de réseaux mobiles dans le contexte industriel, personnel ou médical + + + en respectant les normes et protocoles en vigueur + en intégrant les dernières technologies mobiles + + + + + Comprendre les architectures et spécificités des réseaux dédiés à l'IoT + Mettre en œuvre des systèmes de transmissions pour l’accès à un réseau IoT + + + + + Comprendre les architectures, protocoles et services des réseaux mobiles 4G/5G + Choisir un réseau pour satisfaire les contraintes énergétiques et spectrales, en délai, en débit et en portée des objets connectés + Mettre en œuvre des réseaux mobiles personnels ou industriels + + + + + + + Adéquation technique des solutions réseaux informatiques et télécoms à la demande client + Élaboration de solutions techniques clients adaptées + Accompagnement technique de la mise en place des solutions clients + + + en maîtrisant les enjeux techniques et réglementaires des nouvelles technologies + en pilotant un projet technique R&T + en faisant preuve de vision stratégique en phase avec le marché des réseaux et des télécommunications + en collaborant de façon responsable avec des équipes + + + + + Compréhension d’un cahier des charges technique R&T + Planification des étapes d’un projet technique R&T + Co-animation d’une équipe technique + Proposition de solutions techniques R&T efficientes + Échanges vulgarisés ou techniques avec tous les acteurs d’un projet + + + + + Rédaction d'un appel d'offres ou d'un cahier des charges technique R&T + Animation technique d’équipes pluridisciplinaires + Coordination d’équipes sur une partie de projet R&T ou sa totalité + Mise en place de solutions techniques R&T efficientes + Livraison et suivi technique de projet R&T + + + + + + + Gestion des services d’un ensemble de clients entreprises d’un opérateur + Gestion du déploiement de nouvelles infrastructures + + + en respectant les règles métiers et les délais + en assurant une communication optimale avec le client + en mettant en place des processus opérationnels de gestion d’incidents + en pilotant les acteurs terrain + + + + + Administrer les réseaux d’accès fixes et mobiles + Virtualiser des services réseaux + Décrire/comprendre l’architecture et les offres des opérateurs + Gérer le routage/commutation et les interconnexions + Automatiser la gestion des équipements réseaux + + + + + Administrer/superviser les infrastructures et les services télécom + Administrer et déployer des fonctions réseaux virtualisées et programmer le réseau + + + + + + + Surveillance et analyse du système d’information + Audit de sécurité + Gestion d’un incident de sécurité + + + en assurant une veille permanente + en réalisant les mises à jour critiques + en automatisant des tâches + en s’intégrant dans une équipe + en surveillant le comportement du réseau + en veillant au respect des contrats et à la conformité des obligations du système d'information + + + + + Administrer les protections contre les logiciels malveillants + Prendre en main des outils de test de pénétration réseau/système + + + + + Surveiller l’activité du système d’information + Appliquer une méthodologie de tests de pénétration + Réagir face à un incident de sécurité + Administrer les outils de surveillance du système d’information + + + + + + + Déploiement d’une application + Intervention sur la chaîne de développement dans une optique DevOps + Surveillance de la qualité de la production + Mise en place des services réseaux nécessaires au développement + + + en respectant un cahier des charges + en documentant le travail réalisé + en respectant les bonnes pratiques de développement et de production + en visant l’amélioration continue + + + + + Développer un microservice + Mettre en production une application + Programmer son réseau par le code + + + + + Adopter les pratiques de pilotage de projet + Concevoir, gérer et sécuriser un environnement de microservices + Gérer son infrastructure comme du code + Gérer une chaîne d’intégration et/ou de déploiement continu + + + + + + + Déploiement d’un système IoT de la source capteur aux traitements des données + Gestion, administration et sécurisation d’un système IoT + + + en travaillant au sein d’une équipe pluridisciplinaire + en respectant les normes et contraintes opérationnelles + + + + + Intégrer des systèmes électroniques et des systèmes d’exploitation embarqués + Mettre en œuvre des protocoles pour les réseaux de l’IoT + Mettre en œuvre des applications et traiter des données issues des objets connectés + + + + + Superviser et analyser le déploiement des réseaux sans-fil + Sécuriser les objets connectés + Créer et innover pour l’IoT + + + + + + + Communication et stratégie technique en interne et en externe pour des projets R&T + Suivi des objectifs opérationnels de projets R&T + Pilotage de la relation client + + + en pilotant avec agilité des solutions techniques + en sachant communiquer à l’écrit et à l’oral avec tous les acteurs d’un projet + en respectant des contraintes technico-économiques (financières, éthiques, temporelles, contractuelles, qualité) + + + + + Prise en compte des contraintes d’un pilotage de projet R&T + Planification de solutions techniques R&T efficientes + Prise de conscience des enjeux de la communication dans les relations interpersonnelles + Établissement d’un relationnel de qualité + + + + + Rigueur dans le pilotage d’un projet R&T dans sa globalité + Flexibilité dans la gestion des équipes et des tâches + Prise de responsabilité envers les équipes + Valorisation de solutions déployées, ou d’offres techniques, ou d’offres commerciales + Force de propositions de solutions R&T innovantes responsables + + + + + + + Déploiement et administration des services de communication + Administration des services multimédia + + + en automatisant la gestion réseau des communications + en sécurisant les infrastructures + en gérant les interconnexions + en assurant une communication optimale avec le client + en respectant les règles métiers et les délais + + + + + Choisir une architecture et déployer des services de ToIP + Administrer un service de téléphonie pour l’entreprise + Mettre en place une politique de QoS pour les applications + + + + + Administrer les services multimédias pour une entreprise + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/unit/test_refcomp.py b/tests/unit/test_refcomp.py index 2b787607..34678e9f 100644 --- a/tests/unit/test_refcomp.py +++ b/tests/unit/test_refcomp.py @@ -8,6 +8,7 @@ import io from flask import g import app from app import db +from app import models from app.but.import_refcomp import orebut_import_refcomp from app.models.but_refcomp import ( ApcReferentielCompetences, @@ -15,39 +16,19 @@ from app.models.but_refcomp import ( ApcSituationPro, ) -ref_xml = """ - - - - - Conception et administration de l’infrastructure du réseau informatique d’une entreprise - Installation et administration des services réseau informatique d’une entreprise - - - - - - Tests unitaires d'une application. - - - - - - - - - -""" - def test_but_refcomp(test_client): """modèles ref. comp.""" - f = io.StringIO(ref_xml) - ref = orebut_import_refcomp(0, f) - assert ref.references.count() == 2 - assert ref.competences[0].situations.count() == 2 + xml_data = open("tests/data/but-RT-refcomp-exemple.xml").read() + dept_id = models.Departement.query.first().id + ref = orebut_import_refcomp(xml_data, dept_id) + assert ref.competences.count() == 13 + assert ref.competences[0].situations.count() == 3 assert ref.competences[0].situations[0].libelle.startswith("Conception ") + assert ( + ref.competences[-1].situations[-1].libelle + == "Administration des services multimédia" + ) # test cascades on delete db.session.delete(ref) db.session.commit()