From 646517651fdc418c6413139f8532046546c0022c Mon Sep 17 00:00:00 2001
From: Matheus Horstmann <mch15@inf.ufpr.br>
Date: Tue, 16 Apr 2019 11:43:42 -0300
Subject: [PATCH] Issue #18:  Add handler for testing

Signed-off-by: Matheus Horstmann <mch15@inf.ufpr.br>
---
 CHANGELOG.md                        | 13 +++++-
 package.json                        |  2 +-
 src/api/controllers/form.spec.ts    | 52 ++++++++-------------
 src/api/controllers/form.ts         |  8 ++--
 src/core/input.ts                   |  2 +-
 src/utils/dbHandler.spec.ts         | 44 ++++--------------
 src/utils/dbHandler.ts              |  8 ++--
 src/utils/testHandler.spec.ts       | 20 ++++++++
 src/utils/testHandler.ts            | 72 +++++++++++++++++++++++++++++
 src/utils/validationHandler.spec.ts |  4 +-
 src/utils/validationHandler.ts      |  8 ++--
 11 files changed, 145 insertions(+), 88 deletions(-)
 create mode 100644 src/utils/testHandler.spec.ts
 create mode 100644 src/utils/testHandler.ts

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 32709f6..3cf888f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## 0.0.10 - 16-04-2019
+### Added
+- TestHandler to test form and inputs #18 (Horstmann)
+### Changed
+- controller form tests to use testHandler #18 (Horstmann)
+- controller form to improve code coverage
+- dbHandler tests to use testHandler #18 (Horstmann)
+- ValidationType to has as arguments an array of strings
+- ValidationHandler to receive a string as size instead number as validation arguments
+- ValidationHandler to cast size to number
+- ValidationHandler tests to use string instead of number as validation arguments
 
 ## 0.0.9 - 10-04-2019
 ### Added
@@ -17,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Changed
 - main.ts to include dbHandler Middleware and remove dummie class
 ### Added
-- Create dbHandler Middleware to be abble to access by routes #15 (Horstmann)
+- Create dbHandler Middleware to be able to access by routes #15 (Horstmann)
 ## 0.0.6 - 01-04-2019
 ### Changed
 - Input class to match with database model (Add id and description) (Horstmann)
