-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui-src/src/app/configurations/configurations.component.spec.ts b/ui-src/src/app/configurations/configurations.component.spec.ts
index b484fcd..f4eff9d 100644
--- a/ui-src/src/app/configurations/configurations.component.spec.ts
+++ b/ui-src/src/app/configurations/configurations.component.spec.ts
@@ -3,8 +3,8 @@ import {ConfigurationsComponent} from "./configurations.component";
import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from "@angular/core";
import {ToastModule} from "ng2-toastr/ng2-toastr";
-import {AutomatedUIServices} from "../automated-ui-services";
-
+import {ConfigurationService} from "./configuration.service";
+import {TestSuiteService} from "../test-suites/test-suite.service";
import {HttpClientModule} from "@angular/common/http";
import {FormsModule} from "@angular/forms";
import {ToastsManager, ToastOptions} from "ng2-toastr/ng2-toastr";
@@ -20,7 +20,7 @@ describe("ConfigurationsComponent", () => {
beforeEach(
async(() => {
TestBed.configureTestingModule({
- providers: [AutomatedUIServices, ToastsManager, ToastOptions],
+ providers: [ConfigurationService, ToastsManager, ToastOptions, TestSuiteService],
declarations: [ConfigurationsComponent],
imports: [FormsModule, HttpClientModule, ToastModule.forRoot()],
schemas: [NO_ERRORS_SCHEMA,
@@ -31,7 +31,7 @@ describe("ConfigurationsComponent", () => {
component = fixture.componentInstance;
fixture.detectChanges();
- configurationService = TestBed.get(AutomatedUIServices);
+ configurationService = TestBed.get(ConfigurationService);
toastr = TestBed.get(ToastsManager);
}));
diff --git a/ui-src/src/app/configurations/configurations.component.ts b/ui-src/src/app/configurations/configurations.component.ts
index cc8ad23..404f16b 100644
--- a/ui-src/src/app/configurations/configurations.component.ts
+++ b/ui-src/src/app/configurations/configurations.component.ts
@@ -1,8 +1,9 @@
-import { Component, OnInit } from "@angular/core";
-import { HttpClient } from "@angular/common/http";
-import { AutomatedUIServices } from "../automated-ui-services";
-import { JsonSchemaFormModule } from "angular2-json-schema-form";
-import { ToastsManager } from "ng2-toastr/ng2-toastr";
+import {Component, OnInit} from "@angular/core";
+import {HttpClient} from "@angular/common/http";
+import {ConfigurationService} from "./configuration.service";
+import {TestSuiteService} from "../test-suites/test-suite.service";
+import {JsonSchemaFormModule} from "angular2-json-schema-form";
+import {ToastsManager} from "ng2-toastr/ng2-toastr";
import "rxjs/add/operator/map";
@Component({
@@ -12,21 +13,23 @@ import "rxjs/add/operator/map";
})
export class ConfigurationsComponent implements OnInit {
formData = {};
+ test = [];
+ test2 = [];
+ testArary = [];
configPath = undefined;
xmlFileName = undefined;
fileName = undefined;
- // needed for layout to load
- configSchema = { layout: true };
+ configSchema = {};
constructor(
- private automatedUIServices: AutomatedUIServices,
+ private configurationService: ConfigurationService,
+ private testSuiteService: TestSuiteService,
private toastr: ToastsManager,
-
private http: HttpClient
) {}
ngOnInit() {
- this.automatedUIServices
+ this.configurationService
.getSchema$("assets/schema.json")
.subscribe((data: any) => {
this.configSchema = data;
@@ -34,7 +37,7 @@ export class ConfigurationsComponent implements OnInit {
}
onSubmit(configData) {
- this.automatedUIServices.postConfig$(configData, this.configPath).subscribe(
+ this.configurationService.postConfig$(configData, this.configPath).subscribe(
data => {
this.toastr.success("Your data has been saved!", "Success!");
},
@@ -65,7 +68,7 @@ export class ConfigurationsComponent implements OnInit {
}
onCancel() {
- this.automatedUIServices
+ this.configurationService
.getConfig$(this.configPath, this.xmlFileName)
.subscribe(
data => {
@@ -80,13 +83,24 @@ export class ConfigurationsComponent implements OnInit {
);
}
+
fileSelector(event) {
this.fileName = event.srcElement.files[0].name;
this.xmlFileName = this.fileName;
+ this.xmlFileName = this.xmlFileName.substring(
+ 0,
+ this.xmlFileName.length - 4);
+
this.onGetFile();
+ (
document.getElementById("file")).value = "";
}
+
+ onClearFile() {
+ this.xmlFileName = undefined;
+ }
+
onGetFile() {
- this.automatedUIServices
+ this.configurationService
.getConfig$(this.configPath, this.xmlFileName)
.subscribe(
data => {
@@ -120,8 +134,9 @@ export class ConfigurationsComponent implements OnInit {
}
);
}
+
onUpdate(configData) {
- this.automatedUIServices
+ this.configurationService
.putConfig$(this.formData, this.configPath, this.xmlFileName)
.subscribe(
data => {
@@ -141,7 +156,7 @@ export class ConfigurationsComponent implements OnInit {
break;
}
case 500: {
- this.toastr.error("Internal server error!");
+ this.toastr.error("An error has occurred!", "Check the logs!");
break;
}
default: {
diff --git a/ui-src/src/app/shared/test-cases-list/test-cases-list.component.css b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.css
new file mode 100644
index 0000000..6ee5204
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.css
@@ -0,0 +1,5 @@
+td, th {
+ border: 1px solid #dddddd;
+ padding: 8px;
+ width: 100%;
+}
\ No newline at end of file
diff --git a/ui-src/src/app/shared/test-cases-list/test-cases-list.component.html b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.html
new file mode 100644
index 0000000..f24e860
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.html
@@ -0,0 +1,17 @@
+
+
+
+ | Description |
+ Pre-Think |
+ Post-Think |
+ Exec-Weight |
+
+
+ | {{testCase.description}} |
+ {{testCase.preThinkTime}} |
+ {{testCase.postThinkTime}} |
+ {{testCase.execWeight}} |
+
+
+
+
\ No newline at end of file
diff --git a/ui-src/src/app/shared/test-cases-list/test-cases-list.component.spec.ts b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.spec.ts
new file mode 100644
index 0000000..dac8ea6
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { TestCasesListComponent } from "./test-cases-list.component";
+
+describe("TestCasesListComponent", () => {
+ let component: TestCasesListComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TestCasesListComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TestCasesListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ui-src/src/app/shared/test-cases-list/test-cases-list.component.ts b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.ts
new file mode 100644
index 0000000..7027a80
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-list/test-cases-list.component.ts
@@ -0,0 +1,19 @@
+import {Component, Input, Output, EventEmitter} from "@angular/core";
+
+@Component({
+ selector: "app-test-cases-list",
+ templateUrl: "./test-cases-list.component.html",
+ styleUrls: ["./test-cases-list.component.css"]
+})
+export class TestCasesListComponent {
+ selectedTestCaseData = [];
+ @Input() testCases;
+ @Output() addToSelected = new EventEmitter();
+ @Output() reverse = new EventEmitter();
+
+ selectedCase(testCase, i) {
+ this.selectedTestCaseData = testCase;
+ this.addToSelected.emit(this.selectedTestCaseData);
+ this.reverse.emit(i);
+ }
+}
diff --git a/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.css b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.html b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.html
new file mode 100644
index 0000000..60b7d73
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.html
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.spec.ts b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.spec.ts
new file mode 100644
index 0000000..f0862ad
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.spec.ts
@@ -0,0 +1,31 @@
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
+import {TestCaseService} from "../../test-cases/test-case.service";
+import { TestCasesSelectionComponent } from "./test-cases-selection.component";
+import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from "@angular/core";
+import {HttpClientModule} from "@angular/common/http";
+
+describe("TestCasesSelectionComponent", () => {
+ let component: TestCasesSelectionComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ TestCasesSelectionComponent ],
+ providers: [TestCaseService],
+ imports: [HttpClientModule],
+ schemas: [NO_ERRORS_SCHEMA,
+ CUSTOM_ELEMENTS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TestCasesSelectionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.ts b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.ts
new file mode 100644
index 0000000..7d3d4e0
--- /dev/null
+++ b/ui-src/src/app/shared/test-cases-selection/test-cases-selection.component.ts
@@ -0,0 +1,25 @@
+import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
+import { TestCaseService } from "../../test-cases/test-case.service";
+
+@Component({
+ selector: "app-test-cases-selection",
+ templateUrl: "./test-cases-selection.component.html",
+ styleUrls: ["./test-cases-selection.component.css"]
+})
+export class TestCasesSelectionComponent implements OnInit {
+ @Input() testSuiteDirPath;
+ @Input() availableTestCases;
+ @Input() selectedTestCaseData = [];
+ @Output() addToSelected = new EventEmitter();
+ @Output() reverse = new EventEmitter();
+
+ constructor(private testCaseService: TestCaseService) {}
+
+ ngOnInit() {}
+ onReverse(selectedIndex) {
+ this.reverse.emit(selectedIndex);
+ }
+ onAddToSelected(testCase, selectedIndex) {
+ this.addToSelected.emit(testCase);
+ }
+}
diff --git a/ui-src/src/app/test-cases/test-case.service.spec.ts b/ui-src/src/app/test-cases/test-case.service.spec.ts
new file mode 100644
index 0000000..792c304
--- /dev/null
+++ b/ui-src/src/app/test-cases/test-case.service.spec.ts
@@ -0,0 +1,91 @@
+import {TestBed, inject, getTestBed} from "@angular/core/testing";
+import {HttpClientModule} from "@angular/common/http";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {environment} from "../../environments/environment";
+import {
+ HttpClientTestingModule,
+ HttpTestingController
+} from "@angular/common/http/testing";
+
+import { TestCaseService } from "./test-case.service";
+
+describe("TestCaseService", () => {
+ let injector;
+ let service;
+ let httpInterceptor: HttpTestingController;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientModule, HttpClientTestingModule],
+ providers: [TestCaseService]
+ });
+
+ injector = getTestBed();
+ service = injector.get(TestCaseService);
+ httpInterceptor = injector.get(HttpTestingController);
+ });
+
+ it("should be created", () => {
+ expect(service).toBeTruthy();
+ });
+
+ it("should make post test case request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.postTestCase$({data: "data1"}, "data2").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "data2");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-cases`);
+ expect(req.request.method).toBe("POST");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toEqual({data: "data1"});
+ req.flush({});
+ });
+
+ it("should make put test case request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.putTestCase$({data: "data1"}, "direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-cases/fileName.xml`);
+ expect(req.request.method).toBe("PUT");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toEqual({data: "data1"});
+ req.flush({});
+ });
+
+ it("should make get test case request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.getTestCase$("direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-cases/fileName.xml`);
+ expect(req.request.method).toBe("GET");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toBeNull();
+ req.flush({});
+ });
+
+ it("should make get all test case request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.getTestCases$("direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-cases`);
+ expect(req.request.method).toBe("GET");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toBeNull();
+ req.flush({});
+ });
+});
diff --git a/ui-src/src/app/test-cases/test-case.service.ts b/ui-src/src/app/test-cases/test-case.service.ts
new file mode 100644
index 0000000..53c6b0a
--- /dev/null
+++ b/ui-src/src/app/test-cases/test-case.service.ts
@@ -0,0 +1,44 @@
+import {Injectable} from "@angular/core";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {TestCasesComponent} from "./test-cases.component";
+import {Observable} from "rxjs/Observable";
+import { environment } from '../../environments/environment';
+
+@Injectable()
+export class TestCaseService {
+
+ private headers: HttpHeaders;
+ constructor(private http: HttpClient) {
+ this.headers = new HttpHeaders({"Content-Type": "application/json"});
+ }
+
+ getTestCases$(testCasePath): Observable {
+ this.headers = this.headers.set("path", testCasePath);
+ return this.http.get(`${environment.API_BASE_URL}test-cases`, {
+ headers: this.headers
+ });
+ }
+
+ postTestCase$(testCaseData, testCasePath): Observable {
+ this.headers = this.headers.set("path", testCasePath);
+ return this.http.post(`${environment.API_BASE_URL}test-cases`, testCaseData, {
+ headers: this.headers
+ });
+ }
+
+ getTestCase$(testCasePath, testCaseFileName): Observable {
+ this.headers = this.headers.set("path", testCasePath);
+ return this.http.get(`${environment.API_BASE_URL}test-cases/${testCaseFileName}`, {
+ headers: this.headers
+ });
+ }
+
+ putTestCase$(testCaseData, testCasePath, testCaseFileName): Observable {
+ this.headers = this.headers.set("path", testCasePath);
+ return this.http.put(
+ `${environment.API_BASE_URL}test-cases/${testCaseFileName}`,
+ testCaseData,
+ { headers: this.headers }
+ );
+ }
+}
diff --git a/ui-src/src/app/test-cases/test-cases.component.css b/ui-src/src/app/test-cases/test-cases.component.css
index 8b13789..95792d7 100644
--- a/ui-src/src/app/test-cases/test-cases.component.css
+++ b/ui-src/src/app/test-cases/test-cases.component.css
@@ -1 +1,69 @@
+.row {
+ margin-top: 25px;
+ margin-bottom: 25px;
+ }
+ .button-row { margin-top: 25px;}
+ .column {
+
+ padding: 0px;
+ }
+
+ table {
+
+ font-family: arial, sans-serif;
+ border-collapse: collapse;
+ width: 100%;
+ margin-bottom: 25px;
+
+}
+
+td, th {
+ border: 1px solid #dddddd;
+ text-align: left;
+ padding: 8px;
+}
+
+tr:nth-child(even) {
+ background-color: #dddddd;
+}
+
+.btn{
+ margin-bottom: 25px;
+}
+
+submit-widget{
+ display : none;
+}
+
+h1{
+ font-family: arial, sans-serif;
+ font-weight: bold;
+ margin-top: 0px;
+ font-size: 16px;
+ line-height: 1.42857143;
+ color: #333;
+}
+
+.load-button {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ margin-top: 18px;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 1px;
+}
diff --git a/ui-src/src/app/test-cases/test-cases.component.html b/ui-src/src/app/test-cases/test-cases.component.html
index ec92454..48014c9 100644
--- a/ui-src/src/app/test-cases/test-cases.component.html
+++ b/ui-src/src/app/test-cases/test-cases.component.html
@@ -1 +1,42 @@
-test-cases works
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Existing Test Cases
+
+
+
+
+ | Name |
+ Description |
+ Http Method |
+
+
+ | {{testCase.testname}} |
+ {{testCase.description}} |
+ {{testCase.httpMethod}} |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui-src/src/app/test-cases/test-cases.component.spec.ts b/ui-src/src/app/test-cases/test-cases.component.spec.ts
index 161be17..db68d9d 100644
--- a/ui-src/src/app/test-cases/test-cases.component.spec.ts
+++ b/ui-src/src/app/test-cases/test-cases.component.spec.ts
@@ -1,24 +1,39 @@
-import { async, ComponentFixture, TestBed } from "@angular/core/testing";
-
-import { TestCasesComponent } from "./test-cases.component";
+import {async, fakeAsync, ComponentFixture, TestBed} from "@angular/core/testing";
+import {TestCasesComponent} from "./test-cases.component";
+import {TestSuiteService} from "../test-suites/test-suite.service";
+import {ConfigurationService} from "../configurations/configuration.service";
+import {TestCaseService} from "../test-cases/test-case.service";
+import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from "@angular/core";
+import {ToastModule} from "ng2-toastr/ng2-toastr";
+import {HttpClientModule} from "@angular/common/http";
+import {FormsModule} from "@angular/forms";
+import {ToastsManager, ToastOptions} from "ng2-toastr/ng2-toastr";
+import {Observable} from "rxjs/Observable";
+import "rxjs/add/observable/of";
+import "rxjs/add/observable/throw";
describe("TestCasesComponent", () => {
let component: TestCasesComponent;
let fixture: ComponentFixture;
+ let testSuiteService, toastr;
beforeEach(
async(() => {
TestBed.configureTestingModule({
- declarations: [TestCasesComponent]
+ providers: [ConfigurationService, ToastsManager, ToastOptions, TestSuiteService, TestCaseService],
+ declarations: [TestCasesComponent],
+ imports: [FormsModule, HttpClientModule, ToastModule.forRoot()],
+ schemas: [NO_ERRORS_SCHEMA,
+ CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
- })
- );
- beforeEach(() => {
- fixture = TestBed.createComponent(TestCasesComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
+ fixture = TestBed.createComponent(TestCasesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ testSuiteService = TestBed.get(TestSuiteService);
+ toastr = TestBed.get(ToastsManager);
+ }));
it("should create", () => {
expect(component).toBeTruthy();
diff --git a/ui-src/src/app/test-cases/test-cases.component.ts b/ui-src/src/app/test-cases/test-cases.component.ts
index 977b195..919cb9d 100644
--- a/ui-src/src/app/test-cases/test-cases.component.ts
+++ b/ui-src/src/app/test-cases/test-cases.component.ts
@@ -1,8 +1,155 @@
import { Component, OnInit } from "@angular/core";
+import { ConfigurationService } from "../configurations/configuration.service";
+import { TestCaseService } from "./test-case.service";
+import { ToastsManager } from "ng2-toastr/ng2-toastr";
+import { JsonSchemaFormModule } from "angular2-json-schema-form";
+import { HttpClient } from "@angular/common/http";
+import "rxjs/add/operator/map";
@Component({
selector: "app-test-cases",
templateUrl: "./test-cases.component.html",
styleUrls: ["./test-cases.component.css"]
})
-export class TestCasesComponent {}
+export class TestCasesComponent implements OnInit {
+ testCaseData = {};
+ testCasePath = undefined;
+ testCaseSchema = { layout: true };
+ testCaseFileName = undefined;
+ testCases = [];
+
+
+ constructor(
+ private configurationService: ConfigurationService,
+ private testCaseService: TestCaseService,
+ private toastr: ToastsManager,
+ private http: HttpClient
+ ) { }
+
+ ngOnInit() {
+ this.configurationService
+ .getSchema$("assets/testCase_schema.json")
+ .subscribe((data: any) => {
+ this.testCaseSchema = data;
+ });
+ }
+
+ onLoad() {
+ this.testCaseService.getTestCases$(this.testCasePath).subscribe(
+ (data: any) => {
+ this.testCases = data;
+ this.toastr.success("Your Test Cases have loaded!", "Success!");
+ },
+ error => {
+ switch (error.status) {
+ case 500: {
+ this.toastr.error("An error has occurred!", "Check the logs!");
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "No Test Case Directory added",
+ "An error occurred!"
+ );
+ break;
+ }
+ default: {
+ this.toastr.error("An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+ onSelectCase(testCase, i) {
+ this.testCaseData = testCase;
+ this.testCaseFileName = testCase.testname;
+ }
+
+ onAdd() {
+ this.testCaseData = undefined;
+ this.testCaseFileName = undefined;
+ }
+
+ onDelete() { }
+
+ onSave(testCaseData) {
+ this.testCaseService.postTestCase$(testCaseData, this.testCasePath).subscribe(
+ data => {
+ this.toastr.success("Your data has been saved!", "Success!");
+ },
+
+ error => {
+ switch (error.status) {
+ case 500: {
+ this.toastr.error("An error has occurred!", "Check the logs!");
+ break;
+ }
+ case 409: {
+ this.toastr.error("File already exists!", "An error occurred!");
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "Some of the fields do not conform to the schema!",
+ "An error occurred!"
+ );
+ break;
+ }
+ default: {
+ this.toastr.error("Your data did not save!", "An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+
+ onUpdate(testCaseData) {
+ this.testCaseService
+ .putTestCase$(testCaseData, this.testCasePath, this.testCaseFileName)
+ .subscribe(
+ data => {
+ this.toastr.success("Success!");
+ this.onLoad();
+ },
+ error => {
+ switch (error.status) {
+ case 404: {
+ this.toastr.error("File not found", "An error occured!");
+
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "File must be specified!",
+ "An error occurred!"
+ );
+ break;
+ }
+ case 500: {
+ this.toastr.error("Internal server error!");
+ break;
+ }
+ default: {
+ this.toastr.error("File was not updated!", "An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+ onCancel() {
+ this.testCaseService
+ .getTestCase$(this.testCasePath, this.testCaseFileName)
+ .subscribe(
+ data => {
+ this.testCaseData = data;
+ this.toastr.success("Previous data reloaded!");
+ },
+ error => {
+ this.onAdd();
+ }
+ );
+ }
+}
diff --git a/ui-src/src/app/test-suites/test-suite.service.spec.ts b/ui-src/src/app/test-suites/test-suite.service.spec.ts
new file mode 100644
index 0000000..36e36a2
--- /dev/null
+++ b/ui-src/src/app/test-suites/test-suite.service.spec.ts
@@ -0,0 +1,91 @@
+import {TestBed, inject, getTestBed} from "@angular/core/testing";
+import {HttpClientModule} from "@angular/common/http";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {environment} from "../../environments/environment";
+import {
+ HttpClientTestingModule,
+ HttpTestingController
+} from "@angular/common/http/testing";
+
+import {TestSuiteService} from "./test-suite.service";
+
+describe("TestSuiteService", () => {
+ let injector;
+ let service;
+ let httpInterceptor: HttpTestingController;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientModule, HttpClientTestingModule],
+ providers: [TestSuiteService]
+ });
+
+ injector = getTestBed();
+ service = injector.get(TestSuiteService);
+ httpInterceptor = injector.get(HttpTestingController);
+ });
+
+ it("should be created", () => {
+ expect(service).toBeTruthy();
+ });
+
+ it("should make post test suite request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.postTestSuite$({data: "data1"}, "data2").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "data2");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-suites`);
+ expect(req.request.method).toBe("POST");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toEqual({data: "data1"});
+ req.flush({});
+ });
+
+ it("should make put test suite request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.putTestSuite$({data: "data1"}, "direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-suites/fileName.xml`);
+ expect(req.request.method).toBe("PUT");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toEqual({data: "data1"});
+ req.flush({});
+ });
+
+ it("should make get test suite request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.getTestSuite$("direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-suites/fileName.xml`);
+ expect(req.request.method).toBe("GET");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toBeNull();
+ req.flush({});
+ });
+
+ it("should make get all test suites request", () => {
+ // TODO add mock so it is no longer calling the real service
+ service.getTestSuites$("direct path", "fileName.xml").subscribe(() => {});
+
+ let headers = new HttpHeaders();
+ headers = headers.set("Content-Type", "application/json;");
+ headers = headers.append("configPathDir", "direct path");
+
+ const req = httpInterceptor.expectOne(`${environment.API_BASE_URL}test-suites`);
+ expect(req.request.method).toBe("GET");
+ expect(req.request.headers.getAll).toBe(headers.getAll);
+ expect(req.request.body).toBeNull();
+ req.flush({});
+ });
+});
diff --git a/ui-src/src/app/test-suites/test-suite.service.ts b/ui-src/src/app/test-suites/test-suite.service.ts
new file mode 100644
index 0000000..f13803d
--- /dev/null
+++ b/ui-src/src/app/test-suites/test-suite.service.ts
@@ -0,0 +1,44 @@
+import {Injectable} from "@angular/core";
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {TestSuitesComponent} from "./test-suites.component";
+import {Observable} from "rxjs/Observable";
+import {environment} from "../../environments/environment";
+
+@Injectable()
+export class TestSuiteService {
+
+ private headers: HttpHeaders;
+ constructor(private http: HttpClient) {
+ this.headers = new HttpHeaders({"Content-Type": "application/json"});
+ }
+
+ postTestSuite$(testSuiteData, testSuitePath): Observable {
+ this.headers = this.headers.set("path", testSuitePath);
+ return this.http.post(`${environment.API_BASE_URL}test-suites`, testSuiteData, {
+ headers: this.headers
+ });
+ }
+
+ getTestSuite$(testSuitePath, testSuiteFileName): Observable {
+ this.headers = this.headers.set("path", testSuitePath);
+ return this.http.get(`${environment.API_BASE_URL}test-suites/${testSuiteFileName}`, {
+ headers: this.headers
+ });
+ }
+
+ getTestSuites$(testSuitePath): Observable {
+ this.headers = this.headers.set("path", testSuitePath);
+ return this.http.get(`${environment.API_BASE_URL}test-suites`, {
+ headers: this.headers
+ });
+ }
+
+ putTestSuite$(testSuiteData, testSuitePath, testSuiteFileName): Observable {
+ this.headers = this.headers.set("path", testSuitePath);
+ return this.http.put(
+ `${environment.API_BASE_URL}test-suites/${testSuiteFileName}`,
+ testSuiteData,
+ {headers: this.headers}
+ );
+ }
+}
diff --git a/ui-src/src/app/test-suites/test-suites.component.css b/ui-src/src/app/test-suites/test-suites.component.css
index e69de29..d0c6fff 100644
--- a/ui-src/src/app/test-suites/test-suites.component.css
+++ b/ui-src/src/app/test-suites/test-suites.component.css
@@ -0,0 +1,40 @@
+.row {
+ margin-top: 25px;
+ margin-bottom: 25px;
+ padding: 10px;
+}
+.button-row {
+ margin-top: 25px;
+}
+.column {
+ padding: 0px;
+}
+
+table {
+ font-family: arial, sans-serif;
+ border-collapse: collapse;
+ width: 90%;
+ margin-bottom: 25px;
+ padding-right: 5px;
+}
+
+td,
+th {
+ border: 1px solid #dddddd;
+ text-align: left;
+ padding: 8px;
+}
+
+tr:nth-child(even) {
+ background-color: #dddddd;
+}
+
+.btn {
+ margin-bottom: 25px;
+}
+fieldset {
+ display: none;
+}
+submit-widget {
+ display: none;
+}
diff --git a/ui-src/src/app/test-suites/test-suites.component.html b/ui-src/src/app/test-suites/test-suites.component.html
index 8f39c17..b491270 100644
--- a/ui-src/src/app/test-suites/test-suites.component.html
+++ b/ui-src/src/app/test-suites/test-suites.component.html
@@ -1 +1,38 @@
-test-suite works
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+ | Name |
+ Description |
+
+
+ | {{testSuite.name}} |
+ {{testSuite.description}} |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui-src/src/app/test-suites/test-suites.component.spec.ts b/ui-src/src/app/test-suites/test-suites.component.spec.ts
index a7d333c..14aaeba 100644
--- a/ui-src/src/app/test-suites/test-suites.component.spec.ts
+++ b/ui-src/src/app/test-suites/test-suites.component.spec.ts
@@ -1,24 +1,39 @@
-import { async, ComponentFixture, TestBed } from "@angular/core/testing";
-
-import { TestSuitesComponent } from "./test-suites.component";
+import {async, fakeAsync, ComponentFixture, TestBed} from "@angular/core/testing";
+import {TestSuitesComponent} from "./test-suites.component";
+import {TestSuiteService} from "./test-suite.service";
+import {ConfigurationService} from "../configurations/configuration.service";
+import {TestCaseService} from "../test-cases/test-case.service";
+import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from "@angular/core";
+import {ToastModule} from "ng2-toastr/ng2-toastr";
+import {HttpClientModule} from "@angular/common/http";
+import {FormsModule} from "@angular/forms";
+import {ToastsManager, ToastOptions} from "ng2-toastr/ng2-toastr";
+import {Observable} from "rxjs/Observable";
+import "rxjs/add/observable/of";
+import "rxjs/add/observable/throw";
describe("TestSuitesComponent", () => {
let component: TestSuitesComponent;
let fixture: ComponentFixture
;
+ let testSuiteService, toastr;
beforeEach(
async(() => {
TestBed.configureTestingModule({
- declarations: [TestSuitesComponent]
+ providers: [ConfigurationService, ToastsManager, ToastOptions, TestSuiteService, TestCaseService],
+ declarations: [TestSuitesComponent],
+ imports: [FormsModule, HttpClientModule, ToastModule.forRoot()],
+ schemas: [NO_ERRORS_SCHEMA,
+ CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
- })
- );
- beforeEach(() => {
- fixture = TestBed.createComponent(TestSuitesComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
+ fixture = TestBed.createComponent(TestSuitesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+
+ testSuiteService = TestBed.get(TestSuiteService);
+ toastr = TestBed.get(ToastsManager);
+ }));
it("should create", () => {
expect(component).toBeTruthy();
diff --git a/ui-src/src/app/test-suites/test-suites.component.ts b/ui-src/src/app/test-suites/test-suites.component.ts
index 5e5db2f..73bff17 100644
--- a/ui-src/src/app/test-suites/test-suites.component.ts
+++ b/ui-src/src/app/test-suites/test-suites.component.ts
@@ -1,8 +1,166 @@
-import { Component, OnInit } from "@angular/core";
-
+import {Component, OnInit, Input, Output, EventEmitter} from "@angular/core";
+import {TestSuiteService} from "./test-suite.service";
+import {TestCaseService} from "../test-cases/test-case.service";
+import {ConfigurationService} from "../configurations/configuration.service";
+import {ToastsManager} from "ng2-toastr/ng2-toastr";
+import {TestCasesSelectionComponent} from "../shared/test-cases-selection/test-cases-selection.component";
@Component({
selector: "app-test-suites",
templateUrl: "./test-suites.component.html",
styleUrls: ["./test-suites.component.css"]
})
-export class TestSuitesComponent {}
+export class TestSuitesComponent implements OnInit {
+ testSuitePath = undefined;
+ testCaseArray = [];
+ testSuites = [];
+ selectedTestCaseData = [];
+ testSuiteData = {};
+ testCases = [];
+ testSuiteFileName = undefined;
+ testSuiteFileNameTruncated = undefined;
+ testSuiteSchema = {layout: true};
+
+ constructor(
+ private testSuiteService: TestSuiteService,
+ private testCaseService: TestCaseService,
+ private configurationService: ConfigurationService,
+ private toastr: ToastsManager
+ ) {}
+
+ ngOnInit() {
+ this.configurationService
+ .getSchema$("assets/testSuite_schema.json")
+ .subscribe((data: any) => {
+ this.testSuiteSchema = data;
+ });
+ }
+
+ onAdd() {
+ this.testSuiteService.getTestSuites$(this.testSuitePath).subscribe(
+ data => {
+ this.testSuites = data;
+ },
+
+ error => {
+ switch (error.status) {
+ case 500: {
+ this.toastr.error("An error has occurred!", "Check the logs!");
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "No Test Suite Directory added",
+ "An error occurred!"
+ );
+ break;
+ }
+ default: {
+ this.toastr.error("An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+ getTestCases() {
+ this.testCaseService
+ .getTestCases$(this.testSuitePath)
+ .subscribe((data: any) => (this.testCases = data));
+ }
+
+ onCancel() {
+ this.toastr.success("Your data has been cleared", "Success!");
+ this.testSuiteData = undefined;
+ this.selectedTestCaseData = [];
+ this.testSuiteFileName = undefined;
+ this.onAdd();
+ }
+
+ truncateFileName() {
+ if (this.testSuiteFileName) {
+ this.testSuiteFileNameTruncated = this.testSuiteFileName.substring(
+ 0,
+ this.testSuiteFileName.length - 4
+ );
+ }
+ }
+
+ onUpdate(formData) {
+ this.truncateFileName();
+ this.testCaseArray["testCases"] = this.selectedTestCaseData;
+ Object.assign(formData, this.testCaseArray);
+ this.testSuiteService
+ .putTestSuite$(formData, this.testSuitePath, this.testSuiteFileNameTruncated)
+ .subscribe(
+ data => {
+ this.toastr.success("Success!");
+ this.onAdd();
+ },
+ error => {
+ switch (error.status) {
+ case 404: {
+ this.toastr.error("File not found", "An error occured!");
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "File must be specified!",
+ "An error occurred!"
+ );
+ break;
+ }
+ case 500: {
+ this.toastr.error("Internal server error!");
+ break;
+ }
+ default: {
+ this.toastr.error("File was not updated!", "An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+ onSave(formData) {
+ this.testCaseArray["testCases"] = this.selectedTestCaseData;
+ Object.assign(formData, this.testCaseArray);
+ this.testSuiteService.postTestSuite$(formData, this.testSuitePath).subscribe(
+ data => {
+ this.toastr.success("Your data has been saved!", "Success!");
+ this.onAdd();
+ },
+ error => {
+ switch (error.status) {
+ case 500: {
+ this.toastr.error("An error has occurred!", "Check the logs!");
+ break;
+ }
+ case 400: {
+ this.toastr.error(
+ "Some of the fields do not conform to the schema!",
+ "An error occurred!"
+ );
+ break;
+ }
+ default: {
+ this.toastr.error("Your data did not save!", "An error occurred!");
+ }
+ }
+ }
+ );
+ }
+
+ onSelectSuite(testSuite, selectedIndex) {
+ this.onAdd();
+ this.testSuiteData = testSuite;
+ this.selectedTestCaseData = testSuite.testCases;
+ this.testSuiteFileName = testSuite.file;
+ }
+ updateSelected(testCase) {
+ this.selectedTestCaseData.push(testCase);
+
+ }
+ onReverse(selectedIndex) {
+ this.selectedTestCaseData.splice(selectedIndex, 1);
+ }
+}
diff --git a/ui-src/src/assets/schema.json b/ui-src/src/assets/schema.json
index 50ec856..1109f1c 100644
--- a/ui-src/src/assets/schema.json
+++ b/ui-src/src/assets/schema.json
@@ -18,17 +18,30 @@
"baseStatsOutputDir",
"reportOutputDir"
],
+ "additionalProperties": false,
"properties": {
- "apiName": { "type": "string" },
- "targetHost": { "type": "string" },
+ "apiName": {
+ "type": "string"
+ },
+ "targetHost": {
+ "type": "string"
+ },
"targetPort": {
"type": "string",
"minimum": 1,
"maximum": 65535
},
- "memoryEndpoint": { "type": "string" },
- "numIterations": { "type": "integer", "minimum": 1 },
- "concurrentUsers": { "type": "integer", "minimum": 1 },
+ "memoryEndpoint": {
+ "type": "string"
+ },
+ "numIterations": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "concurrentUsers": {
+ "type": "integer",
+ "minimum": 1
+ },
"allowablePeakMemoryVariance": {
"type": "number",
"minimum": 0,
@@ -41,24 +54,54 @@
},
"testSuite": {
"type": "string",
- "enum": ["Default-1", "Default-2", "Default-3"]
- },
- "requestDelay": { "type": "integer", "minimum": 1 },
- "TPSFreq": { "type": "integer", "minimum": 1 },
- "rampUsers": { "type": "integer", "minimum": 1 },
- "rampDelay": { "type": "integer", "minimum": 0 },
- "testCaseDir": { "type": "string" },
- "testSuiteDir": { "type": "string" },
- "baseStatsOutputDir": { "type": "string" },
- "reportOutputDir": { "type": "string" }
+ "enum": [
+ "Default-1",
+ "Default-2",
+ "Default-3"
+ ]
+ },
+ "requestDelay": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "TPSFreq": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "rampUsers": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "rampDelay": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "testCaseDir": {
+ "type": "string"
+ },
+ "testSuiteDir": {
+ "type": "string"
+ },
+ "baseStatsOutputDir": {
+ "type": "string"
+ },
+ "reportOutputDir": {
+ "type": "string"
+ }
},
- "layout" : [
+ "layout": [
{
"type": "flex",
"flex-flow": "row wrap",
"items": [
"apiName",
+ {
+ "md": 4
+ },
"numIterations",
+ {
+ "md": 4
+ },
{
"key": "requestDelay",
"title": "Request Delay (ms)"
@@ -70,7 +113,13 @@
"flex-flow": "row wrap",
"items": [
"targetHost",
+ {
+ "md": 4
+ },
"concurrentUsers",
+ {
+ "md": 4
+ },
{
"key": "TPSFreq",
"title": "TPS Frequency (s)"
@@ -82,10 +131,16 @@
"flex-flow": "row wrap",
"items": [
"targetPort",
+ {
+ "md": 4
+ },
{
"key": "allowablePeakMemoryVariance",
"title": "Memory Variance (%)"
},
+ {
+ "md": 4
+ },
"rampUsers"
]
},
@@ -94,21 +149,43 @@
"flex-flow": "row wrap",
"items": [
"memoryEndpoint",
+ {
+ "md": 4
+ },
{
"key": "allowableServiceResponseTimeVariance",
"title": "Service Variance (%)"
},
+ {
+ "md": 4
+ },
{
"key": "rampDelay",
"title": "Ramp Delay (s)"
}
]
},
- { "key": "testSuite" },
- { "key": "testCaseDir", "title": "Test Case Directory" },
- { "key": "testSuiteDir", "title": "Test Suites Directory" },
- { "key": "baseStatsOutputDir", "title": "Base Stats Output Directory" },
- { "key": "reportOutputDir", "title": "Report Output Directory" }
-
+ {
+ "key": "testSuite"
+ },
+ {
+ "key": "testCaseDir",
+ "title": "Test Case Directory"
+ },
+ {
+ "key": "testSuiteDir",
+ "title": "Test Suites Directory"
+ },
+ {
+ "key": "baseStatsOutputDir",
+ "title": "Base Stats Output Directory"
+ },
+ {
+ "key": "reportOutputDir",
+ "title": "Report Output Directory"
+ }
]
-}
\ No newline at end of file
+}
+
+
+
diff --git a/ui-src/src/assets/testCase_schema.json b/ui-src/src/assets/testCase_schema.json
index 401a5f0..2b8da10 100644
--- a/ui-src/src/assets/testCase_schema.json
+++ b/ui-src/src/assets/testCase_schema.json
@@ -4,50 +4,69 @@
"testname",
"overridePort",
"overrideHost",
- "HttpMethod",
- "BaseURI",
+ "httpMethod",
+ "baseUri",
"multipart",
+ "multipartPayload",
"payload",
"responseStatusCode",
"responseContentType",
"preThinkTime",
"postThinkTime",
"execWeight",
- "Headers",
- "ResponseValues",
- "MultipartPayload"
+ "headers",
+ "responseValues"
],
+ "additionalProperties": false,
"properties": {
- "overridePort": {
- "type": "string"
- },
"testname": {
"type": "string"
},
"description": {
"type": "string"
},
- "overrideHost": {
+ "baseUri": {
"type": "string"
},
- "HttpMethod": {
- "type": "string",
- "enum": ["POST","GET","PUT","DELETE"]
- },
- "BaseURI": {
+ "overrideHost": {
"type": "string"
},
"multipart": {
"type": "boolean"
},
+ "overridePort": {
+ "type": "string"
+ },
"payload": {
"type": "string"
},
- "responseStatusCode": {
- "type": "number"
+ "httpMethod": {
+ "type": "string",
+ "enum": [
+ "POST",
+ "GET",
+ "PUT",
+ "DELETE"
+ ]
},
- "responseContentType": {
- "type": "string"
+ "headers": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "key",
+ "value"
+ ],
+ "properties": {
+ "key": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ }
+ }
},
"preThinkTime": {
"type": "number"
@@ -57,56 +76,52 @@
},
"execWeight": {
"type": "string",
- "enum": ["Sparse","Infrequent"]
+ "enum": [
+ "Sparse",
+ "Infrequent"
+ ]
+ },
+ "responseStatusCode": {
+ "type": "number"
+ },
+ "responseContentType": {
+ "type": "string"
},
- "Headers": {
+ "multipartPayload": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
- "required": ["Key", "Value"],
"properties": {
- "Key": {
+ "fieldName": {
"type": "string"
},
- "Value": {
+ "fieldValue":{
+ "type": "string"
+ },
+ "fileName": {
"type": "string"
}
}
}
},
- "ResponseValues": {
+ "responseValues": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
- "required": ["Value", "ExtractionKey"],
+ "required": [
+ "value",
+ "extractionKey"
+ ],
"properties": {
- "Value": {
+ "extractionKey": {
"type": "string"
},
- "ExtractionKey": {
+ "value": {
"type": "string"
}
}
- },
- "MultipartPayload": {
- "type": "array",
- "items": {
- "type": "object",
- "required": ["FieldName", "FieldValue","FileName", "FileContent"],
- "properties": {
- "fieldName": {
- "type": "string"
- },
- "FieldValue": {
- "type": "string"
- },
- "FileName": {
- "type": "string"
- }
- }
- }
}
}
}
diff --git a/ui-src/src/assets/testSuite_schema.json b/ui-src/src/assets/testSuite_schema.json
index 745e1a3..28274d9 100644
--- a/ui-src/src/assets/testSuite_schema.json
+++ b/ui-src/src/assets/testSuite_schema.json
@@ -15,28 +15,30 @@
},
"testCases": {
"type": "array",
- "items": {
+ "testCases": {
"type": "object",
"additionalProperties": false,
- "required": ["name"],
+ "required": [
+ "name",
+ "preThinkTime",
+ "postThinkTime",
+ "execWeight"
+ ],
"properties": {
- "preThinkTime": {
- "type": "integer",
- "minimum": 0
- },
- "postThinkTime": {
- "type": "integer",
- "minimum": 0
- },
- "execWeight": {
- "type": "string",
- "enum": ["Infrequent", "Sparse"]
+ "key": {
+ "type": "string"
},
- "name": {
+ "value": {
"type": "string"
}
}
}
}
- }
-}
+ }}
+
+
+
+
+
+
+
diff --git a/ui-src/src/environments/environment.prod.ts b/ui-src/src/environments/environment.prod.ts
index da91497..6ae38d1 100644
--- a/ui-src/src/environments/environment.prod.ts
+++ b/ui-src/src/environments/environment.prod.ts
@@ -1,6 +1,5 @@
export const environment = {
production: true,
-
- apiBaseUrl: "http://localhost:9191/"
-
+ API_BASE_URL: "http://localhost:9191/",
+ ASSESTS_BASE_URL: "http://localhost:9191/"
};
diff --git a/ui-src/src/environments/environment.ts b/ui-src/src/environments/environment.ts
index b7f639a..dc92f2b 100644
--- a/ui-src/src/environments/environment.ts
+++ b/ui-src/src/environments/environment.ts
@@ -4,5 +4,7 @@
// The list of which env maps to which file can be found in `.angular-cli.json`.
export const environment = {
- production: false
+ production: false,
+ API_BASE_URL: "http://localhost:9191/",
+ ASSESTS_BASE_URL: "http://localhost:4200/"
};
diff --git a/ui-src/src/styles.css b/ui-src/src/styles.css
index dba64b8..5e244ec 100644
--- a/ui-src/src/styles.css
+++ b/ui-src/src/styles.css
@@ -2,7 +2,9 @@
/* You can add global styles to this file, and also import other style files */
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700');
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
-@import "~@angular/material/prebuilt-themes/indigo-pink.css";
+@import './app/configurations/configurations.component.css';
+@import './app/test-suites/test-suites.component.css';
+@import "./app/test-cases/test-cases.component.css";
diff --git a/ui-src/tslint.json b/ui-src/tslint.json
index 09f179b..2517c6a 100644
--- a/ui-src/tslint.json
+++ b/ui-src/tslint.json
@@ -1,22 +1,37 @@
{
- "rulesDirectory": ["node_modules/codelyzer"],
+ "rulesDirectory": [
+ "node_modules/codelyzer"
+ ],
"rules": {
"arrow-return-shorthand": true,
"callable-types": true,
"class-name": true,
- "comment-format": [true, "check-space"],
+ "comment-format": [
+ true,
+ "check-space"
+ ],
"curly": true,
"deprecation": {
"severity": "warn"
},
"eofline": true,
"forin": true,
- "import-blacklist": [true, "rxjs", "rxjs/Rx"],
+ "import-blacklist": [
+ true,
+ "rxjs",
+ "rxjs/Rx"
+ ],
"import-spacing": true,
- "indent": [true, "spaces"],
+ "indent": [
+ true,
+ "spaces"
+ ],
"interface-over-type-literal": true,
"label-position": true,
- "max-line-length": [true, 140],
+ "max-line-length": [
+ true,
+ 140
+ ],
"member-access": false,
"member-ordering": [
true,
@@ -31,14 +46,24 @@
],
"no-arg": true,
"no-bitwise": true,
- "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
+ "no-console": [
+ true,
+ "debug",
+ "info",
+ "time",
+ "timeEnd",
+ "trace"
+ ],
"no-construct": true,
"no-debugger": true,
"no-duplicate-super": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
- "no-inferrable-types": [true, "ignore-params"],
+ "no-inferrable-types": [
+ true,
+ "ignore-params"
+ ],
"no-misused-new": true,
"no-non-null-assertion": true,
"no-shadowed-variable": true,
@@ -59,10 +84,19 @@
"check-whitespace"
],
"prefer-const": true,
- "quotemark": [true, "double"],
+ "quotemark": [
+ true,
+ "double"
+ ],
"radix": true,
- "semicolon": [true, "always"],
- "triple-equals": [true, "allow-null-check"],
+ "semicolon": [
+ true,
+ "always"
+ ],
+ "triple-equals": [
+ true,
+ "allow-null-check"
+ ],
"typedef-whitespace": [
true,
{
@@ -84,8 +118,18 @@
"check-separator",
"check-type"
],
- "directive-selector": [true, "attribute", "app", "camelCase"],
- "component-selector": [true, "element", "app", "kebab-case"],
+ "directive-selector": [
+ true,
+ "attribute",
+ "app",
+ "camelCase"
+ ],
+ "component-selector": [
+ true,
+ "element",
+ "app",
+ "kebab-case"
+ ],
"no-output-on-prefix": true,
"use-input-property-decorator": true,
"use-output-property-decorator": true,
@@ -97,4 +141,4 @@
"component-class-suffix": true,
"directive-class-suffix": true
}
-}
+}
\ No newline at end of file
diff --git a/uiServices/src/configServices.go b/uiServices/src/configServices.go
index fe6b204..2ee1ec4 100644
--- a/uiServices/src/configServices.go
+++ b/uiServices/src/configServices.go
@@ -15,17 +15,10 @@ import (
"github.com/xtracdev/automated-perf-test/perfTestUtils"
)
-var schemaFilename string = "schema.json"
-var structName string = "Config"
-
-func getConfigHeader(req *http.Request) string {
- configPathDir := req.Header.Get("configPathDir")
-
- if !strings.HasSuffix(configPathDir, "/") {
- configPathDir = configPathDir + "/"
- }
- return configPathDir
-}
+const (
+ configSchema = "schema.json"
+ configStruct = "Config"
+)
func IsHeaderValid(header string) error {
if len(header) <= 1 {
@@ -43,13 +36,12 @@ func IsNameValid(name string) error {
return nil
}
-func IsPathDirValid(name string, rw http.ResponseWriter) bool {
+func IsPathDirValid(name string) error {
if len(name) <= 1 {
- logrus.Error("No file directory entered")
- rw.WriteHeader(http.StatusBadRequest)
- return false
+ logrus.Error("No directory path entered")
+ return fmt.Errorf("No directory path entered")
}
- return true
+ return nil
}
func ConfigCtx(next http.Handler) http.Handler {
@@ -59,11 +51,12 @@ func ConfigCtx(next http.Handler) http.Handler {
}
func postConfigs(rw http.ResponseWriter, req *http.Request) {
- configPathDir := req.Header.Get("configPathDir")
+ rw.Header().Set("Access-Control-Allow-Origin", "*")
+ configPathDir := getPathHeader(req)
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
- if !ValidateJSONWithSchema(buf.Bytes(), "schema.json", "Configurations") {
+ if !validateJSONWithSchema(buf.Bytes(), "schema.json", "Configurations") {
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -102,7 +95,7 @@ func postConfigs(rw http.ResponseWriter, req *http.Request) {
}
- if !configWriterXML(config, configPathDir+config.APIName+".xml") {
+ if !writeXML(config, configPathDir+config.APIName+".xml") {
rw.WriteHeader(http.StatusInternalServerError)
return
@@ -111,14 +104,9 @@ func postConfigs(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusCreated)
}
-func FilePathExist(path string) bool {
- _, err := os.Stat(path)
- return !os.IsNotExist(err)
-}
-
func getConfigs(rw http.ResponseWriter, req *http.Request) {
-
- configPathDir := getConfigHeader(req)
+ rw.Header().Set("Access-Control-Allow-Origin", "*")
+ configPathDir := getPathHeader(req)
configName := chi.URLParam(req, "configName")
if err := IsHeaderValid(configPathDir); err != nil {
@@ -152,14 +140,14 @@ func getConfigs(rw http.ResponseWriter, req *http.Request) {
err = xml.Unmarshal(byteValue, &config)
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot Unmarshall")
+ logrus.Error("Cannot Unmarshall XML ", err)
return
}
configJson, err := json.MarshalIndent(config, "", "")
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot Marshall")
+ logrus.Error("Cannot Marshall JSON", err)
return
}
@@ -170,7 +158,7 @@ func getConfigs(rw http.ResponseWriter, req *http.Request) {
}
func putConfigs(rw http.ResponseWriter, req *http.Request) {
- path := getConfigHeader(req)
+ path := getPathHeader(req)
configName := chi.URLParam(req, "configName")
if err := IsHeaderValid(path); err != nil {
@@ -187,7 +175,7 @@ func putConfigs(rw http.ResponseWriter, req *http.Request) {
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
- if !ValidateJSONWithSchema(buf.Bytes(), schemaFilename, structName) {
+ if !validateJSONWithSchema(buf.Bytes(), configSchema, configStruct) {
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -207,7 +195,7 @@ func putConfigs(rw http.ResponseWriter, req *http.Request) {
}
- if !configWriterXML(config, configPathDir) {
+ if !writeXML(config, configPathDir) {
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -216,7 +204,7 @@ func putConfigs(rw http.ResponseWriter, req *http.Request) {
}
func putConfigFileName(rw http.ResponseWriter, req *http.Request) {
- path := getConfigHeader(req)
+ path := getPathHeader(req)
configFileName := chi.URLParam(req, "configFileName")
newConfigFileName := chi.URLParam(req, "newConfigFileName")
diff --git a/uiServices/src/configServices_test.go b/uiServices/src/configServices_test.go
index c538322..e9fac6a 100644
--- a/uiServices/src/configServices_test.go
+++ b/uiServices/src/configServices_test.go
@@ -1,8 +1,6 @@
package services
import (
- "fmt"
-
"net/http"
"net/http/httptest"
"os"
@@ -14,7 +12,7 @@ import (
"github.com/xtracdev/automated-perf-test/perfTestUtils"
)
-const validJSON = `{
+const validJson = `{
"apiName": "ServiceTestConfig",
"targetHost": "localhost",
"targetPort": "9191",
@@ -94,22 +92,6 @@ const validJsonWithOneCharName = `{
"rampDelay": 15
}`
-func TestFilePathExist(t *testing.T) {
- path := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
- actual := false
- fmt.Println(path)
- actual = FilePathExist(path)
- expected := true
- assert.Equal(t, expected, actual)
-}
-
-func TestFilePathDoesNotExist(t *testing.T) {
- path := "((((((("
- actual := FilePathExist(path)
- expected := false
- assert.Equal(t, expected, actual)
-}
-
func TestInvalidJsonPostMissingRequiredField(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
@@ -119,7 +101,7 @@ func TestInvalidJsonPostMissingRequiredField(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -138,25 +120,23 @@ func TestValidJsonPost(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", postConfigs)
os.Remove(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/ServiceTestConfig.xml")
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+
+ assert.NoError(t, err)
+
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
- if err != nil {
- t.Error(err)
- }
+ assert.Equal(t, http.StatusCreated, w.Code)
- if w.Code != http.StatusCreated {
- t.Error("TestValidJsonPost. Expected:", http.StatusCreated, " Got:", w.Code, " Error. Did not succesfully post")
- }
}
func TestPostWithOneCharName(t *testing.T) {
@@ -170,7 +150,7 @@ func TestPostWithOneCharName(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -187,12 +167,12 @@ func TestPostWithInvalidHeader(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", postConfigs)
filePath := "xxxxxx"
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -227,11 +207,11 @@ func TestInvalidJsonPost(t *testing.T) {
}
}
-func TestWhenConfigPathDirEmpty(t *testing.T) {
+func TestWhenpathEmpty(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", postConfigs)
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
@@ -244,13 +224,13 @@ func TestWhenConfigPathDirEmpty(t *testing.T) {
}
if w.Code != http.StatusBadRequest {
- t.Error("TestWhenConfigPathDirEmpty. Expected:", http.StatusBadRequest, " Got:", w.Code, "Error. ConfigPathDir is Empty ")
+ t.Error("TestWhenpathEmpty. Expected:", http.StatusBadRequest, " Got:", w.Code, "Error. path is Empty ")
}
}
func TestInvalidURL(t *testing.T) {
pt := perfTestUtils.Config{}
- configWriterXML(pt, "/path/xxx")
+ writeXML(pt, "/path/xxx")
}
func TestSuccessfulGet(t *testing.T) {
@@ -258,12 +238,12 @@ func TestSuccessfulGet(t *testing.T) {
r.Mount("/", GetIndexPage())
// create file to GET
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", postConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPost, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -271,8 +251,8 @@ func TestSuccessfulGet(t *testing.T) {
filePath = os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err = http.NewRequest(http.MethodGet, "/configs/ServiceTestConfig", nil)
- request.Header.Set("configPathDir", filePath)
- request.Header.Get("configPathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w = httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -295,8 +275,8 @@ func TestSuccessfulGetPathWihoutSlash(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodGet, "/configs/ServiceTestConfig", nil)
- request.Header.Set("configPathDir", filePath)
- request.Header.Get("configPathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -319,8 +299,8 @@ func TestGetNoHeaderPath(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodGet, "/configs/serviceTestConfig", nil)
- request.Header.Set("configPathDir", filePath)
- request.Header.Get("configPathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -343,8 +323,8 @@ func TestGetFileNotFound(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodGet, "/configs/xxx.java", nil)
- request.Header.Set("configPathDir", filePath)
- request.Header.Get("configPathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -362,12 +342,12 @@ func TestValidJsonPut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/configs/ServiceTestConfig", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -388,7 +368,7 @@ func TestMissingFieldPut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/configs/ServiceTestConfig", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -409,7 +389,7 @@ func TestInvalidJsonPut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/configs/ServiceTestConfig", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -425,12 +405,12 @@ func TestInvalidUrlPut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/configs/xxx", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -446,12 +426,12 @@ func TestNoUrlPut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -467,12 +447,12 @@ func TestSuccessfulPutWithNoPathSlash(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/configs/ServiceTestConfig", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -487,12 +467,12 @@ func TestNoPathPut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := ""
request, err := http.NewRequest(http.MethodPut, "/configs/ServiceTestConfig", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -508,12 +488,12 @@ func TestNoFileNamePut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(validJSON)
+ reader := strings.NewReader(validJson)
r.HandleFunc("/configs", putConfigs)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/configs", reader)
- request.Header.Set("configPathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
diff --git a/uiServices/src/homepage.go b/uiServices/src/homepage.go
index b2b0bb2..0dab8c3 100644
--- a/uiServices/src/homepage.go
+++ b/uiServices/src/homepage.go
@@ -1,25 +1,21 @@
package services
import (
- "io/ioutil"
- "net/http"
- "path/filepath"
-<<<<<<< HEAD
- "github.com/go-chi/cors"
-=======
-
"github.com/Sirupsen/logrus"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
+ "github.com/go-chi/cors"
+ "io/ioutil"
+ "net/http"
+ "path/filepath"
->>>>>>> 3739ecf74b1ebdd56489c07d1e556eb8b43fb1fd
"os"
)
const contentTypeHeader = `Content-Type`
const htmlType = `text/html`
-func StartUiMode() {
+func StartUIMode() {
http.ListenAndServe(":9191", GetRouter())
}
@@ -78,9 +74,9 @@ func GetIndexPage() *chi.Mux {
router.Get("/*", func(w http.ResponseWriter, r *http.Request) {
- resourceUrl := r.URL.String()
+ resourceURL := r.URL.String()
- path := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/ui/" + resourceUrl
+ path := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/ui/" + resourceURL
absPath, err := filepath.Abs(path)
@@ -118,6 +114,7 @@ func routeConfigs() http.Handler {
router.Post("/", postConfigs)
router.Get("/{configName}", getConfigs)
router.Put("/{configName}", putConfigs)
+ router.Put("/filename/{configFileName}/{newConfigFileName}", putConfigFileName)
return router
}
@@ -142,6 +139,7 @@ func routeTestCases() http.Handler {
router.Get("/", getAllTestCases)
router.Get("/{testCaseName}", getTestCase)
router.Delete("/{testCaseName}", deleteTestCase)
+ router.Delete("/", deleteAllTestCases)
return router
}
diff --git a/uiServices/src/homepage_test.go b/uiServices/src/homepage_test.go
deleted file mode 100644
index 85961c3..0000000
--- a/uiServices/src/homepage_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package services
-
-import (
- "github.com/go-chi/chi"
- "github.com/stretchr/testify/assert"
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-func TestStartUiModeSuccesfully(t *testing.T) {
-
- r := chi.NewRouter()
-
- r.Mount("/", GetIndexPage())
-
- assert.IsType(t, &chi.Mux{}, r)
-
- resp := httptest.NewRecorder()
-
- req, _ := http.NewRequest(http.MethodGet, "/", nil)
- r.ServeHTTP(resp, req)
-
- assert.Equal(t, http.StatusOK, resp.Code)
- assert.Equal(t, htmlType, resp.Header().Get(contentTypeHeader))
-
-}
-
-func TestStartUiModeWithInvalidURL(t *testing.T) {
-
- r := chi.NewRouter()
-
- r.Mount("/", GetIndexPage())
-
- assert.IsType(t, &chi.Mux{}, r)
-
- resp := httptest.NewRecorder()
-
- req, _ := http.NewRequest(http.MethodGet, "/xxx", nil)
- r.ServeHTTP(resp, req)
-
- assert.Equal(t, http.StatusNotFound, resp.Code)
-}
-
-func TestStartUiModeWithResource(t *testing.T) {
-
- r := chi.NewRouter()
-
- r.Mount("/", GetIndexPage())
-
- assert.IsType(t, &chi.Mux{}, r)
-
- resp := httptest.NewRecorder()
-
- req, _ := http.NewRequest(http.MethodGet, "/index.html", nil)
- r.ServeHTTP(resp, req)
-
- assert.Equal(t, http.StatusOK, resp.Code)
- assert.Equal(t, htmlType, resp.Header().Get(contentTypeHeader))
-
-}
diff --git a/uiServices/src/testCaseServices.go b/uiServices/src/testCaseServices.go
index 10aeac7..be977b7 100644
--- a/uiServices/src/testCaseServices.go
+++ b/uiServices/src/testCaseServices.go
@@ -9,62 +9,59 @@ import (
"net/http"
"os"
"path/filepath"
- "strings"
"github.com/Sirupsen/logrus"
"github.com/go-chi/chi"
"github.com/xtracdev/automated-perf-test/testStrategies"
)
-const testCaseSchema string = "testCase_schema.json"
-const structTypeName string = "TestCase "
+const (
+ testCaseSchema = "testCase_Schema.json"
+ testCaseStruct = "testDefinition"
+)
type Case struct {
- HttpMethod string `json:"httpMethod"`
- Name string `json:"name"`
- Description string `json:"description"`
+ HttpMethod string `json:"httpMethod"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ PreThinkTime int64 `json:"preThinkTime"`
+ PostThinkTime int64 `json:"postThinkTime"`
+ ExecWeight string `json:"execWeight"`
}
func TestCaseCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
-
-}
-func getTestCaseHeader(req *http.Request) string {
- testCasePathDir := req.Header.Get("testCasePathDir")
-
- if !strings.HasSuffix(testCasePathDir, "/") {
- testCasePathDir = testCasePathDir + "/"
- }
- return testCasePathDir
}
func postTestCase(rw http.ResponseWriter, req *http.Request) {
- testCasePathDir := getTestCaseHeader(req)
+ testCasePathDir := getPathHeader(req)
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
testCase := testStrategies.TestDefinition{}
err := json.Unmarshal(buf.Bytes(), &testCase)
if err != nil {
- logrus.Error("Failed to unmarshall json body")
+ logrus.Error("Failed to unmarshall json body", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if err := IsHeaderValid(testCasePathDir); err != nil {
+ logrus.Error("No header path found", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if err := IsNameValid(testCase.TestName); err != nil {
+ logrus.Error("File name is empty", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if !FilePathExist(testCasePathDir) {
- logrus.Error("Directory path does not exist")
+ logrus.Error("No directory path entered")
rw.WriteHeader(http.StatusBadRequest)
return
@@ -77,7 +74,13 @@ func postTestCase(rw http.ResponseWriter, req *http.Request) {
}
- if !testCaseWriterXml(testCase, testCasePathDir+testCase.TestName+".xml") {
+ if !validateJSONWithSchema(buf.Bytes(), testCaseSchema, testCaseStruct) {
+ rw.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ if !writeXML(testCase, testCasePathDir+testCase.TestName+".xml") {
+ logrus.Error("Error writing to the file")
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -86,21 +89,23 @@ func postTestCase(rw http.ResponseWriter, req *http.Request) {
}
func putTestCase(rw http.ResponseWriter, req *http.Request) {
- path := getTestCaseHeader(req)
+ path := getPathHeader(req)
testCaseName := chi.URLParam(req, "testCaseName")
if err := IsHeaderValid(path); err != nil {
+ logrus.Error("No header path found", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if err := IsNameValid(testCaseName); err != nil {
+ logrus.Error("File name is empty", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
testCasePathDir := fmt.Sprintf("%s%s.xml", path, testCaseName)
- buf := new(bytes.Buffer)
- buf.ReadFrom(req.Body)
+
+ logrus.Error("testCasePathDir", testCasePathDir)
if !FilePathExist(testCasePathDir) {
logrus.Error("File path does not exist")
@@ -109,7 +114,10 @@ func putTestCase(rw http.ResponseWriter, req *http.Request) {
}
- if !ValidateJSONWithSchema(buf.Bytes(), testCaseSchema, structTypeName) {
+ buf := new(bytes.Buffer)
+ buf.ReadFrom(req.Body)
+
+ if !validateJSONWithSchema(buf.Bytes(), testCaseSchema, testCaseStruct) {
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -118,7 +126,7 @@ func putTestCase(rw http.ResponseWriter, req *http.Request) {
err := json.Unmarshal(buf.Bytes(), &testCase)
if err != nil {
- logrus.Error("Cannot Unmarshall Json")
+ logrus.Error("Error unmarshalling Json", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -129,7 +137,8 @@ func putTestCase(rw http.ResponseWriter, req *http.Request) {
return
}
- if !testCaseWriterXml(testCase, testCasePathDir) {
+ if !writeXML(testCase, testCasePathDir) {
+ logrus.Error("Error writing to the file")
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -138,16 +147,20 @@ func putTestCase(rw http.ResponseWriter, req *http.Request) {
}
func getAllTestCases(rw http.ResponseWriter, req *http.Request) {
+ rw.Header().Set("Access-Control-Allow-Origin", "*")
+ testCasePathDir := getPathHeader(req)
- testCasePathDir := getTestCaseHeader(req)
-
- if !IsPathDirValid(testCasePathDir, rw) {
+ if err := IsPathDirValid(testCasePathDir); err != nil {
+ logrus.Error("Path Directory is not valid", err)
+ rw.WriteHeader(http.StatusBadRequest)
return
}
files, err := ioutil.ReadDir(testCasePathDir)
if err != nil {
- logrus.Error(err)
+ logrus.Error("Error reading the directory ", err)
+ rw.WriteHeader(http.StatusInternalServerError)
+ return
}
testCases := make([]Case, 0)
@@ -161,28 +174,34 @@ func getAllTestCases(rw http.ResponseWriter, req *http.Request) {
file, err := os.Open(fmt.Sprintf("%s%s", testCasePathDir, filename))
if err != nil {
- logrus.Error("Cannot Open File: " + filename)
+ logrus.Error("Cannot open file: ", filename, err)
+ logrus.Error("Error opening the file: " + filename)
continue
}
byteValue, err := ioutil.ReadAll(file)
if err != nil {
- logrus.Error("Cannot Read File: " + filename)
+ logrus.Error("Cannot Read File: ", filename, err)
+ logrus.Error("Error reading the file: " + filename)
continue
}
err = xml.Unmarshal(byteValue, testCase)
if err != nil {
- logrus.Error("Cannot Unmarshall File: " + filename)
+ logrus.Error("Cannot Unmarshall: ", filename, err)
+
+ logrus.Error("Error unmarshalling the file: " + filename)
continue
}
- //if a Test Case Name can't be assigned, it isn't a Test Case object
if testCase.TestName != "" {
testCases = append(testCases, Case{
- Name: testCase.TestName,
- Description: testCase.Description,
- HttpMethod: testCase.HTTPMethod,
+ Name: testCase.TestName,
+ Description: testCase.Description,
+ HttpMethod: testCase.HTTPMethod,
+ PostThinkTime: testCase.PostThinkTime,
+ PreThinkTime: testCase.PreThinkTime,
+ ExecWeight: testCase.ExecWeight,
})
}
}
@@ -190,7 +209,7 @@ func getAllTestCases(rw http.ResponseWriter, req *http.Request) {
err = json.NewEncoder(rw).Encode(testCases)
if err != nil {
- logrus.Error("Could not enocde Test Cases")
+ logrus.Error("Error encoding Test Cases", err)
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -199,20 +218,25 @@ func getAllTestCases(rw http.ResponseWriter, req *http.Request) {
}
func getTestCase(rw http.ResponseWriter, req *http.Request) {
-
- testCasePathDir := getTestCaseHeader(req)
+ rw.Header().Set("Access-Control-Allow-Origin", "*")
+ testCasePathDir := getPathHeader(req)
testCaseName := chi.URLParam(req, "testCaseName")
if err := IsHeaderValid(testCasePathDir); err != nil {
+ logrus.Error("No header path found", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if err := IsNameValid(testCaseName); err != nil {
+ logrus.Error("File name is empty", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
+ filePath := fmt.Sprintf("%s%s.xml", testCasePathDir, testCaseName)
+ logrus.Info("FilePath: ", filePath)
+
if _, err := os.Stat(fmt.Sprintf("%s%s.xml", testCasePathDir, testCaseName)); err != nil {
if os.IsNotExist(err) {
logrus.Error("Test Case File Not Found: " + testCaseName)
@@ -223,8 +247,8 @@ func getTestCase(rw http.ResponseWriter, req *http.Request) {
file, err := os.Open(fmt.Sprintf("%s%s.xml", testCasePathDir, testCaseName))
if err != nil {
- logrus.Error("Cannot open: " + testCaseName)
- rw.WriteHeader(http.StatusInternalServerError)
+ logrus.Error("Test Case Name Not Found: " + testCasePathDir + testCaseName)
+ rw.WriteHeader(http.StatusNotFound)
return
}
defer file.Close()
@@ -233,22 +257,23 @@ func getTestCase(rw http.ResponseWriter, req *http.Request) {
byteValue, err := ioutil.ReadAll(file)
if err != nil {
+ logrus.Error("Error reading from file", err)
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot Read File", err)
+ logrus.Error("Cannot Read File")
return
}
err = xml.Unmarshal(byteValue, &testCase)
if err != nil {
+ logrus.Error("Error unmarshalling from XML", err)
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot Unmarshall from XML", err)
return
}
testSuiteJSON, err := json.MarshalIndent(testCase, "", "")
if err != nil {
+ logrus.Error("Error marshalling to JSON", err)
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot marshall to JSON", err)
return
}
@@ -258,15 +283,17 @@ func getTestCase(rw http.ResponseWriter, req *http.Request) {
}
func deleteTestCase(rw http.ResponseWriter, req *http.Request) {
- testCasePathDir := getTestCaseHeader(req)
+ testCasePathDir := getPathHeader(req)
testCaseName := chi.URLParam(req, "testCaseName")
if err := IsHeaderValid(testCasePathDir); err != nil {
+ logrus.Error("No header path found", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
if err := IsNameValid(testCaseName); err != nil {
+ logrus.Error("File name is empty", err)
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -283,8 +310,8 @@ func deleteTestCase(rw http.ResponseWriter, req *http.Request) {
err := os.Remove(filepath)
if err != nil {
- logrus.Println("File was not deleted", err)
- rw.WriteHeader(http.StatusInternalServerError)
+ logrus.Println("Error deleting the file", err)
+ rw.WriteHeader(http.StatusNoContent)
return
}
@@ -292,3 +319,31 @@ func deleteTestCase(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusNoContent)
}
+func deleteAllTestCases(rw http.ResponseWriter, req *http.Request) {
+ testCasePathDir := getPathHeader(req)
+
+ if err := IsHeaderValid(testCasePathDir); err != nil {
+ logrus.Error("No heared path found", err)
+ rw.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ files, err := ioutil.ReadDir(testCasePathDir)
+ if err != nil {
+ logrus.Error("Error reading the directory ", err)
+ rw.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ for _, file := range files {
+ filepath := fmt.Sprintf("%s%s", testCasePathDir, file.Name())
+
+ err := os.Remove(filepath)
+ if err != nil {
+ logrus.Error("Error removing the files from directory", err)
+ rw.WriteHeader(http.StatusNoContent)
+ return
+ }
+ }
+ rw.WriteHeader(http.StatusOK)
+}
diff --git a/uiServices/src/testCaseServices_test.go b/uiServices/src/testCaseServices_test.go
index d3d8c69..bd7bc2d 100644
--- a/uiServices/src/testCaseServices_test.go
+++ b/uiServices/src/testCaseServices_test.go
@@ -1,12 +1,15 @@
package services
import (
+ "fmt"
+ "io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
+ "github.com/Sirupsen/logrus"
"github.com/go-chi/chi"
"github.com/stretchr/testify/assert"
)
@@ -17,8 +20,8 @@ const validTestCase = `
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -26,18 +29,18 @@ const validTestCase = `
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
`
@@ -48,8 +51,8 @@ const TestCaseNoName = `
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -57,18 +60,18 @@ const TestCaseNoName = `
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
`
@@ -79,7 +82,7 @@ const TestCaseMissingRequired = `
"description":"",
"overrideHost":"",
"overridePort":"",
- "BaseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -90,14 +93,14 @@ const TestCaseMissingRequired = `
}
`
-const TestCaseForDeletion = `
+const testCaseForDeletion = `
{
"testname":"TestCaseService2",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -105,18 +108,18 @@ const TestCaseForDeletion = `
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
`
@@ -132,7 +135,7 @@ func TestValidTestCasePost(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-cases", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -151,7 +154,7 @@ func TestCasePostWithExistingFileName(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-cases", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -170,7 +173,7 @@ func TestCasePostNoHeader(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodPost, "/test-cases", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -189,7 +192,7 @@ func TestPostTestCaseMissingRequiredValues(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-cases", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -202,21 +205,20 @@ func TestPostTestCaseMissingRequiredValues(t *testing.T) {
func TestValidTestCasePut(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
-
reader := strings.NewReader(validTestCase)
- r.HandleFunc("/test-cases", putTestCase)
+
+ //r.HandleFunc("/test-cases", putTestCase)
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-cases/TestCaseService", reader)
- request.Header.Set("testCasePathDir", filePath)
+
+ assert.NoError(t, err)
+
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
- if err != nil {
- t.Error(err)
- }
-
assert.Equal(t, http.StatusNoContent, w.Code, "Did Not successfully Update")
}
@@ -229,7 +231,7 @@ func TestTestCasePutMissingRequired(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-cases/TestCaseService", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -250,7 +252,7 @@ func TestInvalidUrlTestCasePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-cases/xxxxxxxxxxxzzx", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -271,7 +273,7 @@ func TestNoUrlTestCasePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -292,7 +294,7 @@ func TestCasePutWithNoPathSlash(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/test-cases/TestCaseService", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -313,7 +315,7 @@ func TestNoPathTestCasePut(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodPut, "/test-cases/TestCaseService", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -334,7 +336,7 @@ func TestNoNameTestCasePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/test-cases/TestCaseService", reader)
- request.Header.Set("testCasePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -350,47 +352,45 @@ func TestSuccessfulGetAllCases(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- DirectoryPath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
+ directoryPath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodGet, "/test-cases", nil)
+ assert.NoError(t, err)
- request.Header.Set("testCasePathDir", DirectoryPath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", directoryPath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
- if assert.NoError(t, err) {
- assert.Equal(t, http.StatusOK, w.Code, "Did not get all test cases")
- }
+ assert.Equal(t, http.StatusOK, w.Code, "Did not get all test casess")
}
func TestGetAllCasesNoHeader(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- DircetoryPath := ""
request, err := http.NewRequest(http.MethodGet, "/test-cases", nil)
- request.Header.Set("testCasePathDir", DircetoryPath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", "")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
- if assert.NoError(t, err) {
- assert.Equal(t, http.StatusBadRequest, w.Code, "Did not get all test cases")
+ if err != nil {
+ t.Error(err)
}
+
+ assert.Equal(t, http.StatusBadRequest, w.Code, "Should not have retrieved all test cases")
}
-func TestSuccessfulGetTestCase(t *testing.T) {
+func TestGetTestCaseNoHeader(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
- request, err := http.NewRequest(http.MethodGet, "/test-cases/TestCaseService", nil)
+ filePath := ""
+ request, err := http.NewRequest(http.MethodGet, "/test-cases/Case1", nil)
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -399,18 +399,18 @@ func TestSuccessfulGetTestCase(t *testing.T) {
t.Error(err)
}
- assert.Equal(t, http.StatusOK, w.Code, "Error. Did not successfully GET")
+ assert.Equal(t, http.StatusBadRequest, w.Code, "Should not return data")
}
-func TestGetTestCaseNoHeader(t *testing.T) {
+func TestGetTestCaseFileNotFound(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- filePath := ""
- request, err := http.NewRequest(http.MethodGet, "/test-cases/TestCaseService", nil)
+ filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/cases"
+ request, err := http.NewRequest(http.MethodGet, "/test-cases/xxx", nil)
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -419,39 +419,79 @@ func TestGetTestCaseNoHeader(t *testing.T) {
t.Error(err)
}
- assert.Equal(t, http.StatusBadRequest, w.Code, "Should not return data")
+ assert.Equal(t, http.StatusNotFound, w.Code, "Should not return data")
}
-func TestGetTestCaseFileNotFound(t *testing.T) {
+func TestDeleteAllCasesSuccess(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
- request, err := http.NewRequest(http.MethodGet, "/test-cases/xxx", nil)
+ directory := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/cases"
+ err := ioutil.WriteFile(fmt.Sprintf("%s%s.xml", directory, "test"), nil, 0666)
+ if err != nil {
+ logrus.Errorf("Error trying to create a file: %s", err)
+ }
+
+ request, err := http.NewRequest(http.MethodDelete, "/test-cases", nil)
+ assert.NoError(t, err)
+
+ request.Header.Set("path", directory)
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ w := httptest.NewRecorder()
+ r.ServeHTTP(w, request)
+
+ assert.Equal(t, http.StatusOK, w.Code, "All files have been DELETED")
+
+}
+
+func TestDeleteAllCasesNoHeader(t *testing.T) {
+ r := chi.NewRouter()
+ r.Mount("/", GetIndexPage())
+
+ DirectoryPath := ""
+ request, err := http.NewRequest(http.MethodDelete, "/test-cases", nil)
+ if err != nil {
+ logrus.Warnf("Error creating the request %s", err)
+ }
+
+ request.Header.Set("path", DirectoryPath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
+ assert.Equal(t, http.StatusBadRequest, w.Code, "Did not DELETE the files")
+}
+
+func TestDeleteAllCasesEmptyDirectory(t *testing.T) {
+ r := chi.NewRouter()
+ r.Mount("/", GetIndexPage())
+
+ DirectoryPath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/cases/"
+ request, err := http.NewRequest(http.MethodDelete, "/test-cases/", nil)
if err != nil {
- t.Error(err)
+ logrus.Warnf("Error creating the request %s", err)
+ return
}
- assert.Equal(t, http.StatusNotFound, w.Code, "Should not return data")
+ request.Header.Set("path", DirectoryPath)
+
+ w := httptest.NewRecorder()
+ r.ServeHTTP(w, request)
+
+ assert.Equal(t, http.StatusNotFound, w.Code, "Empty Directory")
}
func TestSuccessfulCaseDelete(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
- reader := strings.NewReader(TestCaseForDeletion)
+ reader := strings.NewReader(testCaseForDeletion)
r.HandleFunc("/test-cases", postTestCase)
- filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
+ filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPost, "/test-cases", reader)
- request.Header.Set("testCasePathDir", filePath)
+ assert.NoError(t, err)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -460,19 +500,16 @@ func TestSuccessfulCaseDelete(t *testing.T) {
assert.Equal(t, http.StatusCreated, w.Code, "Error: Did Not Successfully Post")
+ r.HandleFunc("/test-cases", deleteTestCase)
+
filePath = os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err = http.NewRequest(http.MethodDelete, "/test-cases/TestCaseService2", nil)
-
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ assert.NoError(t, err)
+ request.Header.Set("path", filePath)
w = httptest.NewRecorder()
r.ServeHTTP(w, request)
- if err != nil {
- t.Error(err)
- }
-
assert.Equal(t, http.StatusNoContent, w.Code, "Error. Did not successfully Delete")
}
@@ -483,8 +520,8 @@ func TestDeleteCaseFileNotFound(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodDelete, "/test-cases/xxx", nil)
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -503,8 +540,8 @@ func TestDeleteCaseWithNoHeader(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodDelete, "/test-cases/TestCaseService", nil)
- request.Header.Set("testCasePathDir", filePath)
- request.Header.Get("testCasePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
diff --git a/uiServices/src/testSuiteServices.go b/uiServices/src/testSuiteServices.go
index 72ce528..34d2557 100644
--- a/uiServices/src/testSuiteServices.go
+++ b/uiServices/src/testSuiteServices.go
@@ -10,16 +10,16 @@ import (
"net/http"
"os"
"path/filepath"
- "strings"
"github.com/Sirupsen/logrus"
"github.com/go-chi/chi"
- "github.com/xeipuuv/gojsonschema"
"github.com/xtracdev/automated-perf-test/testStrategies"
)
-var schemaFile string = "testSuite_schema.json"
-var structType string = "TestSuite"
+const (
+ schemaFile = "testSuite_schema.json"
+ structType = "testSuite"
+)
type Suite struct {
File string `json:"file"`
@@ -33,19 +33,10 @@ func TestSuiteCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
-
-}
-func getTestSuiteHeader(req *http.Request) string {
- testSuitePathDir := req.Header.Get("testSuitePathDir")
-
- if !strings.HasSuffix(testSuitePathDir, "/") {
- testSuitePathDir = testSuitePathDir + "/"
- }
- return testSuitePathDir
}
func postTestSuites(rw http.ResponseWriter, req *http.Request) {
- testSuitePathDir := getTestSuiteHeader(req)
+ testSuitePathDir := getPathHeader(req)
buf := new(bytes.Buffer)
buf.ReadFrom(req.Body)
@@ -67,7 +58,7 @@ func postTestSuites(rw http.ResponseWriter, req *http.Request) {
return
}
- if !ValidateJSONWithSchema(buf.Bytes(), schemaFile, structType) {
+ if !validateJSONWithSchema(buf.Bytes(), schemaFile, structType) {
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -79,14 +70,15 @@ func postTestSuites(rw http.ResponseWriter, req *http.Request) {
}
- if FilePathExist(fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuite.Name)) {
+ filePath := fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuite.Name)
+
+ if FilePathExist(filePath) {
logrus.Error("File already exists")
rw.WriteHeader(http.StatusBadRequest)
return
-
}
- if !testSuiteWriterXML(testSuite, testSuitePathDir+testSuite.Name+".xml") {
+ if !writeXML(testSuite, filePath) {
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -94,30 +86,8 @@ func postTestSuites(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusCreated)
}
-func ValidateJSONWithSchema(testSuite []byte, schemaName, structType string) bool {
- goPath := os.Getenv("GOPATH")
- schemaLoader := gojsonschema.NewReferenceLoader("file:///" + goPath + "/src/github.com/xtracdev/automated-perf-test/ui-src/src/assets/" + schemaName)
- documentLoader := gojsonschema.NewBytesLoader(testSuite)
- logrus.Info(schemaLoader)
- result, error := gojsonschema.Validate(schemaLoader, documentLoader)
-
- if error != nil {
- return false
- }
- if !result.Valid() {
- logrus.Errorf("%sdocument is not valid. see errors :", structType)
- for _, desc := range result.Errors() {
- logrus.Error("- ", desc)
- return false
- }
- }
-
- logrus.Infof("%s document is valid", structType)
- return true
-}
-
func putTestSuites(rw http.ResponseWriter, req *http.Request) {
- path := getTestSuiteHeader(req)
+ path := getPathHeader(req)
testSuiteName := chi.URLParam(req, "testSuiteName")
if err := IsHeaderValid(path); err != nil {
@@ -138,10 +108,9 @@ func putTestSuites(rw http.ResponseWriter, req *http.Request) {
logrus.Error("File path does not exist")
rw.WriteHeader(http.StatusNotFound)
return
-
}
- if !ValidateJSONWithSchema(buf.Bytes(), schemaFile, structType) {
+ if !validateJSONWithSchema(buf.Bytes(), schemaFile, structType) {
rw.WriteHeader(http.StatusBadRequest)
return
}
@@ -155,7 +124,7 @@ func putTestSuites(rw http.ResponseWriter, req *http.Request) {
return
}
- if !testSuiteWriterXML(testSuite, testSuitePathDir) {
+ if !writeXML(testSuite, testSuitePathDir) {
rw.WriteHeader(http.StatusInternalServerError)
return
}
@@ -164,7 +133,7 @@ func putTestSuites(rw http.ResponseWriter, req *http.Request) {
}
func deleteTestSuite(rw http.ResponseWriter, req *http.Request) {
- testSuitePathDir := getTestSuiteHeader(req)
+ testSuitePathDir := getPathHeader(req)
testSuiteName := chi.URLParam(req, "testSuiteName")
if err := IsHeaderValid(testSuitePathDir); err != nil {
@@ -177,15 +146,18 @@ func deleteTestSuite(rw http.ResponseWriter, req *http.Request) {
return
}
- if _, err := os.Stat(fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuiteName)); err != nil {
+ filepath := fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuiteName)
+
+ if _, err := os.Stat(filepath); err != nil {
if os.IsNotExist(err) {
- logrus.Error("Test Suite File Not Found: " + testSuitePathDir + testSuiteName)
+ logrus.Error("Test Suite File Not Found: ", err)
rw.WriteHeader(http.StatusNotFound)
return
}
}
- err := os.Remove(fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuiteName))
+ filePath := fmt.Sprintf("%s%s.xml", testSuitePathDir, testSuiteName)
+ err := os.Remove(filePath)
if err != nil {
logrus.Errorf("Error deleting the file from filesystem: %s", err)
rw.WriteHeader(http.StatusInternalServerError)
@@ -196,8 +168,7 @@ func deleteTestSuite(rw http.ResponseWriter, req *http.Request) {
}
func getTestSuite(rw http.ResponseWriter, req *http.Request) {
-
- testSuitePathDir := getTestSuiteHeader(req)
+ testSuitePathDir := getPathHeader(req)
testSuiteName := chi.URLParam(req, "testSuiteName")
if err := IsHeaderValid(testSuitePathDir); err != nil {
@@ -230,14 +201,14 @@ func getTestSuite(rw http.ResponseWriter, req *http.Request) {
err = xml.Unmarshal(byteValue, &testSuite)
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot Unmarshall from XML")
+ logrus.Error("Cannot Unmarshall from XML", err)
return
}
testSuiteJSON, err := json.MarshalIndent(testSuite, "", "")
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
- logrus.Error("Cannot marshall to JSON")
+ logrus.Error("Cannot marshall to JSON", err)
return
}
@@ -247,8 +218,7 @@ func getTestSuite(rw http.ResponseWriter, req *http.Request) {
}
func getAllTestSuites(rw http.ResponseWriter, req *http.Request) {
-
- testSuitePathDir := getTestSuiteHeader(req)
+ testSuitePathDir := getPathHeader(req)
if len(testSuitePathDir) <= 1 {
logrus.Error("No file directory entered")
rw.WriteHeader(http.StatusBadRequest)
diff --git a/uiServices/src/testSuiteServices_test.go b/uiServices/src/testSuiteServices_test.go
index 7c38abc..45b674d 100644
--- a/uiServices/src/testSuiteServices_test.go
+++ b/uiServices/src/testSuiteServices_test.go
@@ -2,12 +2,15 @@ package services
import (
"github.com/go-chi/chi"
- "github.com/stretchr/testify/assert"
+
"net/http"
"net/http/httptest"
"os"
+
"strings"
"testing"
+
+ "github.com/stretchr/testify/assert"
)
const validTestSuite = `
@@ -78,25 +81,6 @@ const TestSuiteNoName = `
}
`
-const validTestSuiteForDelete = `
-{
- "name": "TestSuiteA",
- "testStrategy": "SuiteBased",
- "description": "Services for XYZ",
- "testCases": [
- {
- "name":"file1",
- "preThinkTime": 1000,
- "postThinkTime": 2000,
- "execWeight": "Infrequent"
- },
- {
- "name":"file2"
- }
- ]
-}
-`
-
func TestValidTestSuitePost(t *testing.T) {
r := chi.NewRouter()
r.Mount("/", GetIndexPage())
@@ -108,7 +92,7 @@ func TestValidTestSuitePost(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -129,7 +113,7 @@ func TestFileExistsPost(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -150,7 +134,7 @@ func TestMissingRequiredTestSuitePost(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -172,7 +156,7 @@ func TestIncorrectDataTypePost(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -194,7 +178,7 @@ func TestValidTestSuitePostNoConfigPathDir(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -216,7 +200,7 @@ func TestValidTestSuitePostConfigPathDirNotExist(t *testing.T) {
filePath := "C:/a/b/c/d/////"
request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -238,7 +222,7 @@ func TestValidTestSuitePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-suites/TestSuiteService", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -259,7 +243,7 @@ func TestTestSuiteMissingFieldPut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-suites/TestSuiteService", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -280,7 +264,7 @@ func TestInvalidTestSuitePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-suites/TestSuiteService", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -301,7 +285,7 @@ func TestInvalidUrlTestSuitePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "/test-suites/xxx", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -322,7 +306,7 @@ func TestNoUrlTestSuitePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodPut, "", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -343,7 +327,7 @@ func TestPutWithNoPathSlash(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/test-suites/TestSuiteService", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -364,7 +348,7 @@ func TestNoPathTestSuitePut(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodPut, "/test-suites/TestSuiteService", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -385,7 +369,7 @@ func TestNoFileNameTestSuitePut(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
request, err := http.NewRequest(http.MethodPut, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -404,8 +388,7 @@ func TestSuccessfulGetTestSuite(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodGet, "/test-suites/TestSuiteService", nil)
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
+ request.Header.Set("path", filePath)
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -424,8 +407,8 @@ func TestGetTestSuiteNoPath(t *testing.T) {
filePath := ""
request, err := http.NewRequest(http.MethodGet, "/test-suites/TestSuiteService.xml", nil)
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -444,8 +427,8 @@ func TestGetTestSuiteFileNotFound(t *testing.T) {
filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodGet, "/test-suites/xxx", nil)
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
+ request.Header.Set("path", filePath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -464,8 +447,8 @@ func TestSuccessfulGetAllSuites(t *testing.T) {
DirectoryPath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
request, err := http.NewRequest(http.MethodGet, "/test-suites", nil)
- request.Header.Set("testSuitePathDir", DirectoryPath)
- request.Header.Get("testSuitePathDir")
+ request.Header.Set("path", DirectoryPath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -484,8 +467,8 @@ func TestGetAllSuitesNoHeader(t *testing.T) {
DircetoryPath := ""
request, err := http.NewRequest(http.MethodGet, "/test-suites", nil)
- request.Header.Set("testSuitePathDir", DircetoryPath)
- request.Header.Get("testSuitePathDir")
+ request.Header.Set("path", DircetoryPath)
+ request.Header.Get("path")
w := httptest.NewRecorder()
r.ServeHTTP(w, request)
@@ -496,80 +479,3 @@ func TestGetAllSuitesNoHeader(t *testing.T) {
assert.Equal(t, http.StatusBadRequest, w.Code, "Did not get all test suites")
}
-
-func TestSuccessfulDeleteTestSuite(t *testing.T) {
- r := chi.NewRouter()
- r.Mount("/", GetIndexPage())
-
- //create file to be deleted
- reader := strings.NewReader(validTestSuiteForDelete)
- r.HandleFunc("/test-suites", postTestSuites)
-
- filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
- request, err := http.NewRequest(http.MethodPost, "/test-suites", reader)
- request.Header.Set("testSuitePathDir", filePath)
-
- w := httptest.NewRecorder()
- r.ServeHTTP(w, request)
-
- if err != nil {
- t.Error(err)
- }
-
- assert.Equal(t, http.StatusCreated, w.Code, "Error: Did Not Successfully Post")
-
- filePath = os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
- request, err = http.NewRequest(http.MethodDelete, "/test-suites/TestSuiteA", nil)
-
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
-
- w = httptest.NewRecorder()
- r.ServeHTTP(w, request)
-
- if err != nil {
- t.Error(err)
- }
-
- assert.Equal(t, http.StatusNoContent, w.Code, "Error. Did not successfully Delete")
-}
-
-func TestDeleteTestSuiteNoHeader(t *testing.T) {
- r := chi.NewRouter()
- r.Mount("/", GetIndexPage())
-
- filePath := ""
- request, err := http.NewRequest(http.MethodDelete, "/test-suites/TestSuiteService", nil)
-
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
-
- w := httptest.NewRecorder()
- r.ServeHTTP(w, request)
-
- if err != nil {
- t.Error(err)
- }
-
- assert.Equal(t, http.StatusBadRequest, w.Code, "Deleted. But SHould Not Have")
-}
-
-func TestDeleteTestSuiteNotFound(t *testing.T) {
- r := chi.NewRouter()
- r.Mount("/", GetIndexPage())
-
- filePath := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
- request, err := http.NewRequest(http.MethodDelete, "/test-suites/xxx", nil)
-
- request.Header.Set("testSuitePathDir", filePath)
- request.Header.Get("testSuitePathDir")
-
- w := httptest.NewRecorder()
- r.ServeHTTP(w, request)
-
- if err != nil {
- t.Error(err)
- }
-
- assert.Equal(t, http.StatusNotFound, w.Code, "Deleted. But should not have")
-}
diff --git a/uiServices/src/util.go b/uiServices/src/util.go
new file mode 100644
index 0000000..4961bcf
--- /dev/null
+++ b/uiServices/src/util.go
@@ -0,0 +1,45 @@
+package services
+
+import (
+ "net/http"
+ "os"
+ "strings"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/xeipuuv/gojsonschema"
+)
+
+func getPathHeader(req *http.Request) string {
+ pathHeader := req.Header.Get("path")
+
+ if !strings.HasSuffix(pathHeader, "/") {
+ pathHeader = pathHeader + "/"
+ }
+ return pathHeader
+}
+
+func validateJSONWithSchema(testSuite []byte, schemaName, structType string) bool {
+ goPath := os.Getenv("GOPATH")
+ schemaLoader := gojsonschema.NewReferenceLoader("file:///" + goPath + "/src/github.com/xtracdev/automated-perf-test/ui-src/src/assets/" + schemaName)
+ documentLoader := gojsonschema.NewBytesLoader(testSuite)
+ logrus.Info(schemaLoader)
+ result, error := gojsonschema.Validate(schemaLoader, documentLoader)
+
+ if error != nil {
+ return false
+ }
+ if !result.Valid() {
+ logrus.Errorf("%sdocument is not valid. see errors :", structType)
+ for _, desc := range result.Errors() {
+ logrus.Error("- ", desc)
+ return false
+ }
+ }
+
+ logrus.Infof("%s document is valid", structType)
+ return true
+}
+func FilePathExist(path string) bool {
+ _, err := os.Stat(path)
+ return !os.IsNotExist(err)
+}
diff --git a/uiServices/src/util_test.go b/uiServices/src/util_test.go
new file mode 100644
index 0000000..21ffdd0
--- /dev/null
+++ b/uiServices/src/util_test.go
@@ -0,0 +1,25 @@
+package services
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFilePathExist(t *testing.T) {
+ path := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/"
+ actual := false
+ fmt.Println(path)
+ actual = FilePathExist(path)
+ expected := true
+ assert.Equal(t, expected, actual)
+}
+
+func TestFilePathDoesNotExist(t *testing.T) {
+ path := "((((((("
+ actual := FilePathExist(path)
+ expected := false
+ assert.Equal(t, expected, actual)
+}
diff --git a/uiServices/src/xmlWriter.go b/uiServices/src/xmlWriter.go
index 71415d4..683e6a2 100644
--- a/uiServices/src/xmlWriter.go
+++ b/uiServices/src/xmlWriter.go
@@ -7,14 +7,12 @@ import (
"os"
log "github.com/Sirupsen/logrus"
- "github.com/xtracdev/automated-perf-test/perfTestUtils"
- "github.com/xtracdev/automated-perf-test/testStrategies"
)
-func configWriterXML(config perfTestUtils.Config, configPathDir string) bool {
- filename := fmt.Sprintf("%s", configPathDir)
+func writeXML(definition interface{}, path string) bool {
+ filename := fmt.Sprintf("%s", path)
- configAsXML, err := xml.MarshalIndent(config, " ", " ")
+ payloadXML, err := xml.MarshalIndent(definition, " ", " ")
if err != nil {
log.Error("Failed to marshal to XML. Error:", err)
return false
@@ -28,47 +26,7 @@ func configWriterXML(config perfTestUtils.Config, configPathDir string) bool {
}
if file != nil {
defer file.Close()
- file.Write(configAsXML)
- }
- return true
-}
-
-func testSuiteWriterXML(testSuite testStrategies.TestSuite, configPathDir string) bool {
- filename := fmt.Sprintf("%s", configPathDir)
-
- testSuiteAsXML, err := xml.MarshalIndent(testSuite, " ", " ")
- if err != nil {
- log.Error("Failed to marshal to XML. Error:", err)
- return false
- }
-
- file, err := os.Create(filename)
- if err != nil {
- log.Error("Failed to create output file. Error:", err)
- return false
- }
- if file != nil {
- defer file.Close()
- file.Write(testSuiteAsXML)
- }
- return true
-}
-
-func testCaseWriterXml(testSuite testStrategies.TestDefinition, path string) bool {
- filename := fmt.Sprintf("%s", path)
-
- testCaseAsXml, err := xml.MarshalIndent(testSuite, " ", " ")
- if err != nil {
- log.Error("Failed to marshal to XML. Error:", err)
- return false
- }
-
- file, err := os.Create(filename)
- if err != nil {
- log.Error("Failed to create output file. Error:", err)
- return false
+ file.Write(payloadXML)
}
- defer file.Close()
- file.Write(testCaseAsXml)
return true
}
diff --git a/uiServices/test/configFile.feature b/uiServices/test/configFile.feature
index 2787caa..3421228 100644
--- a/uiServices/test/configFile.feature
+++ b/uiServices/test/configFile.feature
@@ -1,66 +1,90 @@
Feature: Create Configuration File
- As an API user
- I want to be able to create a configuration file
- So that I can test my application using custom metrics
+As an API user
+I want to be able to create a configuration file
+So that I can test my application using custom metrics
- ###################################
- ####### POST REQUESTS ##########
- ###################################
+ ###################################
+ ####### POST REQUESTS ##########
+ ###################################
Scenario: Successful creation of config file
- Given there is no existing test file "GodogConfig.xml"
+ Given there is no existing test file "ConfigSAMPLE.xml"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/GodogConfig.xml"
+ And the header "path" is "/uiServices/test"
When I send "POST" request to "/configs" with a body:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost",
- "targetPort":"9191",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 1000,
- "allowablePeakMemoryVariance": 30,
- "allowableServiceResponseTimeVariance": 30,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 5000,
- "TPSFreq": 30,
- "rampUsers": 5,
- "rampDelay": 15
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
}
"""
Then the response code should be 201
And the response body should be empty
- And the config file was created at location defined by configsPathDir
-#
+
Scenario: Unsuccessful creation of config file (file already exists)
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/GodogConfig.xml"
+ Given there is no existing test file "ConfigSAMPLE.xml"
+ And the header "path" is "/uiServices/test"
+ When I send "POST" request to "/configs" with a body:
+ """
+ {
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
+ }
+ """
+ Then the response code should be 201
+ And the header "path" is "/uiServices/test"
When I send "POST" request to "/configs" with a body:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost",
- "targetPort":"9191",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 1000,
- "allowablePeakMemoryVariance": 30,
- "allowableServiceResponseTimeVariance": 30,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 5000,
- "TPSFreq": 30,
- "rampUsers": 5,
- "rampDelay": 15
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
}
"""
Then the response code should be 400
@@ -68,321 +92,360 @@ Feature: Create Configuration File
Scenario: Unsuccessful creation of config file (Missing required field)
Given the automated performance ui server is available
When I send "POST" request to "/configs" with a body:
- """
+ """
{
- "apiName": "GodogConfig2",
- "targetHost": "localhost",
- "targetPort":"9191",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 1000,
- "allowablePeakMemoryVariance": 30,
- "allowableServiceResponseTimeVariance": 30,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "",
- "requestDelay": 5000,
- "TPSFreq": 30,
- "rampUsers": 5,
- "rampDelay": 15
+ "apiName": "ConfigSAMPLE2",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
}
"""
- And the header "configPathDir" is "/uiServices/test/GodogConfig.xml"
+ And the header "path" is "/uiServices/test"
Then the response code should be 400
Scenario: Unsuccessful creation of config file (Missing Header)
Given the automated performance ui server is available
- And the header "configPathDir" is ""
+ And the header "path" is ""
When I send "POST" request to "/configs" with a body:
- """
+ """
{
- "apiName": "GodogConfig3",
- "targetHost": "localhost",
- "targetPort":"9191",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 1000,
- "allowablePeakMemoryVariance": 30,
- "allowableServiceResponseTimeVariance": 30,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-1",
- "requestDelay": 5000,
- "TPSFreq": 30,
- "rampUsers": 5,
- "rampDelay": 15
+ "apiName": "ConfigSAMPLE3",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-1",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
}
"""
Then the response code should be 400
- ###################################
- ####### GET REQUESTS ########
- ###################################
+ ###################################
+ ####### GET REQUESTS ########
+ ###################################
Scenario: Try to retrieve config file with valid "GET" request
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
- Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
- And the file name is "GodogConfig.xml"
- When I send a "GET" request to "/configs/GodogConfig"
+ Given the file "testConfig.xml" exists at "/uiServices/test/samples"
+ And the header "path" is "/uiServices/test/samples"
+ And the file name is "testConfig.xml"
+ When I send a "GET" request to "/configs/testConfig"
Then the response code should be 200
And the response body should match json:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost",
- "targetPort":"9191",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 1000,
- "allowablePeakMemoryVariance": 30,
- "allowableServiceResponseTimeVariance": 30,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 5000,
- "TPSFreq": 30,
- "rampUsers": 5,
- "rampDelay": 15
+ "apiName": "testConfig",
+ "targetHost": "localhost",
+ "targetPort": "8080",
+ "numIterations": 55,
+ "allowablePeakMemoryVariance": 12,
+ "allowableServiceResponseTimeVariance": 15,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": ".efreefef",
+ "concurrentUsers": 50,
+ "testSuite": "Default-1",
+ "memoryEndpoint": "/alt/debug/vars",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 15,
+ "rampDelay": 15,
+ "GBS": false,
+ "ReBaseMemory": false,
+ "ReBaseAll": false,
+ "ExecutionHost": "",
+ "ReportTemplateFile": ""
}
"""
Scenario: Unsuccessful retrieval of config file (File Not Found)
Given the automated performance ui server is available
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "GET" request to "/configs/xxx"
Then the response code should be 404
- ##################################
- ###### PUT REQUESTS ###########
- ##################################
+ ##################################
+ ###### PUT REQUESTS ###########
+ ##################################
Scenario: Unsuccessful update of config file with PUT request (No File Path)
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is ""
- When I send "PUT" request to "/configs/GodogConfig" with body:
- """
+ And the header "path" is ""
+ When I send "PUT" request to "/configs/ConfigSAMPLE" with body:
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost2",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost2",
+ "targetPort":"1001",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 400
Scenario: Unsuccessful update of config file with PUT request (Incorrect File Name)
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/configs/xxx" with body:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"1001",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 404
Scenario: Unsuccessful update of config file with PUT request (No File Name)
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/configs/" with body:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"1001",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 404
Scenario: Unsuccessful update of config file with PUT request (Missing Required Fields)
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
- When I send "PUT" request to "/configs/GodogConfig" with body:
- """
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/configs/ConfigSAMPLE" with body:
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "",
- "targetPort":"",
- "memoryEndpoint": ,
- "numIterations": ,
- "allowablePeakMemoryVariance": ,
- "allowableServiceResponseTimeVariance": ,
- "testCaseDir": "",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": ,
- "testSuite": "",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "",
+ "targetPort":"",
+ "memoryEndpoint": ,
+ "numIterations": ,
+ "allowablePeakMemoryVariance": ,
+ "allowableServiceResponseTimeVariance": ,
+ "testCaseDir": "",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": ,
+ "testSuite": "",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 400
Scenario: Successful update of config file with PUT request
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
- When I send "PUT" request to "/configs/GodogConfig" with body:
- """
+ Given there is no existing test file "ConfigSAMPLE.xml"
+ And the header "path" is "/uiServices/test"
+ When I send "POST" request to "/configs" with a body:
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost2",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost",
+ "targetPort":"9191",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 1000,
+ "allowablePeakMemoryVariance": 30,
+ "allowableServiceResponseTimeVariance": 30,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 5000,
+ "TPSFreq": 30,
+ "rampUsers": 5,
+ "rampDelay": 15
+ }
+ """
+ Then the response code should be 201
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/configs/ConfigSAMPLE" with body:
+ """
+ {
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost2",
+ "targetPort":"1001",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 204
And the response body should be empty
- When I send a "GET" request to "/configs/GodogConfig"
+ When I send a "GET" request to "/configs/ConfigSAMPLE"
And the updated file should match json:
- """
+ """
{
- "apiName": "GodogConfig",
- "targetHost": "localhost2",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "ConfigSAMPLE",
+ "targetHost": "localhost2",
+ "targetPort": "1001",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "memoryEndpoint": "/alt/debug/vars",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10,
+ "GBS": false,
+ "ReBaseMemory": false,
+ "ReBaseAll": false,
+ "ExecutionHost": "",
+ "ReportTemplateFile": ""
}
"""
Scenario: Successful update of config file with PUT request (Update API Name to not match Filename)
- Given the file "GodogConfig.xml" exists at "/uiServices/test/"
+ Given the file "ConfigSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "configPathDir" is "/uiServices/test/"
- When I send "PUT" request to "/configs/GodogConfig" with body:
- """
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/configs/ConfigSAMPLE" with body:
+ """
{
- "apiName": "GodogAPI",
- "targetHost": "localhost",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "newTest",
+ "targetHost": "localhost",
+ "targetPort":"1001",
+ "memoryEndpoint": "/alt/debug/vars",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10
}
"""
Then the response code should be 204
And the response body should be empty
- When I send a "GET" request to "/configs/GodogConfig"
+ When I send a "GET" request to "/configs/ConfigSAMPLE"
And the updated file should match json:
- """
+ """
{
- "apiName": "GodogAPI",
- "targetHost": "localhost",
- "targetPort":"1001",
- "memoryEndpoint": "/alt/debug/vars",
- "numIterations": 4000,
- "allowablePeakMemoryVariance": 50,
- "allowableServiceResponseTimeVariance": 50,
- "testCaseDir": "./definitions/testCases",
- "testSuiteDir": "./definitions/testSuites",
- "baseStatsOutputDir": "./envStats",
- "reportOutputDir": "./report",
- "concurrentUsers": 50,
- "testSuite": "Default-3",
- "requestDelay": 1000,
- "TPSFreq": 10,
- "rampUsers": 10,
- "rampDelay": 10
+ "apiName": "newTest",
+ "targetHost": "localhost",
+ "targetPort": "1001",
+ "numIterations": 4000,
+ "allowablePeakMemoryVariance": 50,
+ "allowableServiceResponseTimeVariance": 50,
+ "testCaseDir": "./definitions/testCases",
+ "testSuiteDir": "./definitions/testSuites",
+ "baseStatsOutputDir": "./envStats",
+ "reportOutputDir": "./report",
+ "concurrentUsers": 50,
+ "testSuite": "Default-3",
+ "memoryEndpoint": "/alt/debug/vars",
+ "requestDelay": 1000,
+ "TPSFreq": 10,
+ "rampUsers": 10,
+ "rampDelay": 10,
+ "GBS": false,
+ "ReBaseMemory": false,
+ "ReBaseAll": false,
+ "ExecutionHost": "",
+ "ReportTemplateFile": ""
}
"""
\ No newline at end of file
diff --git a/uiServices/test/godog_test.go b/uiServices/test/godog_test.go
index acd8dcc..e37469f 100644
--- a/uiServices/test/godog_test.go
+++ b/uiServices/test/godog_test.go
@@ -10,6 +10,7 @@ import (
"net/http"
"net/http/httptest"
"os"
+ "path/filepath"
"reflect"
"strings"
@@ -31,15 +32,13 @@ type apiFeature struct {
headerName string
}
-var suitDir = os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test"
-
func (a *apiFeature) resetResponse() {
a.client = &http.Client{}
a.resp = nil
}
func (a *apiFeature) iSendrequestTo(method, endpoint string) (err error) {
- response, err := makePostRequest(a.client, method, endpoint, "", "", "")
+ response, err := makeRequest(a.client, method, endpoint, "", "", "")
if err != nil {
return err
}
@@ -59,7 +58,8 @@ func (a *apiFeature) theResponseBodyShouldMatchJSON(body *gherkin.DocString) (er
var expectedConfig perfTestUtils.Config
var actualConfig perfTestUtils.Config
- file, _ := os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + a.filename)
+ file, _ :=
+ os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + "/" + a.filename + ".xml")
byteValue, err := ioutil.ReadAll(file)
xml.Unmarshal(byteValue, &expectedConfig)
@@ -76,7 +76,9 @@ func (a *apiFeature) theTestSuiteResponseBodyShouldMatchJSON(body *gherkin.DocSt
var expectedSuite testStrategies.TestSuite
var actualSuite testStrategies.TestSuite
- file, _ := os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + a.filename)
+ file, _ :=
+ os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + "/" + a.filename + ".xml")
+
byteValue, err := ioutil.ReadAll(file)
xml.Unmarshal(byteValue, &expectedSuite)
@@ -92,7 +94,6 @@ func (a *apiFeature) theTestSuiteResponseBodyShouldMatchJSON(body *gherkin.DocSt
func (a *apiFeature) theTestSuiteCollectionResponseBodyShouldMatchJSON(body *gherkin.DocString) (err error) {
var expectedSuite testStrategies.TestSuite
var actualSuite testStrategies.TestSuite
-
exp :=
`"""
[
@@ -211,15 +212,13 @@ func (a *apiFeature) theHeaderIs(name string, path string) error {
func (a *apiFeature) theConfigFileWasCreatedAtLocationDefinedByConfigsPathDir() error {
configsPathDir := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath
-
fileExists := services.FilePathExist(configsPathDir)
-
if !fileExists {
return fmt.Errorf("File Does Not Exist")
}
logrus.Println("File Exists")
- if !IsValidXml(a.requestbody, a.headerPath) {
+ if !IsValidXML(a.requestbody, a.headerPath) {
return fmt.Errorf("File is not a valid XML file")
}
logrus.Println("File is a valid XML file")
@@ -227,7 +226,7 @@ func (a *apiFeature) theConfigFileWasCreatedAtLocationDefinedByConfigsPathDir()
}
func (a *apiFeature) iSendRequestToWithABody(method, endpoint string, body *gherkin.DocString) error {
- response, err := makePostRequest(a.client, method, endpoint, body.Content, a.headerPath, a.headerName)
+ response, err := makeRequest(a.client, method, endpoint, body.Content, a.headerPath, a.headerName)
a.requestbody = body.Content
if err != nil {
return err
@@ -236,73 +235,17 @@ func (a *apiFeature) iSendRequestToWithABody(method, endpoint string, body *gher
return nil
}
-func makePostRequest(client *http.Client, method, endpoint, body string, headerPath string, headerName string) (*http.Response, error) {
-
- var reqBody io.Reader
- if body != "" {
- reqBody = strings.NewReader(body)
- }
-
- req, err := http.NewRequest(method, "http://localhost:9191"+endpoint, reqBody)
-
- if headerPath == "" {
- req.Header.Set(headerName, "")
- } else {
- req.Header.Set(headerName, fmt.Sprintf("%s/src/github.com/xtracdev/automated-perf-test/uiServices/test/", os.Getenv("GOPATH")))
- }
- if err != nil {
- return nil, err
- }
-
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
-
- return resp, nil
-}
-
-func FeatureContext(s *godog.Suite) {
- api := &apiFeature{}
-
- s.BeforeScenario(func(interface{}) {
-
- api.resetResponse()
-
- })
-
- s.Step(`^I send "(GET|POST|PUT|DELETE)" request to "([^"]*)"$`, api.iSendrequestTo)
- s.Step(`^the response code should be (\d+)$`, api.theResponseCodeShouldBe)
- s.Step(`^the header "([^"]*)" is "([^"]*)"$`, api.theHeaderIs)
- s.Step(`^the response body should match json:$`, api.theResponseBodyShouldMatchJSON)
- s.Step(`^the response body should be empty$`, api.theResponseBodyShouldBeEmpty)
- s.Step(`^the config file was created at location defined by configsPathDir$`, api.theConfigFileWasCreatedAtLocationDefinedByConfigsPathDir)
- s.Step(`^the automated performance ui server is available$`, theAutomatedPerformanceUiServerIsAvailable)
- s.Step(`^I send "([^"]*)" request to "([^"]*)" with a body:$`, api.iSendRequestToWithABody)
- s.Step(`^the file name is "([^"]*)"$`, api.theFileNameis)
- s.Step(`^I send a "([^"]*)" request to "([^"]*)"$`, api.iSendARequestTo)
- s.Step(`^the file "([^"]*)" exists at "([^"]*)"$`, theFileExistsAt)
- s.Step(`^I send "([^"]*)" request to "([^"]*)" with body:$`, api.iSendRequestToWithBody)
- s.Step(`^the updated file should match json:$`, api.theUpdatedFileShouldMatchJSON)
- s.Step(`^there is no existing test file "([^"]*)"$`, api.thereIsNoExistingTestFile)
- s.Step(`^the test suite response body should match json:$`, api.theTestSuiteResponseBodyShouldMatchJSON)
- s.Step(`^the test suite collection response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
- s.Step(`^the "([^"]*)" has been created at "([^"]*)"$`, createNewFile)
- s.Step(`^the test case collection response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
- s.Step(`^the test case response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
-}
-
func (a *apiFeature) thereIsNoExistingTestFile(file string) error {
os.Remove(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test/" + file)
return nil
}
-func theAutomatedPerformanceUiServerIsAvailable() error {
+func theAutomatedPerformanceUIServerIsAvailable() error {
go http.ListenAndServe(":9191", services.GetRouter())
return nil
}
-func IsValidXml(config string, header string) bool {
+func IsValidXML(config string, header string) bool {
file, err := os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + header)
if err != nil {
fmt.Println(err)
@@ -343,36 +286,23 @@ func (a *apiFeature) theFileNameis(filename string) error {
}
func (a *apiFeature) iSendARequestTo(method, endpoint string) error {
- response, err := makeGetRequest(a.client, method, endpoint, a.filename, a.headerPath, a.headerName)
+ response, err := makeRequest(a.client, method, endpoint, a.filename, a.headerPath, a.headerName)
if err != nil {
return err
}
-
+ // TODO this can be removed
+ pathSplit := strings.Split(endpoint, "/")
+ if len(pathSplit) >= 3 {
+ a.filename = pathSplit[2]
+ }
a.resp = response
return nil
}
-func makeGetRequest(client *http.Client, method, endpoint string, filename string, headerPath, headerName string) (*http.Response, error) {
- req, err := http.NewRequest(method, "http://localhost:9191"+endpoint, nil)
-
- if headerPath == "" {
- req.Header.Set(headerName, "")
- } else {
- req.Header.Set(headerName, fmt.Sprintf("%s/src/github.com/xtracdev/automated-perf-test/uiServices/test/", os.Getenv("GOPATH")))
- }
- if err != nil {
- return nil, err
- }
-
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
+func theFileExistsAt(filename, path string) error {
- return resp, nil
-}
+ os.Create(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + path + filename)
-func theFileExistsAt(filename, path string) error {
_, err := os.Stat(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + path + filename)
if err != nil {
fmt.Println("Error. File Not Found at location : " + path + filename)
@@ -382,7 +312,7 @@ func theFileExistsAt(filename, path string) error {
}
func (a *apiFeature) iSendRequestToWithBody(method, endpoint string, body *gherkin.DocString) error {
- response, err := makePutRequest(a.client, method, endpoint, body.Content, a.headerPath, a.headerName)
+ response, err := makeRequest(a.client, method, endpoint, body.Content, a.headerPath, a.headerName)
a.requestbody = body.Content
if err != nil {
return err
@@ -391,7 +321,7 @@ func (a *apiFeature) iSendRequestToWithBody(method, endpoint string, body *gherk
return nil
}
-func makePutRequest(client *http.Client, method, endpoint, body string, headerPath, headerName string) (*http.Response, error) {
+func makeRequest(client *http.Client, method string, endpoint string, body string, headerPath string, headerName string) (*http.Response, error) {
var reqBody io.Reader
if body != "" {
@@ -403,7 +333,7 @@ func makePutRequest(client *http.Client, method, endpoint, body string, headerPa
if headerPath == "" {
req.Header.Set(headerName, "")
} else {
- req.Header.Set(headerName, fmt.Sprintf("%s/src/github.com/xtracdev/automated-perf-test/uiServices/test/", os.Getenv("GOPATH")))
+ req.Header.Set(headerName, fmt.Sprintf("%s/src/github.com/xtracdev/automated-perf-test/%s", os.Getenv("GOPATH"), headerPath))
}
if err != nil {
return nil, err
@@ -421,7 +351,8 @@ func (a *apiFeature) theUpdatedFileShouldMatchJSON(body *gherkin.DocString) (err
var expectedConfig perfTestUtils.Config
var actualConfig perfTestUtils.Config
- file, _ := os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + a.filename)
+ file, _ :=
+ os.Open(os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test" + a.headerPath + a.filename + ".xml")
byteValue, err := ioutil.ReadAll(file)
xml.Unmarshal(byteValue, &expectedConfig)
@@ -434,12 +365,57 @@ func (a *apiFeature) theUpdatedFileShouldMatchJSON(body *gherkin.DocString) (err
return nil
}
-func createNewFile(fileName, path string) error {
+func FeatureContext(s *godog.Suite) {
+ api := &apiFeature{}
- err := ioutil.WriteFile(fmt.Sprintf("%s%s/%s", suitDir, path, fileName), nil, 0666)
- if err != nil {
- logrus.Error(" error creating file ", err)
- return err
- }
- return err
+ s.AfterScenario(func(interface{}, error) {
+ dirname := os.Getenv("GOPATH") + "/src/github.com/xtracdev/automated-perf-test/uiServices/test"
+
+ d, err := os.Open(dirname)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+ defer d.Close()
+
+ files, err := d.Readdir(-1)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ fmt.Println("Reading " + dirname)
+
+ for _, file := range files {
+ if file.Mode().IsRegular() {
+ if filepath.Ext(file.Name()) == ".xml" {
+ os.Remove(file.Name())
+ fmt.Println("Deleted ", file.Name())
+ }
+ }
+ }
+ })
+
+ s.BeforeScenario(func(interface{}) {
+ api.resetResponse()
+ })
+
+ s.Step(`^I send "(GET|POST|PUT|DELETE)" request to "([^"]*)"$`, api.iSendrequestTo)
+ s.Step(`^the response code should be (\d+)$`, api.theResponseCodeShouldBe)
+ s.Step(`^the header "([^"]*)" is "([^"]*)"$`, api.theHeaderIs)
+ s.Step(`^the response body should match json:$`, api.theResponseBodyShouldMatchJSON)
+ s.Step(`^the response body should be empty$`, api.theResponseBodyShouldBeEmpty)
+ s.Step(`^the config file was created at location defined by path`, api.theConfigFileWasCreatedAtLocationDefinedByConfigsPathDir)
+ s.Step(`^the automated performance ui server is available$`, theAutomatedPerformanceUIServerIsAvailable)
+ s.Step(`^I send "([^"]*)" request to "([^"]*)" with a body:$`, api.iSendRequestToWithABody)
+ s.Step(`^the file name is "([^"]*)"$`, api.theFileNameis)
+ s.Step(`^I send a "([^"]*)" request to "([^"]*)"$`, api.iSendARequestTo)
+ s.Step(`^the file "([^"]*)" exists at "([^"]*)"$`, theFileExistsAt)
+ s.Step(`^I send "([^"]*)" request to "([^"]*)" with body:$`, api.iSendRequestToWithBody)
+ s.Step(`^the updated file should match json:$`, api.theUpdatedFileShouldMatchJSON)
+ s.Step(`^there is no existing test file "([^"]*)"$`, api.thereIsNoExistingTestFile)
+ s.Step(`^the test suite response body should match json:$`, api.theTestSuiteResponseBodyShouldMatchJSON)
+ s.Step(`^the test suite collection response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
+ s.Step(`^the test case collection response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
+ s.Step(`^the test case response body should match json:$`, api.theTestSuiteCollectionResponseBodyShouldMatchJSON)
}
diff --git a/uiServices/test/samples/TestCaseSAMPLE.xml b/uiServices/test/samples/TestCaseSAMPLE.xml
new file mode 100644
index 0000000..e69de29
diff --git a/uiServices/test/samples/testCase.json b/uiServices/test/samples/testCase.json
new file mode 100644
index 0000000..e69de29
diff --git a/uiServices/test/samples/testCase.xml b/uiServices/test/samples/testCase.xml
new file mode 100644
index 0000000..89fda5b
--- /dev/null
+++ b/uiServices/test/samples/testCase.xml
@@ -0,0 +1,22 @@
+
+ testCase
+ host
+ x
+ GET
+ desciiii
+ path/to/URI
+ false
+ payload
+
+ 200
+ ccccc
+
+
+
+
+ Res-Valueeee
+
+ 55
+ 0
+ Infrequent
+
\ No newline at end of file
diff --git a/uiServices/test/samples/testConfig.xml b/uiServices/test/samples/testConfig.xml
new file mode 100644
index 0000000..39e8b9c
--- /dev/null
+++ b/uiServices/test/samples/testConfig.xml
@@ -0,0 +1,19 @@
+
+ testConfig
+ localhost
+ 8080
+ 55
+ 12
+ 15
+ ./definitions/testCases
+ ./definitions/testSuites
+ ./envStats
+ .efreefef
+ 50
+ Default-1
+ /alt/debug/vars
+ 5000
+ 30
+ 15
+ 15
+
\ No newline at end of file
diff --git a/uiServices/test/samples/testSuite.json b/uiServices/test/samples/testSuite.json
new file mode 100644
index 0000000..e69de29
diff --git a/uiServices/test/samples/testSuite.xml b/uiServices/test/samples/testSuite.xml
new file mode 100644
index 0000000..cbf9494
--- /dev/null
+++ b/uiServices/test/samples/testSuite.xml
@@ -0,0 +1,7 @@
+
+ testSuite
+ Services for XYZrrr
+ SuiteBased
+
+
+
\ No newline at end of file
diff --git a/uiServices/test/testCase.feature b/uiServices/test/testCase.feature
index 771bdcf..dcff5bc 100644
--- a/uiServices/test/testCase.feature
+++ b/uiServices/test/testCase.feature
@@ -9,18 +9,18 @@ Feature: Test Case Scenarios
###################################
Scenario: Successful creation of Test Case
- Given there is no existing test file "GodogTestCase.xml"
+ Given there is no existing test file "TestCaseSAMPLE.xml"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test"
When I send "POST" request to "/test-cases" with a body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
"httpMethod":"GET",
- "baseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -48,16 +48,49 @@ Feature: Test Case Scenarios
Scenario: Unsuccessful creation of Test Case (file already exists )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test"
When I send "POST" request to "/test-cases" with a body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
"httpMethod":"GET",
- "baseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
+ "multipart":false,
+ "payload": "payload",
+ "responseStatusCode":200,
+ "responseContentType": "JSON" ,
+ "preThinkTime": 1000,
+ "postThinkTime":2000,
+ "execWeight": "Sparse",
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
+ }],
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
+ }],
+ "multipartPayload":[{
+ "fieldName": "F-Name",
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
+ }]
+ }
+ """
+ Then the response code should be 201
+ And the header "path" is "/uiServices/test/"
+ When I send "POST" request to "/test-cases" with a body:
+ """
+ {
+ "testname":"TestCaseSAMPLE",
+ "description":"desc",
+ "overrideHost":"host",
+ "overridePort":"9191",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -85,16 +118,16 @@ Feature: Test Case Scenarios
Scenario: Unsuccessful creation of test Case ( Missing Required Fields )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-suites" with a body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -102,18 +135,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
- "FieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "multipartPayload":[{
+ "fieldName": "F-Name",
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
"""
@@ -122,16 +155,16 @@ Feature: Test Case Scenarios
Scenario: Unsuccessful creation of Test Case ( No header defined )
Given the automated performance ui server is available
- And the header "testCasePathDir" is ""
+ And the header "path" is ""
When I send "POST" request to "/test-cases" with a body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
"HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -139,18 +172,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
+ "headers":[{
"Key": "Authorization",
"Value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
- "FieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "multipartPayload":[{
+ "fieldName": "F-Name",
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
"""
@@ -163,18 +196,18 @@ Feature: Test Case Scenarios
###################################
Scenario: Unsuccessful update of test-case file with PUT request (No File Path)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is ""
+ And the header "path" is ""
When I send "PUT" request to "/test-suites/GodogTestSuite" with body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -182,18 +215,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
- "fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "multipartPayload":[{
+ "fieldName": "F-Name",
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
@@ -202,18 +235,18 @@ Feature: Test Case Scenarios
Scenario: Unsuccessful update of test-case file with PUT request (Incorrect File Name)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/test-cases/xxx" with body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
"HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -221,18 +254,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
@@ -241,18 +274,18 @@ Feature: Test Case Scenarios
Scenario: Unsuccessful update of test-case file with PUT request (No File Name)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/test-suites/" with body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
- "HttpMethod":"GET",
- "BaseURI": "path/to/URI",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -260,18 +293,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
@@ -279,17 +312,17 @@ Feature: Test Case Scenarios
Then the response code should be 404
Scenario: Unsuccessful update of test-suite file with PUT request (Missing Required Fields)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send "PUT" request to "/test-suites/GodogTestCase" with body:
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/test-suites/TestCaseSAMPLE" with body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"",
"overridePort":"",
- "HttpMethod":"",
- "BaseURI": "path/to/URI",
+ "httpMethod":"",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -297,18 +330,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
@@ -317,18 +350,18 @@ Feature: Test Case Scenarios
Scenario: Successful update of test-case file with PUT request
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send "PUT" request to "/test-cases/GodogTestCase" with body:
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/test-cases/TestCaseSAMPLE" with body:
"""
{
- "testname":"GodogTestCase",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"1001",
- "HttpMethod":"POST",
- "BaseURI": "path/to/URI",
+ "httpMethod":"POST",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -336,18 +369,18 @@ Feature: Test Case Scenarios
"preThinkTime": 1000,
"postThinkTime":2000,
"execWeight": "Sparse",
- "Headers":[{
- "Key": "Authorization",
- "Value" :"Header-Value"
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
}],
- "ResponseValues":[{
- "Value":"Res-Value",
- "ExtractionKey": "Res-Key"
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
}],
- "MultipartPayload":[{
+ "multipartPayload":[{
"fieldName": "F-Name",
- "FieldValue":"PayloadName",
- "FileName": "file-name"
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
}]
}
@@ -361,18 +394,18 @@ Feature: Test Case Scenarios
###################################
Scenario: Successful retrieval all test cases with valid "GET" request
##Add additional file first so there are multiple files to GET
- Given there is no existing test file "GodogTestCase2.xml"
+ Given there is no existing test file "TestCaseSAMPLE2.xml"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-cases" with a body:
"""
{
- "testname":"GodogTestCase2",
+ "testname":"TestCaseSAMPLE2",
"description":"desc2",
"overrideHost":"host",
"overridePort":"9191",
"httpMethod":"PUT",
- "baseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -398,19 +431,19 @@ Feature: Test Case Scenarios
Then the response code should be 201
And the response body should be empty
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "GET" request to "/test-cases"
Then the response code should be 200
And the test case collection response body should match json:
"""
[
{
- "name": "GodogTestCase,
+ "name": "TestCaseSAMPLE,
"description": "Case Desc",
"httpMethod": "GET"
},
{
- "name": "GodogTestCase2,
+ "name": "TestCaseSAMPLE2,
"description": "Case Desc2",
"httpMethod": "PUT"
}
@@ -418,99 +451,127 @@ Feature: Test Case Scenarios
"""
-
Scenario: Unsuccessful retrieval of test-cases (No Header)
Given the automated performance ui server is available
- And the header "testSuitePathDir" is ""
+ And the header "path" is ""
When I send a "GET" request to "/test-cases"
Then the response code should be 400
-
-
-
###################################
####### GET REQUESTS #######
###################################
Scenario: Unsuccessful retrieval of test-Cases file (File Not Found)
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "GET" request to "/test-cases/xxx"
Then the response code should be 404
Scenario: Unsuccessful retrieval of test-suites file (No Header)
Given the automated performance ui server is available
- And the header "testCasePathDir" is ""
- When I send a "GET" request to "/test-suites/GodogTestCase"
+ And the header "path" is ""
+ When I send a "GET" request to "/test-suites/TestCaseSAMPLE"
Then the response code should be 400
Scenario: Retrieve Test Case file with valid "GET" request
- Given the file "GodogTestCase2.xml" exists at "/uiServices/test/"
+ Given there is no existing test file "TestCaseSAMPLE.xml"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- And the file name is "Case1.xml"
- When I send a "GET" request to "/test-cases/GodogTestCase2"
+ And the header "path" is "/uiServices/test"
+ When I send "POST" request to "/test-cases" with a body:
+ """
+ {
+ "testname":"TestCaseSAMPLE",
+ "description":"desc",
+ "overrideHost":"host",
+ "overridePort":"9191",
+ "httpMethod":"GET",
+ "baseUri": "path/to/URI",
+ "multipart":false,
+ "payload": "payload",
+ "responseStatusCode":200,
+ "responseContentType": "JSON" ,
+ "preThinkTime": 1000,
+ "postThinkTime":2000,
+ "execWeight": "Sparse",
+ "headers":[{
+ "key": "Authorization",
+ "value" :"Header-Value"
+ }],
+ "responseValues":[{
+ "value":"Res-Value",
+ "extractionKey": "Res-Key"
+ }],
+ "multipartPayload":[{
+ "fieldName": "F-Name",
+ "fieldValue":"PayloadName",
+ "fileName": "file-name"
+ }]
+ }
+ """
+ Then the response code should be 201
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/samples/"
+ Given the automated performance ui server is available
+ And the header "path" is "/uiServices/test/samples/"
+ And the file name is "TestCaseSAMPLE.xml"
+ When I send a "GET" request to "/test-cases/testCase"
Then the response code should be 200
And the test case response body should match json:
"""
{
- "XMLName": {
- "Space": "",
- "Local": "testDefinition"
- },
- "TestName": GodogTestCase",
+ "TestName": TestCaseSAMPLE",
"OverrideHost": "host",
"OverridePort": "9191",
"HTTPMethod": "GET",
"Description": "desc",
- "BaseURI": "",
+ "baseUri": "",
"Multipart": false,
"Payload": "",
"MultipartPayload": null,
"ResponseStatusCode": 0,
"ResponseContentType": "",
- "Headers": null,
- "ResponseValues": null,
+ "headers": null,
+ "responseValues": null,
"PreThinkTime": 0,
"PostThinkTime": 0,
"ExecWeight": ""
}
"""
-
- ###################################
- ####### DELETE REQUESTS #######
###################################
+ ####### DELETE REQUESTS ########
+ ###################################
+
+
Scenario: Fail to remove Test Case file with "DELETE" request (File Not Found)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "DELETE" request to "/test-cases/xxxx"
Then the response code should be 404
Scenario: Fail to remove Test Case file with "DELETE" request (No Header)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is ""
+ And the header "path" is ""
When I send a "DELETE" request to "/test-cases/xxxx"
Then the response code should be 400
Scenario: Successful removal Test Case file with "DELETE" request
#create file to delete
- Given there is no existing test file "GodogTestCase3.xml"
+ Given there is no existing test file "TestCaseSAMPLE.xml"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-cases" with a body:
"""
{
- "testname":"GodogTestCase3",
+ "testname":"TestCaseSAMPLE",
"description":"desc",
"overrideHost":"host",
"overridePort":"9191",
"httpMethod":"GET",
- "baseURI": "path/to/URI",
+ "baseUri": "path/to/URI",
"multipart":false,
"payload": "payload",
"responseStatusCode":200,
@@ -535,9 +596,30 @@ Feature: Test Case Scenarios
"""
Then the response code should be 201
#Delete
- Given the file "GodogTestCase3.xml" exists at "/uiServices/test/"
+ Given the file "TestCaseSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send a "DELETE" request to "/test-cases/GodogTestCase3"
+ And the header "path" is "/uiServices/test/"
+ When I send a "DELETE" request to "/test-cases/TestCaseSAMPLE"
Then the response code should be 204
+
+Scenario: Unsuccessful deleting of test-case (No Header)
+ Given the automated performance ui server is available
+ And the header "path" is ""
+ When I send a "DELETE" request to "/test-cases"
+ Then the response code should be 400
+
+
+Scenario: Unsuccessful deleting of test-case file (Empty Directory)
+ Given the automated performance ui server is available
+ And the header "path" is "/uiServices/test/cases"
+ When I send a "DELETE" request to "/test-cases/"
+ Then the response code should be 404
+
+
+Scenario: Successful deleting of test-case file with DELETE request
+ Given the file "deleteTest.xml" exists at "/uiServices/test/cases"
+ Given the automated performance ui server is available
+ And the header "path" is "/uiServices/test/cases"
+ When I send a "DELETE" request to "/test-cases"
+ Then the response code should be 200
\ No newline at end of file
diff --git a/uiServices/test/testSuite.feature b/uiServices/test/testSuite.feature
index 0fd6478..e540e4c 100644
--- a/uiServices/test/testSuite.feature
+++ b/uiServices/test/testSuite.feature
@@ -8,13 +8,13 @@ Feature: Test Suite Creation
###################################
Scenario: Successful creation of test Suite
- Given there is no existing test file "GodogTestSuite.xml"
+ Given there is no existing test file "TestSuiteSAMPLE.xml"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-suites" with a body:
"""
{
- "name": "GodogTestSuite",
+ "name": "TestSuiteSAMPLE",
"testStrategy": "SuiteBased",
"description": "Services for XYZ",
"testCases":[
@@ -32,11 +32,30 @@ Feature: Test Suite Creation
Scenario: Unsuccessful creation of test Suite (file already exists )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ Given there is no existing test file "TestSuiteSAMPLE.xml"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-suites" with a body:
"""
{
- "name": "GodogTestSuite",
+ "name": "TestSuiteSAMPLE",
+ "testStrategy": "SuiteBased",
+ "description": "Services for XYZ",
+ "testCases":[
+ {
+ "name":"file1",
+ "preThinkTime": 1000,
+ "postThinkTime": 2000,
+ "execWeight": "Infrequent"
+ }
+ ]
+ }
+ """
+ Then the response code should be 201
+ And the header "path" is "/uiServices/test/"
+ When I send "POST" request to "/test-suites" with a body:
+ """
+ {
+ "name": "TestSuiteSAMPLE",
"testStrategy": "SuiteBased",
"description": "Services for XYZ",
"testCases":[
@@ -60,7 +79,7 @@ Feature: Test Suite Creation
Scenario: Unsuccessful creation of test Suite ( Missing Required Fields )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "POST" request to "/test-suites" with a body:
"""
{
@@ -79,11 +98,11 @@ Feature: Test Suite Creation
Scenario: Unsuccessful creation of test Suite ( No header defined )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is ""
+ And the header "path" is ""
When I send "POST" request to "/test-suites" with a body:
"""
{
- "name": "GodogTestSuite",
+ "name": "TestSuiteSAMPLE",
"testStrategy": "SuiteBased",
"description": "Services for XYZ",
"testCases":[
@@ -101,11 +120,11 @@ Feature: Test Suite Creation
Scenario: Unsuccessful creation of test Suite ( Incorrect URL )
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/GodogTestSuite.xml"
+ And the header "path" is "/uiServices/test/TestSuiteSAMPLE.xml"
When I send "POST" request to "/xxxx" with a body:
"""
{
- "name": "GodogTestSuite",
+ "name": "TestSuiteSAMPLE",
"testStrategy": "SuiteBased",
"description": "Services for XYZ",
"testCases":[
@@ -122,7 +141,7 @@ Feature: Test Suite Creation
Scenario: Unsuccessful creation of test Suite(No Name defined)
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/GodogTestSuite.xml"
+ And the header "path" is "/uiServices/test/TestSuiteSAMPLE.xml"
When I send "POST" request to "/test-suites" with a body:
"""
{
@@ -147,13 +166,13 @@ Feature: Test Suite Creation
###################################
Scenario: Unsuccessful update of test-suite file with PUT request (No File Path)
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is ""
- When I send "PUT" request to "/test-suites/GodogTestSuite" with body:
+ And the header "path" is ""
+ When I send "PUT" request to "/test-suites/TestSuiteSAMPLE" with body:
"""
{
- "name": "GodogTestSuite",
+ "name": "TestSuiteSAMPLE",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -170,13 +189,13 @@ Feature: Test Suite Creation
Scenario: Unsuccessful update of test-suite file with PUT request (Incorrect File Name)
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/test-suites/xxx" with body:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -193,13 +212,13 @@ Feature: Test Suite Creation
Scenario: Unsuccessful update of test-suite file with PUT request (No File Name)
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send "PUT" request to "/test-suites/" with body:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -215,10 +234,10 @@ Feature: Test Suite Creation
Then the response code should be 404
Scenario: Unsuccessful update of test-suite file with PUT request (Missing Required Fields)
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
- When I send "PUT" request to "/test-suites/GodogTestSuite" with body:
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/test-suites/TestSuiteSAMPLE" with body:
"""
{
"testCases":[
@@ -235,13 +254,13 @@ Feature: Test Suite Creation
Scenario: Successful update of test-suite file with PUT request
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
- When I send "PUT" request to "/test-suites/GodogTestSuite" with body:
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/test-suites/TestSuiteSAMPLE" with body:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -256,11 +275,11 @@ Feature: Test Suite Creation
"""
Then the response code should be 204
And the response body should be empty
- When I send a "GET" request to "/test-suites/GodogTestSuite"
+ When I send a "GET" request to "/test-suites/TestSuiteSAMPLE"
And the updated file should match json:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -274,13 +293,13 @@ Feature: Test Suite Creation
}
"""
Scenario: Successful update of test-suite file with PUT request (Update API Name to not match Filename)
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
- When I send "PUT" request to "/test-suites/GodogTestSuite" with body:
+ And the header "path" is "/uiServices/test/"
+ When I send "PUT" request to "/test-suites/TestSuiteSAMPLE" with body:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -295,11 +314,11 @@ Feature: Test Suite Creation
"""
Then the response code should be 204
And the response body should be empty
- When I send a "GET" request to "/test-suites/GodogTestSuite"
+ When I send a "GET" request to "/test-suites/TestSuiteSAMPLE"
And the updated file should match json:
"""
{
- "name": "GodogTestSuite2",
+ "name": "TestSuiteSAMPLE2",
"testStrategy": "SuiteBased",
"description": "ServiceDesc",
"testCases":[
@@ -320,52 +339,39 @@ Feature: Test Suite Creation
###################################
Scenario: Try to retrieve test-suite file with valid "GET" request
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
- And the file name is "GodogTestSuite.xml"
- When I send a "GET" request to "/test-suites/GodogTestSuite"
+ Given the file "testSuite.xml" exists at "/uiServices/test/samples"
+ And the header "path" is "/uiServices/test/samples"
+ And the file name is "testSuite.xml"
+ When I send a "GET" request to "/test-suites/testSuite"
Then the response code should be 200
And the test suite response body should match json:
"""
- {
- "XMLName": {
- "Space": "",
- "Local": "testSuite"
- },
- "name": "GodogTestSuite2",
- "description": "ServiceDesc",
- "testStrategy": "SuiteBased",
- "testCases": [
- {
- "testCase": {
- "Space": "",
- "Local": "testCase"
- },
- "Name": "file1",
- "preThinkTime": 2000,
- "postThinkTime": 5000,
- "execWeight": "Infrequent"
- }
- ],
- "TestDefinitions": null
- }
+ {
+ "XMLName": {
+ "Space": "",
+ "Local": "testSuite"
+ },
+ "name": "testSuite",
+ "description": "Services for XYZrrr",
+ "testStrategy": "SuiteBased"
+ }
"""
Scenario: Unsuccessful retrieval of test-suites file (File Not Found)
Given the automated performance ui server is available
- Given the file "GodogTestSuite.xml" exists at "/uiServices/test/"
+ Given the file "TestSuiteSAMPLE.xml" exists at "/uiServices/test/"
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "GET" request to "/test-suites/xxx"
Then the response code should be 404
Scenario: Unsuccessful retrieval of test-suites file (No Header)
Given the automated performance ui server is available
- And the header "testSuitePathDir" is ""
- When I send a "GET" request to "/test-suites/GodogTestSuite"
+ And the header "path" is ""
+ When I send a "GET" request to "/test-suites/TestSuiteSAMPLE"
Then the response code should be 400
@@ -375,15 +381,15 @@ Feature: Test Suite Creation
Scenario: Try to retrieve all test suites with valid "GET" request
Given the automated performance ui server is available
- And the header "testSuitePathDir" is "/uiServices/test/"
+ And the header "path" is "/uiServices/test/"
When I send a "GET" request to "/test-suites"
Then the response code should be 200
And the test suite collection response body should match json:
"""
[
{
- "file": "GodogTestSuite.xml",
- "name": "GodogTestSuite2,
+ "file": "TestSuiteSAMPLE.xml",
+ "name": "TestSuiteSAMPLE2,
"description": "ServiceDesc",
}
]
@@ -392,71 +398,6 @@ Feature: Test Suite Creation
Scenario: Unsuccessful retrieval of test-suites (No Header)
Given the automated performance ui server is available
- And the header "testSuitePathDir" is ""
+ And the header "path" is ""
When I send a "GET" request to "/test-suites"
- Then the response code should be 400
-
-
-
- ###################################
- ####### DELETE REQUESTS ########
- ###################################
-
- Scenario: Fail to remove Test Case file with "DELETE" request (File Not Found)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
- Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send a "DELETE" request to "/test-cases/xxxx"
- Then the response code should be 404
-
- Scenario: Fail to remove Test Case file with "DELETE" request (No Header)
- Given the file "GodogTestCase.xml" exists at "/uiServices/test/"
- Given the automated performance ui server is available
- And the header "testCasePathDir" is ""
- When I send a "DELETE" request to "/test-cases/xxxx"
- Then the response code should be 400
-
- Scenario: Successful removal Test Case file with "DELETE" request
- #create file to delete
- Given there is no existing test file "GodogTestCase3.xml"
- Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send "POST" request to "/test-cases" with a body:
- """
- {
- "testname":"GodogTestCase3",
- "description":"desc",
- "overrideHost":"host",
- "overridePort":"9191",
- "httpMethod":"GET",
- "baseURI": "path/to/URI",
- "multipart":false,
- "payload": "payload",
- "responseStatusCode":200,
- "responseContentType": "JSON" ,
- "preThinkTime": 1000,
- "postThinkTime":2000,
- "execWeight": "Sparse",
- "headers":[{
- "key": "Authorization",
- "value" :"Header-Value"
- }],
- "responseValues":[{
- "value":"Res-Value",
- "extractionKey": "Res-Key"
- }],
- "multipartPayload":[{
- "fieldName": "F-Name",
- "fieldValue":"PayloadName",
- "fileName": "file-name"
- }]
- }
- """
- Then the response code should be 201
- #Delete
- Given the file "GodogTestCase3.xml" exists at "/uiServices/test/"
- Given the automated performance ui server is available
- And the header "testCasePathDir" is "/uiServices/test/"
- When I send a "DELETE" request to "/test-cases/GodogTestCase3"
- Then the response code should be 204
-
+ Then the response code should be 400
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..da9527e
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,844 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+ajv@^5.2.3:
+ version "5.5.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
+ dependencies:
+ co "^4.6.0"
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+argparse@^1.0.7:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+ dependencies:
+ sprintf-js "~1.0.2"
+
+asap@~2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+
+asn1@0.1.11:
+ version "0.1.11"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7"
+
+asn1@~0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
+
+assert-plus@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+async@~0.9.0:
+ version "0.9.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63"
+
+aws-sign2@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+babel-runtime@^6.11.6:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.11.0"
+
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+ dependencies:
+ tweetnacl "^0.14.3"
+
+bl@~0.9.0:
+ version "0.9.5"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-0.9.5.tgz#c06b797af085ea00bc527afc8efcf11de2232054"
+ dependencies:
+ readable-stream "~1.0.26"
+
+boom@0.4.x:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-0.4.2.tgz#7a636e9ded4efcefb19cef4947a3c67dfaee911b"
+ dependencies:
+ hoek "0.9.x"
+
+boom@2.x.x:
+ version "2.10.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+ dependencies:
+ hoek "2.x.x"
+
+caseless@~0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
+
+caseless@~0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.6.0.tgz#8167c1ab8397fb5bb95f96d28e5a81c50f247ac4"
+
+chain-function@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
+
+chalk@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+classnames@^2.2.5:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
+
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+codecov.io@^0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/codecov.io/-/codecov.io-0.1.6.tgz#59dfd02da1ff31c2fb2b952ad8ad16fd3781b728"
+ dependencies:
+ request "2.42.0"
+ urlgrey "0.4.0"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
+ dependencies:
+ delayed-stream "~1.0.0"
+
+combined-stream@~0.0.4:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-0.0.7.tgz#0137e657baa5a7541c57ac37ac5fc07d73b4dc1f"
+ dependencies:
+ delayed-stream "0.0.5"
+
+commander@^2.9.0:
+ version "2.14.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
+
+core-js@^1.0.0:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
+
+core-js@^2.4.0:
+ version "2.5.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
+
+core-util-is@1.0.2, core-util-is@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+coveralls@^2.11.16:
+ version "2.13.3"
+ resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.3.tgz#9ad7c2ae527417f361e8b626483f48ee92dd2bc7"
+ dependencies:
+ js-yaml "3.6.1"
+ lcov-parse "0.0.10"
+ log-driver "1.2.5"
+ minimist "1.2.0"
+ request "2.79.0"
+
+cryptiles@0.2.x:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c"
+ dependencies:
+ boom "0.4.x"
+
+cryptiles@2.x.x:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+ dependencies:
+ boom "2.x.x"
+
+ctype@0.5.3:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f"
+
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ dependencies:
+ assert-plus "^1.0.0"
+
+deep-equal@~0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.1.2.tgz#b246c2b80a570a47c11be1d9bd1070ec878b87ce"
+
+defined@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/defined/-/defined-0.0.0.tgz#f35eea7d705e933baf13b2f03b3f83d921403b3e"
+
+delayed-stream@0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-0.0.5.tgz#d4b1f43a93e8296dfe02694f4680bc37a313c73f"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+dom-helpers@^3.2.0, dom-helpers@^3.2.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
+
+duplexer@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
+
+ecc-jsbn@~0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+ dependencies:
+ jsbn "~0.1.0"
+
+encoding@^0.1.11:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
+ dependencies:
+ iconv-lite "~0.4.13"
+
+escape-string-regexp@^1.0.2:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+esprima@^2.6.0:
+ version "2.7.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+
+extend@~3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+extsprintf@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+
+extsprintf@^1.2.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+
+fast-deep-equal@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
+
+fast-json-stable-stringify@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+
+fbjs@^0.8.16:
+ version "0.8.16"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
+ dependencies:
+ core-js "^1.0.0"
+ isomorphic-fetch "^2.1.1"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.9"
+
+forever-agent@~0.5.0:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~0.1.0:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12"
+ dependencies:
+ async "~0.9.0"
+ combined-stream "~0.0.4"
+ mime "~1.2.11"
+
+form-data@~2.1.1:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
+
+generate-function@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
+
+generate-object-property@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
+ dependencies:
+ is-property "^1.0.0"
+
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ dependencies:
+ assert-plus "^1.0.0"
+
+har-validator@~2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
+ dependencies:
+ chalk "^1.1.1"
+ commander "^2.9.0"
+ is-my-json-valid "^2.12.4"
+ pinkie-promise "^2.0.0"
+
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+hawk@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-1.1.1.tgz#87cd491f9b46e4e2aeaca335416766885d2d1ed9"
+ dependencies:
+ boom "0.4.x"
+ cryptiles "0.2.x"
+ hoek "0.9.x"
+ sntp "0.2.x"
+
+hawk@~3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+ dependencies:
+ boom "2.x.x"
+ cryptiles "2.x.x"
+ hoek "2.x.x"
+ sntp "1.x.x"
+
+hoek@0.9.x:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505"
+
+hoek@2.x.x:
+ version "2.16.3"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+http-signature@~0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.10.1.tgz#4fbdac132559aa8323121e540779c0a012b27e66"
+ dependencies:
+ asn1 "0.1.11"
+ assert-plus "^0.1.5"
+ ctype "0.5.3"
+
+http-signature@~1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+ dependencies:
+ assert-plus "^0.2.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
+iconv-lite@~0.4.13:
+ version "0.4.19"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
+
+inherits@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+invariant@^2.1.0, invariant@^2.2.1:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688"
+ dependencies:
+ loose-envify "^1.0.0"
+
+is-my-ip-valid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824"
+
+is-my-json-valid@^2.12.4:
+ version "2.17.2"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz#6b2103a288e94ef3de5cf15d29dd85fc4b78d65c"
+ dependencies:
+ generate-function "^2.0.0"
+ generate-object-property "^1.1.0"
+ is-my-ip-valid "^1.0.0"
+ jsonpointer "^4.0.0"
+ xtend "^4.0.0"
+
+is-property@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+
+is-stream@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+
+isomorphic-fetch@^2.1.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
+ dependencies:
+ node-fetch "^1.0.1"
+ whatwg-fetch ">=0.10.0"
+
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+js-tokens@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+
+js-yaml@3.6.1:
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30"
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^2.6.0"
+
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+json-schema-traverse@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+jsonify@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsonpointer@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+
+jsprim@^1.2.2:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.3.0"
+ json-schema "0.2.3"
+ verror "1.10.0"
+
+keycode@^2.1.2:
+ version "2.1.9"
+ resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.9.tgz#964a23c54e4889405b4861a5c9f0480d45141dfa"
+
+lcov-parse@0.0.10:
+ version "0.0.10"
+ resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3"
+
+lodash.topath@^4.5.2:
+ version "4.5.2"
+ resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009"
+
+log-driver@1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
+
+loose-envify@^1.0.0, loose-envify@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+ dependencies:
+ js-tokens "^3.0.0"
+
+mime-db@~1.33.0:
+ version "1.33.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
+
+mime-types@^2.1.12, mime-types@~2.1.7:
+ version "2.1.18"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
+ dependencies:
+ mime-db "~1.33.0"
+
+mime-types@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce"
+
+mime@~1.2.11:
+ version "1.2.11"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10"
+
+minimist@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+node-fetch@^1.0.1:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
+ dependencies:
+ encoding "^0.1.11"
+ is-stream "^1.0.1"
+
+node-uuid@~1.4.0:
+ version "1.4.8"
+ resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
+
+oauth-sign@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.4.0.tgz#f22956f31ea7151a821e5f2fb32c113cad8b9f69"
+
+oauth-sign@~0.8.1:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4.1.0, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+pinkie-promise@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+ dependencies:
+ pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ dependencies:
+ asap "~2.0.3"
+
+prop-types-extra@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.0.1.tgz#a57bd4810e82d27a3ff4317ecc1b4ad005f79a82"
+ dependencies:
+ warning "^3.0.0"
+
+prop-types@^15.5.10, prop-types@^15.5.8:
+ version "15.6.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.3.1"
+ object-assign "^4.1.1"
+
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~1.2.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-1.2.2.tgz#19b57ff24dc2a99ce1f8bdf6afcda59f8ef61f88"
+
+qs@~6.3.0:
+ version "6.3.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c"
+
+"react-bootstrap@>= 0.30.7":
+ version "0.32.1"
+ resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-0.32.1.tgz#60624c1b48a39d773ef6cce6421a4f33ecc166bb"
+ dependencies:
+ babel-runtime "^6.11.6"
+ classnames "^2.2.5"
+ dom-helpers "^3.2.0"
+ invariant "^2.2.1"
+ keycode "^2.1.2"
+ prop-types "^15.5.10"
+ prop-types-extra "^1.0.1"
+ react-overlays "^0.8.0"
+ react-prop-types "^0.4.0"
+ react-transition-group "^2.0.0"
+ uncontrollable "^4.1.0"
+ warning "^3.0.0"
+
+react-jsonschema-form-layout-grid@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/react-jsonschema-form-layout-grid/-/react-jsonschema-form-layout-grid-2.1.0.tgz#1caf8d579aea2c22edcae9e8d89f46353187421b"
+ dependencies:
+ codecov.io "^0.1.6"
+ coveralls "^2.11.16"
+ react-bootstrap ">= 0.30.7"
+ react-jsonschema-form ">= 0.43.0"
+
+"react-jsonschema-form@>= 0.43.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/react-jsonschema-form/-/react-jsonschema-form-1.0.1.tgz#1b83ad5a71458100367c29bef68b5c38d65fbeab"
+ dependencies:
+ ajv "^5.2.3"
+ lodash.topath "^4.5.2"
+ prop-types "^15.5.8"
+ setimmediate "^1.0.5"
+
+react-overlays@^0.8.0:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5"
+ dependencies:
+ classnames "^2.2.5"
+ dom-helpers "^3.2.1"
+ prop-types "^15.5.10"
+ prop-types-extra "^1.0.1"
+ react-transition-group "^2.2.0"
+ warning "^3.0.0"
+
+react-prop-types@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/react-prop-types/-/react-prop-types-0.4.0.tgz#f99b0bfb4006929c9af2051e7c1414a5c75b93d0"
+ dependencies:
+ warning "^3.0.0"
+
+react-transition-group@^2.0.0, react-transition-group@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
+ dependencies:
+ chain-function "^1.0.0"
+ classnames "^2.2.5"
+ dom-helpers "^3.2.0"
+ loose-envify "^1.3.1"
+ prop-types "^15.5.8"
+ warning "^3.0.0"
+
+readable-stream@~1.0.26:
+ version "1.0.34"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
+regenerator-runtime@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+
+request@2.42.0:
+ version "2.42.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.42.0.tgz#572bd0148938564040ac7ab148b96423a063304a"
+ dependencies:
+ bl "~0.9.0"
+ caseless "~0.6.0"
+ forever-agent "~0.5.0"
+ json-stringify-safe "~5.0.0"
+ mime-types "~1.0.1"
+ node-uuid "~1.4.0"
+ qs "~1.2.0"
+ tunnel-agent "~0.4.0"
+ optionalDependencies:
+ aws-sign2 "~0.5.0"
+ form-data "~0.1.0"
+ hawk "1.1.1"
+ http-signature "~0.10.0"
+ oauth-sign "~0.4.0"
+ stringstream "~0.0.4"
+ tough-cookie ">=0.12.0"
+
+request@2.79.0:
+ version "2.79.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
+ dependencies:
+ aws-sign2 "~0.6.0"
+ aws4 "^1.2.1"
+ caseless "~0.11.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.0"
+ forever-agent "~0.6.1"
+ form-data "~2.1.1"
+ har-validator "~2.0.6"
+ hawk "~3.1.3"
+ http-signature "~1.1.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.7"
+ oauth-sign "~0.8.1"
+ qs "~6.3.0"
+ stringstream "~0.0.4"
+ tough-cookie "~2.3.0"
+ tunnel-agent "~0.4.1"
+ uuid "^3.0.0"
+
+resumer@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
+ dependencies:
+ through "~2.3.4"
+
+setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+
+sntp@0.2.x:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-0.2.4.tgz#fb885f18b0f3aad189f824862536bceeec750900"
+ dependencies:
+ hoek "0.9.x"
+
+sntp@1.x.x:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+ dependencies:
+ hoek "2.x.x"
+
+split@~0.2.10:
+ version "0.2.10"
+ resolved "https://registry.yarnpkg.com/split/-/split-0.2.10.tgz#67097c601d697ce1368f418f06cd201cf0521a57"
+ dependencies:
+ through "2"
+
+sprintf-js@~1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ dashdash "^1.12.0"
+ getpass "^0.1.1"
+ optionalDependencies:
+ bcrypt-pbkdf "^1.0.0"
+ ecc-jsbn "~0.1.1"
+ jsbn "~0.1.0"
+ tweetnacl "~0.14.0"
+
+stream-combiner@~0.0.2:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
+ dependencies:
+ duplexer "~0.1.1"
+
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+
+stringstream@~0.0.4:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ dependencies:
+ ansi-regex "^2.0.0"
+
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+tape@2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/tape/-/tape-2.3.0.tgz#0dfeec709227fbcc9170abe7f046962b271431db"
+ dependencies:
+ deep-equal "~0.1.0"
+ defined "~0.0.0"
+ inherits "~2.0.1"
+ jsonify "~0.0.0"
+ resumer "~0.0.0"
+ split "~0.2.10"
+ stream-combiner "~0.0.2"
+ through "~2.3.4"
+
+through@2, through@~2.3.4:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+tough-cookie@>=0.12.0, tough-cookie@~2.3.0:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
+ dependencies:
+ punycode "^1.4.1"
+
+tunnel-agent@~0.4.0, tunnel-agent@~0.4.1:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+ua-parser-js@^0.7.9:
+ version "0.7.17"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
+
+uncontrollable@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-4.1.0.tgz#e0358291252e1865222d90939b19f2f49f81c1a9"
+ dependencies:
+ invariant "^2.1.0"
+
+urlgrey@0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.0.tgz#f065357040fb35c3b311d4e5dc36484d96dbea06"
+ dependencies:
+ tape "2.3.0"
+
+uuid@^3.0.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
+
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+ dependencies:
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
+
+warning@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
+ dependencies:
+ loose-envify "^1.0.0"
+
+whatwg-fetch@>=0.10.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
+
+xtend@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"