summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testapi/opnfv_testapi/tests/UI/e2e/scenarioControllerSpec.js40
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_deploy_result.py17
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/podsController.js11
-rw-r--r--testapi/opnfv_testapi/ui/components/scenarios/modals/customModal.html30
-rw-r--r--testapi/opnfv_testapi/ui/components/scenarios/scenario/scenarioController.js23
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html2
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js28
-rw-r--r--testapi/testapi-client/setup.cfg1
-rw-r--r--testapi/testapi-client/testapiclient/projects.py104
9 files changed, 240 insertions, 16 deletions
diff --git a/testapi/opnfv_testapi/tests/UI/e2e/scenarioControllerSpec.js b/testapi/opnfv_testapi/tests/UI/e2e/scenarioControllerSpec.js
index 60d4949..564fbcf 100644
--- a/testapi/opnfv_testapi/tests/UI/e2e/scenarioControllerSpec.js
+++ b/testapi/opnfv_testapi/tests/UI/e2e/scenarioControllerSpec.js
@@ -336,7 +336,7 @@ describe('testing the scenarios page for anonymous user', function () {
});
-describe('testing the scenarios page for anonymous user', function () {
+describe('testing the scenarios page for user', function () {
beforeEach(function(){
mock([
{
@@ -662,7 +662,7 @@ describe('testing the scenarios page for anonymous user', function () {
browser.wait(EC.urlContains(baseURL+ '#/scenarios/test-scenario'), 10000);
});
- it( 'should not show the add installer option for user', function() {
+ it( 'should show the add installer option for user', function() {
browser.get(baseURL+"#/scenarios/test-scenario");
var EC = browser.ExpectedConditions;
browser.wait(EC.urlContains(baseURL+ '#/scenarios/test-scenario'), 10000);
@@ -1009,6 +1009,42 @@ describe('testing the scenarios page for anonymous user', function () {
.isDisplayed()).toBe(true);
});
+ it( 'Add multiple Customs by user', function() {
+ browser.get(baseURL+"#/scenarios/test-scenario");
+ var EC = browser.ExpectedConditions;
+ browser.wait(EC.urlContains(baseURL+ '#/scenarios/test-scenario'), 10000);
+ var installersShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[1]/a/p'))
+ installersShow.click();
+ var installerShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[1]/td[2]/a'))
+ installerShow.click();
+ var versionsShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[1]/a/p'))
+ versionsShow.click();
+ var versionShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[3]/div/table/tbody/tr[1]/td[2]/a'))
+ versionShow.click()
+ var projectsShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[3]/div/table/tbody/tr[3]/td[2]/div[1]/a'))
+ projectsShow.click();
+ var projectShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[3]/div/table/tbody/tr[3]/td[2]/div[3]/div/table/tbody/tr[1]/td[2]/a'))
+ projectShow.click();
+ var customsShow = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[3]/div/table/tbody/tr[3]/td[2]/div[3]/div/table/tbody[1]/tr[4]/td[2]/a/p'))
+ customsShow.click();
+ var row = element.all(by.repeater('(indexCU, custom) in project.customs')).first();
+ var cells = row.all(by.tagName('td'));
+ expect(cells.get(0).getText()).toContain("dvs");
+ var buttonAdd = element(by.xpath('//*[@id="ng-app"]/body/div/div[1]/div/table/tbody/tr[5]/td[2]/div[3]/div/table/tbody/tr[2]/td[2]/div[3]/div/table/tbody/tr[3]/td[2]/div[3]/div/table/tbody[1]/tr[4]/td[2]/button'))
+ buttonAdd.click()
+ var custom = element(by.model('customModalCtrl.custom'));
+ browser.wait(EC.visibilityOf(custom), 5000);
+ custom.sendKeys('testC');
+ // browser.pause();
+ var buttonAddCustom = element(by.xpath('//*[@id="ng-app"]/body/div[3]/div/div/div/div[1]/div/fieldset/div/div/div/table/tfoot/tr/td[2]/input'))
+ buttonAddCustom.click();
+ custom.sendKeys('testB');
+ var buttonOk = element(by.xpath('//*[@id="ng-app"]/body/div[3]/div/div/div/div[2]/button[1]'))
+ buttonOk.click()
+ expect(element(by.cssContainingText(".alert","Customs are successfully updated."))
+ .isDisplayed()).toBe(true);
+ });
+
it( 'Delete Customs by user', function() {
browser.get(baseURL+"#/scenarios/test-scenario");
var EC = browser.ExpectedConditions;
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_deploy_result.py b/testapi/opnfv_testapi/tests/unit/handlers/test_deploy_result.py
index 65e765e..8f2ca76 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_deploy_result.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_deploy_result.py
@@ -92,6 +92,10 @@ class DeployResultGet(DeployResultBase):
self.req_d_id = self._create_d()
self.req_10d_later = self._create_changed_date(days=10)
+ @executor.get(httplib.OK, 'assert_res')
+ def test_getOne(self):
+ return self.req_d_id
+
@executor.query(httplib.OK, '_query_success', 3)
def test_queryInstaller(self):
return self._set_query('installer')
@@ -165,6 +169,19 @@ class DeployResultGet(DeployResultBase):
self._create_error_start_date('')
return self._set_query(period=5)
+ @executor.query(httplib.OK, '_query_success', 0)
+ def test_notFound(self):
+ return self._set_query('installer',
+ 'version',
+ 'job_name',
+ 'build_id',
+ 'scenario',
+ 'upstream_job_name',
+ 'upstream_build_id',
+ 'criteria',
+ pod='notExistPod',
+ period=1)
+
def _query_success(self, body, number):
self.assertEqual(number, len(body.deployresults))
diff --git a/testapi/opnfv_testapi/ui/components/pods/podsController.js b/testapi/opnfv_testapi/ui/components/pods/podsController.js
index 95e3571..38e084d 100644
--- a/testapi/opnfv_testapi/ui/components/pods/podsController.js
+++ b/testapi/opnfv_testapi/ui/components/pods/podsController.js
@@ -137,7 +137,6 @@
function batchDelete(){
var index;
var checkedBox = [];
- console.log(ctrl.checkBox)
for(index in ctrl.checkBox){
if(!ctrl.showError){
if(ctrl.checkBox[index]){
@@ -153,7 +152,13 @@
* message
*/
function openBatchDeleteModal() {
- confirmModal("Delete",ctrl.batchDelete);
+ var deleteObjects = []
+ for(var index in ctrl.checkBox){
+ if(ctrl.checkBox[index]){
+ deleteObjects.push(ctrl.data.pods[index].name)
+ }
+ }
+ confirmModal("Delete", 'pods', ctrl.batchDelete, deleteObjects);
}
/**
@@ -162,7 +167,7 @@
*/
function openDeleteModal(name) {
console.log(name)
- confirmModal("Delete", ctrl.podDelete, name);
+ confirmModal("Delete", 'pod', ctrl.podDelete, name);
}
/**
diff --git a/testapi/opnfv_testapi/ui/components/scenarios/modals/customModal.html b/testapi/opnfv_testapi/ui/components/scenarios/modals/customModal.html
index 987cb1e..90e4544 100644
--- a/testapi/opnfv_testapi/ui/components/scenarios/modals/customModal.html
+++ b/testapi/opnfv_testapi/ui/components/scenarios/modals/customModal.html
@@ -6,11 +6,31 @@
<legend>{{customModalCtrl.data.text}}</legend>
<div class="row">
<div class="update-project">
- <label for="cpid" class="control-label col-sm-4">Custom: </label>
- <div class="col-sm-6">
- <input type="text" class="form-control" ng-model="customModalCtrl.custom"/>
- <p class="help-block"></p>
- </div>
+ <label for="cpid" class="control-label col-sm-4">Custom: </label>
+ <table cellpadding="0" cellspacing="0">
+ <tbody ng-repeat="custom in customModalCtrl.customs">
+ <tr>
+ <td>
+ <div class="col-sm-12">
+ <input type="text" class="form-control" value="{{custom}}" disabled/>
+ <p class="help-block"></p>
+ </div>
+ </td>
+ <td><input type="button" class="btn btn-danger" ng-click="customModalCtrl.remove($index)" value="Remove" /></td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td>
+ <div class="col-sm-12">
+ <input type="text" class="form-control" ng-model="customModalCtrl.custom"/>
+ <p class="help-block"></p>
+ </div>
+ </td>
+ <td><input type="button" class="btn btn-primary" ng-click="customModalCtrl.add()" value="Add" /></td>
+ </tr>
+ </tfoot>
+ </table>
</div>
</div>
</div>
diff --git a/testapi/opnfv_testapi/ui/components/scenarios/scenario/scenarioController.js b/testapi/opnfv_testapi/ui/components/scenarios/scenario/scenarioController.js
index 53eb13a..b76f63c 100644
--- a/testapi/opnfv_testapi/ui/components/scenarios/scenario/scenarioController.js
+++ b/testapi/opnfv_testapi/ui/components/scenarios/scenario/scenarioController.js
@@ -435,15 +435,34 @@
ctrl.cancel = cancel;
ctrl.data = angular.copy(data);
ctrl.open = open;
+ ctrl.add = add;
+ ctrl.remove = remove;
+ ctrl.customs = [];
+
+ function add() {
+ var custom = ctrl.custom;
+ if(custom!="" && custom!=undefined ){
+ ctrl.customs.push(custom);
+ ctrl.custom = "";
+ }
+ };
+
+ function remove(index) {
+ // var name = ctrl.customs[index].Name;
+ ctrl.customs.splice(index, 1);
+
+ }
/**
* Initiate confirmation and call the success handler with the
* inputs.
*/
function confirm() {
- ctrl.customs = []
- ctrl.customs.push(ctrl.custom)
+ var custom = ctrl.custom;
+ if(custom!="" && custom!=undefined ){
+ ctrl.customs.push(custom);
+ }
ctrl.data.successHandler(ctrl.customs,ctrl.data.project,ctrl.data.version,ctrl.data.installer);
$uibModalInstance.dismiss('cancel');
diff --git a/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html b/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
index e5397e0..417af37 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html
@@ -10,7 +10,7 @@
</div>
<div class="Delete" ng-class="{ 'hidden': confirmModal.data.text!='Delete' }">
<div class="form-group">
- <label for="confirmText"> You are about to delete.</label>
+ <label for="confirmText"> You are about to delete following {{confirmModal.data.resource}} : {{confirmModal.deleteObjects}} </label>
<br>
Do you want to proceed?
</div>
diff --git a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
index 5e79775..c115a3c 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
@@ -11,17 +11,19 @@
* Opens confirm modal dialog with input textbox
*/
function confirmModal($uibModal) {
- return function(text, successHandler, name) {
+ return function(text, resource, successHandler, name) {
$uibModal.open({
- templateUrl: '/testapi-ui/shared/alerts/confirmModal.html',
+ templateUrl: 'testapi-ui/shared/alerts/confirmModal.html',
controller: 'CustomConfirmModalController as confirmModal',
size: 'md',
resolve: {
data: function () {
return {
text: text,
+ resource: resource,
successHandler: successHandler,
name: name
+
};
}
}
@@ -44,8 +46,26 @@
ctrl.confirm = confirm;
ctrl.cancel = cancel;
-
+ ctrl.buildDeleteObjects = buildDeleteObjects;
ctrl.data = angular.copy(data);
+
+ function buildDeleteObjects(){
+ ctrl.deleteObjects = '';
+ if (typeof ctrl.data.name === 'string') {
+ ctrl.deleteObjects = ctrl.data.name
+ }
+ else{
+ for(var index in ctrl.data.name){
+ if(index==0){
+ ctrl.deleteObjects += ctrl.data.name[index]
+ }
+ else{
+ ctrl.deleteObjects += ", "+ ctrl.data.name[index]
+ }
+
+ }
+ }
+ }
/**
* Initiate confirmation and call the success handler with the
* input text.
@@ -63,5 +83,7 @@
function cancel() {
$uibModalInstance.dismiss('cancel');
}
+
+ ctrl.buildDeleteObjects();
}
})();
diff --git a/testapi/testapi-client/setup.cfg b/testapi/testapi-client/setup.cfg
index 1e25b73..8174720 100644
--- a/testapi/testapi-client/setup.cfg
+++ b/testapi/testapi-client/setup.cfg
@@ -25,6 +25,7 @@ testapi =
project create = testapiclient.projects:ProjectCreate
project get = testapiclient.projects:ProjectGet
+ project getone = testapiclient.projects:ProjectGetOne
project delete = testapiclient.projects:ProjectDelete
project put = testapiclient.projects:ProjectPut
diff --git a/testapi/testapi-client/testapiclient/projects.py b/testapi/testapi-client/testapiclient/projects.py
new file mode 100644
index 0000000..57def5d
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/projects.py
@@ -0,0 +1,104 @@
+import json
+from user import User
+from cliff.command import Command
+from httpClient import HTTPClient
+from authHandler import AuthHandler
+from config import Config
+
+
+class ProjectBase(Command):
+ projects_url = Config.config.get("api", "url") + "/projects"
+
+
+class ProjectGet(ProjectBase):
+
+ def get_parser(self, prog_name):
+ parser = super(ProjectGet, self).get_parser(prog_name)
+ parser.add_argument('-name', default='', help='Search projects by name')
+ return parser
+
+ def take_action(self, parsed_args):
+ httpClient = HTTPClient.get_Instance()
+ url = ProjectGet.projects_url
+ if parsed_args.name:
+ url = url + "?name=" + parsed_args.name
+ projects = httpClient.get(url)
+ print projects
+
+
+class ProjectGetOne(ProjectBase):
+
+ def get_parser(self, prog_name):
+ parser = super(ProjectGetOne, self).get_parser(prog_name)
+ parser.add_argument('-name', default='', required=True, help='Search project by name')
+ return parser
+
+ def take_action(self, parsed_args):
+ httpClient = HTTPClient.get_Instance()
+ url = ProjectGet.projects_url + "/" + parsed_args.name
+ project = httpClient.get(url)
+ print project
+
+
+class ProjectCreate(ProjectBase):
+
+ def get_parser(self, prog_name):
+ parser = super(ProjectCreate, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, help='Username for authentication')
+ parser.add_argument('-p', type=str, help='Password for authentication')
+ parser.add_argument('project', type=json.loads, help='Project create request format :{ "name": (required)"", "description": (optional)""}')
+ return parser
+
+ def take_action(self, parsed_args):
+ httpClient = HTTPClient.get_Instance()
+ if(parsed_args.u and parsed_args.p):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ return
+ response = httpClient.post(ProjectCreate.projects_url, User.session, parsed_args.project)
+ if response.status_code == 200:
+ print "Project has been successfully created!"
+ else:
+ print response.text
+
+
+class ProjectDelete(ProjectBase):
+
+ def get_parser(self, prog_name):
+ parser = super(ProjectDelete, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, help='Username for authentication')
+ parser.add_argument('-p', type=str, help='Password for authentication')
+ parser.add_argument('-name', type=str, required=True, help='Delete project by name')
+ return parser
+
+ def take_action(self, parsed_args):
+ httpClient = HTTPClient.get_Instance()
+ if(parsed_args.u and parsed_args.p):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ return
+ projects = httpClient.delete(ProjectDelete.projects_url + "/" + parsed_args.name, User.session)
+ print projects
+
+
+class ProjectPut(ProjectBase):
+
+ def get_parser(self, prog_name):
+ parser = super(ProjectPut, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, help='Username for authentication')
+ parser.add_argument('-p', type=str, help='Password for authentication')
+ parser.add_argument('-name', type=str, required=True, help='Update project by name')
+ parser.add_argument('project', type=json.loads, help='Project Update request format :{ "name": (required)"", "description": (optional)""}')
+ return parser
+
+ def take_action(self, parsed_args):
+ httpClient = HTTPClient.get_Instance()
+ if(parsed_args.u and parsed_args.p):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ return
+ projects = httpClient.put(ProjectPut.projects_url + "/" + parsed_args.name, User.session, parsed_args.project)
+ print projects