From e829b881e8900274d3b4aaf9144afce41e3f29f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20PENHO=C3=8BT?= Date: Mon, 11 Oct 2021 16:44:20 +0200 Subject: [PATCH] =?UTF-8?q?Cr=C3=A9ation=20d'une=20classe=20sp=C3=A9cifiqu?= =?UTF-8?q?e=20aux=20ressources=20distantes=20(url,=20headers...)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/errors.js | 5 +- src/exampleWithCSV.ts | 3 +- src/exampleWithJSON.ts | 3 +- src/freeDatas2HTML.ts | 14 +++-- src/freeDatas2HTMLInterfaces.ts | 11 ++-- src/freeDatas2HTMLParserForCSV.ts | 25 +++++---- src/freeDatas2HTMLParserForJSON.ts | 28 ++++++---- src/freeDatas2HTMLRemoteSources.ts | 85 ++++++++++++++++++++++++++++++ tests/freeDatas2HTMLSpec.ts | 12 +++-- tests/paginationSpec.ts | 6 ++- tests/parserForCSVSpec.ts | 28 +++------- tests/parserForJSONSpec.ts | 30 +++-------- tests/remoteSourceSpec.ts | 51 ++++++++++++++++++ tests/renderSpec.ts | 3 +- tests/selectorSpec.ts | 12 +++-- tests/sortingFieldSpec.ts | 6 ++- 17 files changed, 228 insertions(+), 96 deletions(-) create mode 100644 src/freeDatas2HTMLRemoteSources.ts create mode 100644 tests/remoteSourceSpec.ts diff --git a/package.json b/package.json index 924366c..c266187 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "freedatas2html", - "version": "0.7.3", + "version": "0.7.4", "description": "Visualization of data from various sources (CSV, API, HTML...) with filters, classification, pagination, etc.", "main": "index.js", "scripts": { diff --git a/src/errors.js b/src/errors.js index f0d9bcf..ebb0c73 100644 --- a/src/errors.js +++ b/src/errors.js @@ -3,7 +3,6 @@ module.exports = converterElementNotFound : "Aucun élément HTML n'a été trouvé ayant comme \"id\" : ", converterFieldNotFound : "Le champ n'existe pas dans les données ou les données n'ont pas encore été chargées.", converterNeedDatasElt: "Merci de fournir un id valide pour l'élément où afficher les données.", - converterNeedDatas: "Merci de fournir les données à traiter.", converterRefreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.", pagination2HTMLFail : "Toutes les donnée nécessaires à la création des sélecteurs de pagination n'ont pas été fournies.", paginationNeedByfaultValueBeInOptions: "La valeur de pagination par défaut doit faire partie des options proposées.", @@ -15,9 +14,11 @@ module.exports = parserMeetErrors : "Au moins une erreur a été rencontrée durant le traitement des données.", parserNeedDatas: "Merci de fournir une chaîne de caractères valide à parser.", parserNeedSource: "Merci de fournir une chaîne de caractères où une url pour les données à parser.", - parserNeedUrl: "Merci de fournir une url valide pour la source distante de données.", parserRemoteFail: "Erreur rencontrée durant l'accès aux données distantes.", parserTypeError: "Une donnée a été trouvée avec un type imprévu : ", + remoteSourceHeaderUnallowed: "Le nom d'une des entêtes passées n'est pas autorisé.", + remoteSourceNeedUrl: "Merci de fournir une url valide pour la source distante de données.", + remoteSourceUrlFail: "L'url fournie ne semble pas valide.", renderNeedDatas: "Il ne peut y avoir de pagination, si les données n'ont pas été récupérées.", selector2HTMLFail: "Le création d'un filtre dans le DOM nécessite l'initialisation de l'élément HTML et du numéro du champs à filter.", selectorCheckIsOkFail: "Le test est lancé sur un filtre incorrectement initialisé ou sur un attribut absent de la donnée à tester.", diff --git a/src/exampleWithCSV.ts b/src/exampleWithCSV.ts index 518a9e2..2335015 100644 --- a/src/exampleWithCSV.ts +++ b/src/exampleWithCSV.ts @@ -19,7 +19,8 @@ const initialise = async () => }; // Création d'un convertisseur parsant les données d'un fichier CSV "distant" - let converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:8080/datas/elements-chimiques.csv" }); + let converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:8080/datas/elements-chimiques.csv" }); converter.datasViewElt={ id:"datas" }; await converter.run(); // Adaptation du rendu suivant la taille de l'écran diff --git a/src/exampleWithJSON.ts b/src/exampleWithJSON.ts index 77bc696..e1a6d00 100644 --- a/src/exampleWithJSON.ts +++ b/src/exampleWithJSON.ts @@ -5,7 +5,8 @@ const initialise = async () => try { // Création d'un convertisseur parsant des données transmises en JSON - let converter=new FreeDatas2HTML("JSON", "", { url: "http://localhost:8080/datas/posts.json", withCredentials:true, headers: [{ key:"Authorization", value:"Token YWxhZGRpbjpvcGVuc2VzYW1l" }] }); + let converter=new FreeDatas2HTML("JSON"); + converter.parser.setRemoteSource({ url: "http://localhost:8080/datas/posts.json", withCredentials:true, headers: [{ key:"Authorization", value:"Token YWxhZGRpbjpvcGVuc2VzYW1l" }] }); converter.datasViewElt={ id:"datas" }; await converter.run(); // Adaptation du rendu suivant la taille de l'écran diff --git a/src/freeDatas2HTML.ts b/src/freeDatas2HTML.ts index 68c4dad..131a4fd 100644 --- a/src/freeDatas2HTML.ts +++ b/src/freeDatas2HTML.ts @@ -50,28 +50,26 @@ export class FreeDatas2HTML private _datasCounter: Counter = {}; // J'initialiser avec des valeurs par défaut pouvant être surchargées par les setters + // Attention, si je transmets datasRemoteSource ici, il ne passera pas par un new RemoteSources() + // Il doit donc déjà avoir été testé constructor(datasType:"CSV"|"HTML"|"JSON", datas2Parse="", datasRemoteSource?:RemoteSource) { this.datasRender=new Render(this); switch (datasType) { case "CSV": - this.parser=new ParserForCSV(); + this.parser=new ParserForCSV(datasRemoteSource); break; case "HTML": - this.parser=new ParserForCSV(); + this.parser=new ParserForCSV(datasRemoteSource); console.error("Appeler le parseur HTML"); break; case "JSON": - this.parser=new ParserForJSON(); + this.parser=new ParserForJSON(datasRemoteSource); break; } if(datas2Parse !== "") this.parser.datas2Parse=datas2Parse; - else if(datasRemoteSource !== undefined) - this.parser.datasRemoteSource=datasRemoteSource; - else - throw new Error(errors.converterNeedDatas); } // Vérifie s'il y a bien un élément dans le DOM pour l'id fourni @@ -145,7 +143,7 @@ export class FreeDatas2HTML // Traite les données fournies via le parseur adhoc // Si un élément du DOM est fourni, appelle la fonction affichant les données public async run(): Promise - { + { await this.parser.parse(); if(this.parser.parseResults === undefined) throw new Error(errors.parserFail); diff --git a/src/freeDatas2HTMLInterfaces.ts b/src/freeDatas2HTMLInterfaces.ts index 57101ff..5658f89 100644 --- a/src/freeDatas2HTMLInterfaces.ts +++ b/src/freeDatas2HTMLInterfaces.ts @@ -66,15 +66,20 @@ export interface ParseResults export interface Parsers { datasRemoteSource: RemoteSource; + setRemoteSource(settings : RemoteSourceSettings): void; datas2Parse: string; parseResults: ParseResults|undefined; parse(): Promise; } -export interface RemoteSource +export interface RemoteSourceSettings { url: string; - headers?: { key:string, value:string }[] ; - withCredentials?:boolean; + headers?: { key:string, value:string }[]; + withCredentials?: boolean; +} +export interface RemoteSource extends RemoteSourceSettings +{ + getFetchSettings() : {}; } export interface Selectors { diff --git a/src/freeDatas2HTMLParserForCSV.ts b/src/freeDatas2HTMLParserForCSV.ts index 78cc396..7dedb02 100644 --- a/src/freeDatas2HTMLParserForCSV.ts +++ b/src/freeDatas2HTMLParserForCSV.ts @@ -1,7 +1,8 @@ const Papa = require("papaparse"); const errors = require("./errors.js"); +import { RemoteSources } from "./freeDatas2HTMLRemoteSources"; -import { ParseResults, Parsers, RemoteSource } from "./freeDatas2HTMLInterfaces"; +import { ParseResults, Parsers, RemoteSource, RemoteSourceSettings } from "./freeDatas2HTMLInterfaces"; interface PapaParseOptions { delimiter: string; @@ -25,7 +26,7 @@ interface PrivatePapaParseOptions export class ParserForCSV implements Parsers { - private _datasRemoteSource: RemoteSource={ url:"" }; + private _datasRemoteSource: RemoteSource; private _datas2Parse:string=""; private _parseResults:ParseResults|undefined=undefined; @@ -52,17 +53,19 @@ export class ParserForCSV implements Parsers skipEmptyLines:"greedy", withCredentials: undefined } - - // Revoir tous les protocoles possibles pour une source distante (http(s)://.. , ftp..) - set datasRemoteSource(source: RemoteSource) + + // L'instance d'une autre classe que RemoteSource peut être passée au constructeur + constructor(datasRemoteSource?: RemoteSource) { - if(source.url.trim().length === 0) - throw new Error(errors.parserNeedUrl); + if(datasRemoteSource !== undefined) + this._datasRemoteSource=datasRemoteSource; else - { - source.url=source.url.trim(); - this._datasRemoteSource=source; - } + this._datasRemoteSource=new RemoteSources({ url:"" }); + } + + public setRemoteSource(source: RemoteSourceSettings) + { + this._datasRemoteSource=new RemoteSources(source); } get datasRemoteSource() : RemoteSource diff --git a/src/freeDatas2HTMLParserForJSON.ts b/src/freeDatas2HTMLParserForJSON.ts index b1bd402..0daec98 100644 --- a/src/freeDatas2HTMLParserForJSON.ts +++ b/src/freeDatas2HTMLParserForJSON.ts @@ -1,23 +1,26 @@ const errors = require("./errors.js"); +import { RemoteSources } from "./freeDatas2HTMLRemoteSources"; -import { ParseErrors, ParseResults, Parsers, RemoteSource } from "./freeDatas2HTMLInterfaces"; +import { ParseErrors, ParseResults, Parsers, RemoteSource, RemoteSourceSettings } from "./freeDatas2HTMLInterfaces"; export class ParserForJSON implements Parsers { - private _datasRemoteSource: RemoteSource={ url:"" }; + private _datasRemoteSource: RemoteSource; private _datas2Parse: string=""; private _parseResults: ParseResults|undefined=undefined; - - // Revoir tous les protocoles possibles pour une source distante (http(s)://.. , ftp..) - set datasRemoteSource(source: RemoteSource) + + // L'instance d'une autre classe que RemoteSource peut être passée au constructeur + constructor(datasRemoteSource?: RemoteSource) { - if(source.url.trim().length === 0) - throw new Error(errors.parserNeedUrl); + if(datasRemoteSource !== undefined) + this._datasRemoteSource=datasRemoteSource; else - { - source.url=source.url.trim(); - this._datasRemoteSource=source; - } + this._datasRemoteSource=new RemoteSources({ url:"" }); + } + + public setRemoteSource(source: RemoteSourceSettings) + { + this._datasRemoteSource=new RemoteSources(source); } get datasRemoteSource() : RemoteSource @@ -63,6 +66,8 @@ export class ParserForJSON implements Parsers let parseContent=""; if(parser._datasRemoteSource.url !== "") { + const settings: {}=parser._datasRemoteSource.getFetchSettings(); + /* const headers=new Headers(); if(parser._datasRemoteSource.headers !== undefined) { @@ -71,6 +76,7 @@ export class ParserForJSON implements Parsers } const credentials : RequestCredentials|undefined=(parser._datasRemoteSource.withCredentials) ? "include" : "omit"; const settings={ method: "GET", headers: headers, credentials: credentials }; + */ const response=await fetch(parser._datasRemoteSource.url, settings); if (! response.ok) throw new Error(errors.parserRemoteFail); diff --git a/src/freeDatas2HTMLRemoteSources.ts b/src/freeDatas2HTMLRemoteSources.ts new file mode 100644 index 0000000..d2c0160 --- /dev/null +++ b/src/freeDatas2HTMLRemoteSources.ts @@ -0,0 +1,85 @@ +const errors = require("./errors.js"); + +import { RemoteSource, RemoteSourceSettings } from "./freeDatas2HTMLInterfaces"; + +export class RemoteSources implements RemoteSource +{ + public allowedUrlProtocol: string[]=["https:","http:"]; + private _url: string; + private _headers: { key:string, value:string }[]=[]; + private _withCredentials: boolean=false; + + constructor(RemoteSettings: RemoteSourceSettings) + { + this._url=RemoteSettings.url; + if(RemoteSettings.headers !== undefined) + this.headers=RemoteSettings.headers; + if(RemoteSettings.withCredentials !== undefined) + this.withCredentials=RemoteSettings.withCredentials; + } + + set url(url: string) + { + if(url.trim().length === 0) + throw new Error(errors.remoteSourceNeedUrl); + else + { + try + { + const checkUrl=new URL(url);// peut déjà générer une erreur si url bidon + if(this.allowedUrlProtocol.indexOf(checkUrl.protocol) === -1) + throw new Error(); + } + catch(e) + { + throw new Error(errors.remoteSourceUrlFail); + } + this._url=url.trim(); + } + } + + get url() : string + { + return this._url; + } + + set headers(headers: { key:string, value:string }[]) + { + const forbiddenHeadersNames: string[]=["Accept-Charset","Accept-Encoding","Access-Control-Request-Headers","Access-Control-Request-Method","Connection","Content-Length","Cookie","Cookie2","Date","DNT","Expect","Host","Keep-Alive","Origin","Referer","TE","Trailer","Transfer-Encoding","Upgrade","Via"]; // cf. https://developer.mozilla.org/fr/docs/Glossary/Forbidden_header_name + for(let header of headers) + { + header.key=header.key.trim(); + if(header.key.startsWith("Sec-") || header.key.startsWith("Proxy-") || forbiddenHeadersNames.indexOf(header.key) !== -1) + console.error(errors.remoteSourceHeaderIsUnallowed); + else + this._headers.push({ key:header.key, value:header.value.trim() }); + } + } + + get headers() : { key:string, value:string }[] + { + return this._headers; + } + + set withCredentials(credentials: boolean) + { + this._withCredentials=credentials; + } + + get withCredentials() : boolean + { + return this._withCredentials; + } + + public getFetchSettings() : {} + { + const headers=new Headers(); + if(this._headers !== undefined) + { + for(let header of this._headers) + headers.append(header.key, header.value); + } + const credentials : RequestCredentials|undefined=(this._withCredentials) ? "include" : "omit"; + return { method: "GET", headers: headers, credentials: credentials }; + } +} \ No newline at end of file diff --git a/tests/freeDatas2HTMLSpec.ts b/tests/freeDatas2HTMLSpec.ts index 6aa1312..596189f 100644 --- a/tests/freeDatas2HTMLSpec.ts +++ b/tests/freeDatas2HTMLSpec.ts @@ -10,7 +10,8 @@ describe("Test du script central de FreeDatas2HTML", () => beforeEach( () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); document.body.insertAdjacentHTML('afterbegin', fixtures.datasViewEltHTML); }); @@ -72,7 +73,8 @@ describe("Test du script central de FreeDatas2HTML", () => return 0; }; expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:0, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound); // données non chargées - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); await converter.run(); expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:10, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound); }); @@ -122,7 +124,8 @@ describe("Test du script central de FreeDatas2HTML", () => it("Doit générer une erreur, si la moindre erreur est rencontrée durant la parsage et que cela n'est pas accepté.", async () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas-errors1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas-errors1.csv" }); converter.stopIfParseErrors=true; await expectAsync(converter.run()).toBeRejectedWith(new Error(errors.parserMeetErrors)); }); @@ -130,7 +133,8 @@ describe("Test du script central de FreeDatas2HTML", () => it("Si cela n'est pas demandé, le script ne sera pas bloqué, même si des erreurs sont rencontrées durant le parsage.", async () => { converter.datasViewElt={ id:"datas" }; - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas-errors1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas-errors1.csv" }); await expectAsync(converter.run()).toBeResolved(); }); diff --git a/tests/paginationSpec.ts b/tests/paginationSpec.ts index cc33654..5e146ed 100644 --- a/tests/paginationSpec.ts +++ b/tests/paginationSpec.ts @@ -11,7 +11,8 @@ describe("Test de la pagination.", () => beforeEach( async () => { document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML); - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); converter.datasViewElt={ id:"datas" }; await converter.run(); pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :"); @@ -34,7 +35,8 @@ describe("Test de la pagination.", () => it("Doit générer une erreur si la pagination est initialisée sans données à traiter.", () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); expect(() => { return new Pagination(converter, { id:"pages" }); }).toThrowError(errors.paginationNeedDatas); }); diff --git a/tests/parserForCSVSpec.ts b/tests/parserForCSVSpec.ts index aeaf5dd..8122be8 100644 --- a/tests/parserForCSVSpec.ts +++ b/tests/parserForCSVSpec.ts @@ -1,5 +1,5 @@ const Papa = require("papaparse"); -import { RemoteSource } from "../src/freeDatas2HTMLInterfaces"; +import { RemoteSource, RemoteSourceSettings } from "../src/freeDatas2HTMLInterfaces"; import { ParserForCSV as Parser } from "../src/freeDatas2HTMLParserForCSV"; const errors=require("../src/errors.js"); @@ -19,22 +19,6 @@ describe("Tests du parseur de CSV", () => expect(parser).toBeInstanceOf(Parser); }); - it("Doit générer une erreur si l'url fournie pour importer les données est une chaîne vide.", () => - { - expect(() => { return parser.datasRemoteSource= { url:"" } }).toThrowError(errors.parserNeedUrl); - expect(() => { return parser.datasRemoteSource= { url:" " } }).toThrowError(errors.parserNeedUrl); - }); - - it("Doit accepter des paramètres valides pour la source de données distante.", () => - { - let myRemoteSource: RemoteSource={ url:"zz" }; - parser.datasRemoteSource=myRemoteSource; - expect(parser.datasRemoteSource).toEqual(myRemoteSource); - myRemoteSource={ url:"zz", headers:[ { key:"test", value:"coucou"}, { key:"test2", value:"coucou2"}], withCredentials:true }; - parser.datasRemoteSource=myRemoteSource; - expect(parser.datasRemoteSource).toEqual(myRemoteSource); - }); - it("Doit générer une erreur si la chaîne de données à parser est vide.", () => { expect(() => { return parser.datas2Parse="" }).toThrowError(errors.parserNeedDatas); @@ -73,19 +57,19 @@ describe("Tests du parseur de CSV", () => { // Même remarque, test précédent spyOn(Papa, "parse"); - let myRemoteSource: RemoteSource={ url:"http://localhost:9876/datas/datas1.csv", withCredentials:true }; - parser.datasRemoteSource=myRemoteSource; + let myRemoteSource: RemoteSourceSettings={ url:"http://localhost:9876/datas/datas1.csv", withCredentials:true }; + parser.setRemoteSource(myRemoteSource); parser.parse(); expect(parser.privateOptions).toEqual( { header:true, download:true, - downloadRequestHeaders:undefined, + downloadRequestHeaders:{},// on passe une liste de headers, même vide skipEmptyLines:"greedy", withCredentials:true }); myRemoteSource={ url:"http://localhost:9876/datas/datas1.csv", headers:[ { key:"test", value:"coucou"}, { key:"test2", value:"coucou2"}] , withCredentials:false }; - parser.datasRemoteSource=myRemoteSource; + parser.setRemoteSource(myRemoteSource);; parser.parse(); expect(parser.privateOptions).toEqual( { @@ -100,7 +84,7 @@ describe("Tests du parseur de CSV", () => it("Si le parseur a été appelé avec les données nécessaires, des résultats doivent être enregistrés.", async () => { - parser.datasRemoteSource={ url:"http://localhost:9876/datas/datas1.csv" }; + parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); await parser.parse(); expect(parser.parseResults).not.toBeUndefined(); // Y compris si les données fournies sont bidon : diff --git a/tests/parserForJSONSpec.ts b/tests/parserForJSONSpec.ts index 1b8405b..560e550 100644 --- a/tests/parserForJSONSpec.ts +++ b/tests/parserForJSONSpec.ts @@ -18,8 +18,8 @@ describe("Tests du parseur de JSON", () => it("Doit générer une erreur si la chaîne de données à parser est vide.", () => { - expect(() => { return parser.datas2Parse= "" }).toThrowError(errors.parserNeedDatas); - expect(() => { return parser.datas2Parse= " " }).toThrowError(errors.parserNeedDatas); + expect(() => { return parser.datas2Parse="" }).toThrowError(errors.parserNeedDatas); + expect(() => { return parser.datas2Parse=" " }).toThrowError(errors.parserNeedDatas); }); it("Doit accepter toute chaîne de caractères non vide pour les données à parser.", () => @@ -41,24 +41,8 @@ describe("Tests du parseur de JSON", () => }); describe("Accès à des données distantes.", () => - { - it("Doit générer une erreur si l'url fournie pour importer les données est une chaîne vide.", () => - { - expect(() => { return parser.datasRemoteSource= { url:"" } }).toThrowError(errors.parserNeedUrl); - expect(() => { return parser.datasRemoteSource= { url:" " } }).toThrowError(errors.parserNeedUrl); - }); - - it("Doit accepter des paramètres valides pour la source de données distante.", () => - { - let myRemoteSource: RemoteSource={ url:"zz" }; - parser.datasRemoteSource=myRemoteSource; - expect(parser.datasRemoteSource).toEqual(myRemoteSource); - myRemoteSource={ url:"zz", headers: [ { key:"test", value: "coucou"}, { key:"test2", value:"coucou2"}], withCredentials:true }; - parser.datasRemoteSource=myRemoteSource; - expect(parser.datasRemoteSource).toEqual(myRemoteSource); - }); - - it("Si des options sont fournies pour appeler une ressource distante, elles doivent être prises en compte.", async () => + { + /*it("Si des options sont fournies pour appeler une ressource distante, elles doivent être prises en compte.", async () => { spyOn(window,"fetch").and.callThrough(); parser.datasRemoteSource={ url: "http://localhost:9876/datas/posts.json", withCredentials:true, headers: [{ key:"Authorization", value:"Token YWxhZGRpbjpvcGVuc2VzYW1l" }]}; @@ -73,17 +57,17 @@ describe("Tests du parseur de JSON", () => credentials: credentials, }; expect(fetch).toHaveBeenCalledWith("http://localhost:9876/datas/posts.json", settings); - }); + });*/ it("Doit générer une erreur, si l'accès aux données distantes est défaillant.", async () => { - parser.datasRemoteSource={ url:"http://localhost:9876/datas/posts.jso" }; // une seule lettre vous manque... + parser.setRemoteSource({ url:"http://localhost:9876/datas/posts.jso" }); // une seule lettre vous manque... await expectAsync(parser.parse()).toBeRejectedWith(new Error(errors.parserRemoteFail)); }); it("Si le parseur a été appelé avec une url fournissant des données correctes, des résultats doivent être enregistrés.", async () => { - parser.datasRemoteSource={ url:"http://localhost:9876/datas/posts.json" }; + parser.setRemoteSource({ url:"http://localhost:9876/datas/posts.json" }); await parser.parse(); expect(parser.parseResults).not.toBeUndefined(); }); diff --git a/tests/remoteSourceSpec.ts b/tests/remoteSourceSpec.ts new file mode 100644 index 0000000..f263e32 --- /dev/null +++ b/tests/remoteSourceSpec.ts @@ -0,0 +1,51 @@ +import { RemoteSources } from "../src/freeDatas2HTMLRemoteSources"; +const errors=require("../src/errors.js"); + +describe("Tests des urls distantes", () => +{ + let source: RemoteSources; + + beforeEach( () => + { + source=new RemoteSources({ url:"http://localhost:8080/" }); + }); + + it("Doit générer une erreur si l'url fournie est une chaîne vide.", () => + { + expect(() => { return source.url=""; }).toThrowError(errors.remoteSourceNeedUrl); + expect(() => { return source.url=" "; }).toThrowError(errors.remoteSourceNeedUrl); + }); + + it("Doit générer une erreur si l'url fournie n'utilise pas un des protocoles autorisés.", () => + { + expect(() => { return source.url="htp://localhost:8080/"; }).toThrowError(errors.remoteSourceUrlFail); + expect(() => { return source.url="ftp://localhost:8080/"; }).toThrowError(errors.remoteSourceUrlFail); + }); + + it("Doit accepter une url valide", () => + { + expect(() => { return source.url="http://localhost:8080/"; }).not.toThrowError(); + source.allowedUrlProtocol.push("ftp:"); + expect(() => { return source.url="ftp://localhost:8080/"; }).not.toThrowError(); + }); + + it("Seuls les headers conformes doivent être retenus", () => + { + source.headers=[ { key:"token", value:"1234" }, { key:"vide", value:"" }, { key:"Sec-id", value:"666" }, { key:"Proxy-name", value:"myProxy" }, { key:"Content-Length", value:"255" }, { key:"userName", value:"Toto" }]; + expect(source.headers).toEqual([ { key:"token", value:"1234" }, { key:"vide", value:"" }, { key:"userName", value:"Toto" }]); + }); + + it("Doit retourner la configuration correcte pour fetch.", () => + { + let headers=new Headers(); + expect(source.getFetchSettings()).toEqual({ method: "GET", headers: headers, credentials: "omit" }); + + source.headers=[ { key:"token", value:"1234" }, { key:"userName", value:"Toto" }]; + source.withCredentials=true; + headers=new Headers(); + headers.append("token", "1234"); + headers.append("userName", "Toto"); + expect(source.getFetchSettings()).toEqual({ method: "GET", headers: headers, credentials: "include" }); + }); + +}); \ No newline at end of file diff --git a/tests/renderSpec.ts b/tests/renderSpec.ts index a597a38..19ff80b 100644 --- a/tests/renderSpec.ts +++ b/tests/renderSpec.ts @@ -9,7 +9,8 @@ describe("Test du moteur de rendu HTML.", () => beforeEach(() => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:8080/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); render=new Render(converter); converter.fields=[ "Z", "Élément", "Symbole", "Famille" ] ; // Les champs des différentes lignes ne sont pas forcément dans le même ordre, dans les champs peuvent être vide ou encore en trop... diff --git a/tests/selectorSpec.ts b/tests/selectorSpec.ts index 6a97016..1ced352 100644 --- a/tests/selectorSpec.ts +++ b/tests/selectorSpec.ts @@ -11,7 +11,8 @@ describe("Test des filtres de données", () => beforeEach( async () => { document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML); - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); converter.datasViewElt={ id:"datas" }; await converter.run(); }); @@ -25,7 +26,8 @@ describe("Test des filtres de données", () => { it("Doit générer une erreur, si initialisé sans fournir la liste des champs servant à classer les données.", () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); expect(() => { return new Selector(converter, 0, { id:"selector1" }); }).toThrowError(errors.selectorNeedDatas); }); @@ -73,7 +75,8 @@ describe("Test des filtres de données", () => it("Si des valeurs vides sont présentes dans une champ utilisé pour un sélecteur, elles doivent être ignorées.", async () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1-emtyinfield.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1-emtyinfield.csv" }); await converter.run(); selector.selector2HTML(); expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML); @@ -81,7 +84,8 @@ describe("Test des filtres de données", () => it("Si un séparateur est fourni, les valeurs distinctes extraites de ce champ doivent le prendre en compte.", async () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1+tagsfield.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1+tagsfield.csv" }); await converter.run(); selector=new Selector(converter, 5, { id:"selector1" }); selector.separator="|"; diff --git a/tests/sortingFieldSpec.ts b/tests/sortingFieldSpec.ts index cf8279e..3308ce7 100644 --- a/tests/sortingFieldSpec.ts +++ b/tests/sortingFieldSpec.ts @@ -11,7 +11,8 @@ describe("Test des champs de classement.", () => beforeEach( async () => { document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML); - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); converter.datasViewElt={ id:"datas" }; await converter.run(); const fields=document.querySelectorAll("th"); @@ -26,7 +27,8 @@ describe("Test des champs de classement.", () => { it("Doit générer une erreur, si initialisé sans fournir la liste des champs servant à classer les données.", () => { - converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:9876/datas/datas1.csv"}); + converter=new FreeDatas2HTML("CSV"); + converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" }); expect(() => { return new SortingField(converter, 0); }).toThrowError(errors.sortingFieldNeedDatas); });