diff --git a/package.json b/package.json
index 023c0a0..7335b81 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "form-creator-api",
-  "version": "0.0.9",
+  "version": "0.0.10",
   "description": "RESTful API used to manage and answer forms.",
   "main": "index.js",
   "scripts": {
diff --git a/src/api/controllers/form.spec.ts b/src/api/controllers/form.spec.ts
index 7c5bc07..3cffe5a 100644
--- a/src/api/controllers/form.spec.ts
+++ b/src/api/controllers/form.spec.ts
@@ -22,7 +22,10 @@
  import * as request from "supertest";
  import { expect } from "chai";
  import * as server from "../../main";
- import { InputType, ValidationType } from "../../utils/enumHandler";
+ import { EnumHandler,InputType, ValidationType } from "../../utils/enumHandler";
+ import { TestHandler } from "../../utils/testHandler";
+ import { Form } from "../../core/form";
+ import { Input, Validation } from "../../core/input";
 
 
  describe("API data controller", () => {
@@ -57,41 +60,22 @@
                  .expect(200)
                  .expect((res: any) => {
                      expect(res.body).to.be.an("object");
-                     expect(res.body.id).to.be.equal(1);
-                     expect(res.body.title).to.be.equal("Form Title 1");
-                     expect(res.body.description).to.be.equal("Form Description 1");
-                     expect(res.body.inputs.length).to.be.equal(3);
-                     expect(res.body.inputs[0].id).to.be.equal(1);
-                     expect(res.body.inputs[0].placement).to.be.equal(0);
-                     expect(res.body.inputs[0].description).to.be.equal("Description Question 1 Form 1");
-                     expect(res.body.inputs[0].question).to.be.equal("Question 1 Form 1");
-                     expect(res.body.inputs[0].type).to.be.equal(InputType.TEXT);
-                     expect(res.body.inputs[0].validation.length).to.be.equal(0);
+                     const inputs: Input[] = [];
+                     for( let tmpInput of res.body.inputs ){
+                         let validation: Validation[] = [];
+                         for( let tmpValidation of tmpInput.validation ){
+                             validation.push({type: tmpValidation.type, arguments: tmpValidation.arguments})
+                         }
+                         inputs.push( new Input (tmpInput.placement, tmpInput.description, tmpInput.question, tmpInput.type, validation, tmpInput.id));
+                     }
+                     const form: Form = new Form(res.body.title, res.body.description, inputs, res.body.id);
 
-                     expect(res.body.inputs[1].id).to.be.equal(3);
-                     expect(res.body.inputs[1].placement).to.be.equal(1);
-                     expect(res.body.inputs[1].description).to.be.equal("Description Question 2 Form 1");
-                     expect(res.body.inputs[1].question).to.be.equal("Question 2 Form 1");
-                     expect(res.body.inputs[1].type).to.be.equal(InputType.TEXT);
-                     expect(res.body.inputs[1].validation.length).to.be.equal(2);
-                     expect(res.body.inputs[1].validation[0].type).to.be.equal(ValidationType.MAXCHAR);
-                     expect(res.body.inputs[1].validation[0].arguments.length).to.be.equal(1);
-                     expect(res.body.inputs[1].validation[0].arguments[0]).to.be.equal("10");
-                     expect(res.body.inputs[1].validation[1].type).to.be.equal(ValidationType.MINCHAR);
-                     expect(res.body.inputs[1].validation[1].arguments.length).to.be.equal(1);
-                     expect(res.body.inputs[1].validation[1].arguments[0]).to.be.equal("2");
+                     TestHandler.testForm(form, new Form("Form Title 1", "Form Description 1"
+                                        ,[ new Input (0, "Description Question 1 Form 1", "Question 1 Form 1", InputType.TEXT, [], 1)
+                                           ,new Input (1, "Description Question 2 Form 1", "Question 2 Form 1", InputType.TEXT, [{type: ValidationType.MAXCHAR, arguments: ["10"]}, {type: ValidationType.MINCHAR, arguments: ["2"]}], 3)
+                                           ,new Input (2, "Description Question 3 Form 1", "Question 3 Form 1", InputType.TEXT, [{type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"]}, {type: ValidationType.MANDATORY, arguments: []}], 2)]
+                                        , 1));
 
-                     expect(res.body.inputs[2].id).to.be.equal(2);
-                     expect(res.body.inputs[2].placement).to.be.equal(2);
-                     expect(res.body.inputs[2].description).to.be.equal("Description Question 3 Form 1");
-                     expect(res.body.inputs[2].question).to.be.equal("Question 3 Form 1");
-                     expect(res.body.inputs[2].type).to.be.equal(InputType.TEXT);
-                     expect(res.body.inputs[2].validation.length).to.be.equal(2);
-                     expect(res.body.inputs[2].validation[0].type).to.be.equal(ValidationType.REGEX);
-                     expect(res.body.inputs[2].validation[0].arguments.length).to.be.equal(1);
-                     expect(res.body.inputs[2].validation[0].arguments[0]).to.be.equal("\\d{5}-\\d{3}");
-                     expect(res.body.inputs[2].validation[1].type).to.be.equal(ValidationType.MANDATORY);
-                     expect(res.body.inputs[2].validation[1].arguments.length).to.be.equal(0);
                  })
                  .end(done);
         });
diff --git a/src/api/controllers/form.ts b/src/api/controllers/form.ts
index 4117dc6..21f5134 100644
--- a/src/api/controllers/form.ts
+++ b/src/api/controllers/form.ts
@@ -34,9 +34,7 @@ export class FormCtrl {
                     error: err
                 });
                 return;
-            }
-
-            if (forms) {
+            }else{
                 const mappedForms = forms.map(form => ({
                      id: form.id,
                      title: form.title,
@@ -45,6 +43,7 @@ export class FormCtrl {
                 res.json(mappedForms);
                 return;
             }
+
         });
 
     }
@@ -57,8 +56,7 @@ export class FormCtrl {
                     error: err
                 });
                 return;
-            }
-            if (form) {
+            }else{
                 res.json(form);
                 return;
             }
diff --git a/src/core/input.ts b/src/core/input.ts
index ec01a8b..7da8fdc 100644
--- a/src/core/input.ts
+++ b/src/core/input.ts
@@ -27,7 +27,7 @@ export interface Validation {
     /** Enum Validation Type to identify the type of current validation */
     type: ValidationType;
     /** Array of any, to store informations about validadtion */
-    arguments: any[];
+    arguments: string[];
 }
 
 /**
diff --git a/src/utils/dbHandler.spec.ts b/src/utils/dbHandler.spec.ts
index 588589a..be064ce 100644
--- a/src/utils/dbHandler.spec.ts
+++ b/src/utils/dbHandler.spec.ts
@@ -26,6 +26,7 @@ import { Input, Validation } from "../core/input";
 import { configs } from "./config";
 import { DbHandler } from "./dbHandler";
 import { InputType, ValidationType } from "./enumHandler";
+import { TestHandler } from "./testHandler";
 
 describe("Database Handler", () => {
     const dbhandler = new DbHandler(configs.poolconfig);
@@ -316,41 +317,12 @@ describe("Read and Write on Database", () => {
     it("should read an existent form", (done) => {
         dbhandler.readForm(1, (err: Error, form: Form) => {
             expect(err).to.be.a("null");
-            expect(form.id).to.be.equal(1);
-            expect(form.title).to.be.equal("Form Title 1");
-            expect(form.description).to.be.equal("Form Description 1");
-            expect(form.inputs.length).to.be.equal(3);
-            expect(form.inputs[0].id).to.be.equal(1);
-            expect(form.inputs[0].placement).to.be.equal(0);
-            expect(form.inputs[0].description).to.be.equal("Description Question 1 Form 1");
-            expect(form.inputs[0].question).to.be.equal("Question 1 Form 1");
-            expect(form.inputs[0].type).to.be.equal(InputType.TEXT);
-            expect(form.inputs[0].validation.length).to.be.equal(0);
-
-            expect(form.inputs[1].id).to.be.equal(3);
-            expect(form.inputs[1].placement).to.be.equal(1);
-            expect(form.inputs[1].description).to.be.equal("Description Question 2 Form 1");
-            expect(form.inputs[1].question).to.be.equal("Question 2 Form 1");
-            expect(form.inputs[1].type).to.be.equal(InputType.TEXT);
-            expect(form.inputs[1].validation.length).to.be.equal(2);
-            expect(form.inputs[1].validation[0].type).to.be.equal(ValidationType.MAXCHAR);
-            expect(form.inputs[1].validation[0].arguments.length).to.be.equal(1);
-            expect(form.inputs[1].validation[0].arguments[0]).to.be.equal("10");
-            expect(form.inputs[1].validation[1].type).to.be.equal(ValidationType.MINCHAR);
-            expect(form.inputs[1].validation[1].arguments.length).to.be.equal(1);
-            expect(form.inputs[1].validation[1].arguments[0]).to.be.equal("2");
-
-            expect(form.inputs[2].id).to.be.equal(2);
-            expect(form.inputs[2].placement).to.be.equal(2);
-            expect(form.inputs[2].description).to.be.equal("Description Question 3 Form 1");
-            expect(form.inputs[2].question).to.be.equal("Question 3 Form 1");
-            expect(form.inputs[2].type).to.be.equal(InputType.TEXT);
-            expect(form.inputs[2].validation.length).to.be.equal(2);
-            expect(form.inputs[2].validation[0].type).to.be.equal(ValidationType.REGEX);
-            expect(form.inputs[2].validation[0].arguments.length).to.be.equal(1);
-            expect(form.inputs[2].validation[0].arguments[0]).to.be.equal("\\d{5}-\\d{3}");
-            expect(form.inputs[2].validation[1].type).to.be.equal(ValidationType.MANDATORY);
-            expect(form.inputs[2].validation[1].arguments.length).to.be.equal(0);
+
+            TestHandler.testForm(form, new Form("Form Title 1", "Form Description 1"
+                                     , [ new Input (0, "Description Question 1 Form 1", "Question 1 Form 1", InputType.TEXT, [], 1)
+                                        , new Input (1, "Description Question 2 Form 1", "Question 2 Form 1", InputType.TEXT, [{type: ValidationType.MAXCHAR, arguments: ["10"]}, {type: ValidationType.MINCHAR, arguments: ["2"]}], 3)
+                                        , new Input (2, "Description Question 3 Form 1", "Question 3 Form 1", InputType.TEXT, [{type: ValidationType.REGEX, arguments: ["\\d{5}-\\d{3}"]}, {type: ValidationType.MANDATORY, arguments: []}], 2)]
+                                     , 1));
 
             done();
         });
@@ -372,7 +344,7 @@ describe("Read and Write on Database", () => {
         let input = new Input (1, "Description 1", "Question 1", InputType.TEXT, validation);
         const inputs: Input[] = [];
         inputs.push(input);
-        validation = [{type: ValidationType.MINCHAR, arguments: [5]}];
+        validation = [{type: ValidationType.MINCHAR, arguments: ["5"]}];
 
         input = new Input (2, "Description 2", "Question 2", InputType.TEXT, validation);
         inputs.push(input);
diff --git a/src/utils/dbHandler.ts b/src/utils/dbHandler.ts
index 9451b85..7fec6d0 100644
--- a/src/utils/dbHandler.ts
+++ b/src/utils/dbHandler.ts
@@ -207,7 +207,7 @@ export class DbHandler {
                     return;
                 }
 
-                const sortedInputs: Input[] = this.sortByPlacement(inputs);
+                const sortedInputs: Input[] = DbHandler.sortByPlacement(inputs);
 
                 cb(errors, sortedInputs);
             });
@@ -256,7 +256,7 @@ export class DbHandler {
 
         this.executeQuery(query, (error: Error, result?: QueryResult) => {
 
-            const sortedResult: any[] = this.sortByPlacement(result.rows);
+            const sortedResult: any[] = DbHandler.sortByPlacement(result.rows);
             const argumentArrayTmp = [];
             for (const innerResult of sortedResult){
                 argumentArrayTmp.push(innerResult["argument"]);
@@ -273,7 +273,7 @@ export class DbHandler {
      * @param array - Array with objects that have placement field
      * @returns - A sorted array by placement
      */
-    private sortByPlacement(array: any[]): any[] {
+    private static sortByPlacement(array: any[]): any[] {
 
         const sortedArray: any[] = array.sort((obj1, obj2) => {
             if (obj1["placement"] > obj2["placement"]) {
@@ -434,7 +434,7 @@ export class DbHandler {
      * @param cb - Callback function.
      * @param cb.err - Error information when the method fails.
      */
-     private writeValidationArgumentWithInputIdAndPlacement(validationId: number, argument: any, placement: number, cb: (err: Error) =>  void){
+     private writeValidationArgumentWithInputIdAndPlacement(validationId: number, argument: string, placement: number, cb: (err: Error) =>  void){
          const query: string = "INSERT INTO input_validation_argument \
                                 ( id_input_validation, argument, placement )\
                                 VALUES (  \'" + validationId + "\', \'" +
diff --git a/src/utils/testHandler.spec.ts b/src/utils/testHandler.spec.ts
new file mode 100644
index 0000000..e70e86c
--- /dev/null
+++ b/src/utils/testHandler.spec.ts
@@ -0,0 +1,20 @@
+/*
+ * form-creator-api. RESTful API to manage and answer forms.
+ * Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+ *
+ * This file is part of form-creator-api.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
diff --git a/src/utils/testHandler.ts b/src/utils/testHandler.ts
new file mode 100644
index 0000000..175c3cc
--- /dev/null
+++ b/src/utils/testHandler.ts
@@ -0,0 +1,72 @@
+/*
+ * form-creator-api. RESTful API to manage and answer forms.
+ * Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
+ * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+ *
+ * This file is part of form-creator-api.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+ import { expect } from "chai";
+ import { Form } from "../core/form";
+ import { Input, Validation } from "../core/input";
+ import { EnumHandler, InputType, ValidationType } from "./enumHandler";
+
+ /**
+  * Enum's handler. Manage parse through the project.
+  */
+ export class TestHandler {
+
+     /**
+      * Verify if two forms are semantically equal;
+      * @param form - Form that should be tested
+      * @param stub - A model form that first param itend to be.
+      * @returns - True if forms are equal else false
+      */
+    public static testForm(form: Form, stub: Form){
+        expect(form.id).to.be.equal(stub.id);
+        expect(form.title).to.be.equal(stub.title);
+        expect(form.description).to.be.equal(stub.description);
+        expect(form.inputs.length).to.be.equal(stub.inputs.length);
+        for (let i = 0; i < form.inputs.length ; i++){
+            TestHandler.testInput(form.inputs[i], stub.inputs[i]);
+        }
+
+    }
+
+    /**
+     * Verify if two inputs are semantically equal;
+     * @param input - Input that should be tested
+     * @param stub - A model input that first param itend to be.
+     * @returns - True if inputs are equal else false
+     */
+    public static testInput(input: Input, stub: Input){
+
+        expect(input.id).to.be.equal(stub.id);
+        expect(input.placement).to.be.equal(stub.placement);
+        expect(input.description).to.be.equal(stub.description);
+        expect(input.question).to.be.equal(stub.question);
+        expect(input.type).to.be.equal(stub.type);
+        expect(input.validation.length).to.be.equal(stub.validation.length);
+        for (let i = 0; i < input.validation.length ; i++){
+            expect(input.validation[i].type).to.be.equal(stub.validation[i].type);
+            expect(input.validation[i].arguments.length).to.be.equal(stub.validation[i].arguments.length);
+            for (let j = 0; j < input.validation[i].arguments.length  ; j++){
+                expect(input.validation[i].arguments[j]).to.be.equal(stub.validation[i].arguments[j]);
+            }
+        }
+    }
+
+ }
diff --git a/src/utils/validationHandler.spec.ts b/src/utils/validationHandler.spec.ts
index 2e0da2d..590a3ee 100644
--- a/src/utils/validationHandler.spec.ts
+++ b/src/utils/validationHandler.spec.ts
@@ -47,7 +47,7 @@ describe("Validation Handler", () => {
     });
 
     it("should test when Input has a minimum char number", () => {
-        const validation: Validation[] = [{type: ValidationType.MINCHAR, arguments: [5]}];
+        const validation: Validation[] = [{type: ValidationType.MINCHAR, arguments: ["5"]}];
         const input = new Input (1, "Description", "Question", InputType.TEXT, validation);
 
         expect(ValidationHandler.validateInput(input, "12345")).to.be.true;
@@ -58,7 +58,7 @@ describe("Validation Handler", () => {
         expect(ValidationHandler.validateInput(input, undefined)).to.be.false;
     });
     it("should test when Input has a maximum char number", () => {
-        const validation: Validation[] = [{type: ValidationType.MAXCHAR, arguments: [5]}];
+        const validation: Validation[] = [{type: ValidationType.MAXCHAR, arguments: ["5"]}];
         const input = new Input (1, "Description", "Question", InputType.TEXT, validation);
 
         expect(ValidationHandler.validateInput(input, "1234")).to.be.true;
diff --git a/src/utils/validationHandler.ts b/src/utils/validationHandler.ts
index c62db08..e2a9371 100644
--- a/src/utils/validationHandler.ts
+++ b/src/utils/validationHandler.ts
@@ -53,8 +53,8 @@ export class ValidationHandler {
      * @param size - Minimum size that answer should have.
      * @returns - true if has at least Size chars, else false.
      */
-    private static validateMinChar(answer: string, size: number): boolean{
-        return  (answer !== null && answer !== undefined && size <= answer.length);
+    private static validateMinChar(answer: string, size: string): boolean{
+        return  (answer !== null && answer !== undefined && parseInt(size, 10) <= answer.length);
     }
 
     /**
@@ -63,8 +63,8 @@ export class ValidationHandler {
      * @param size - Maximum size that answer should have.
      * @returns - true if has at max Size chars, else false.
      */
-    private static validateMaxChar(answer: string, size: number): boolean{
-        return  (answer !== null && answer !== undefined  && size >= answer.length);
+    private static validateMaxChar(answer: string, size: string): boolean{
+        return  (answer !== null && answer !== undefined  && parseInt(size, 10) >= answer.length);
     }
 
     /**
-- 
GitLab