summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testapi/opnfv_testapi/common/check.py14
-rw-r--r--testapi/opnfv_testapi/common/message.py4
-rw-r--r--testapi/opnfv_testapi/handlers/base_handlers.py2
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_project.py17
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/podsController.js11
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModal.html2
-rw-r--r--testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js26
7 files changed, 70 insertions, 6 deletions
diff --git a/testapi/opnfv_testapi/common/check.py b/testapi/opnfv_testapi/common/check.py
index 1a66dd7..7f866dd 100644
--- a/testapi/opnfv_testapi/common/check.py
+++ b/testapi/opnfv_testapi/common/check.py
@@ -47,6 +47,20 @@ def is_authorized(method):
return wrapper
+def is_allowed(method):
+ @functools.wraps(method)
+ def wrapper(self, *args, **kwargs):
+ if self.table == 'projects':
+ query_data = {}
+ query_data['project_name'] = kwargs.get('query')['name']
+ data = yield dbapi.db_find_one('testcases', query_data)
+ if data:
+ raises.Unauthorized(message.tied_with_resource())
+ ret = yield gen.coroutine(method)(self, *args, **kwargs)
+ raise gen.Return(ret)
+ return wrapper
+
+
def valid_token(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
diff --git a/testapi/opnfv_testapi/common/message.py b/testapi/opnfv_testapi/common/message.py
index b92b7f0..7c62894 100644
--- a/testapi/opnfv_testapi/common/message.py
+++ b/testapi/opnfv_testapi/common/message.py
@@ -64,3 +64,7 @@ def must_int(name):
def no_permission():
return 'You do not have permission to perform this action'
+
+
+def tied_with_resource():
+ return 'Selected resource is associated with other resources'
diff --git a/testapi/opnfv_testapi/handlers/base_handlers.py b/testapi/opnfv_testapi/handlers/base_handlers.py
index 537077d..ed4aeb2 100644
--- a/testapi/opnfv_testapi/handlers/base_handlers.py
+++ b/testapi/opnfv_testapi/handlers/base_handlers.py
@@ -179,6 +179,7 @@ class GenericApiHandler(web.RequestHandler):
@gen.coroutine
@check.not_exist
@check.is_authorized
+ @check.is_allowed
def _delete(self, data, query=None):
yield dbapi.db_delete(self.table, query)
self.finish_request()
@@ -189,6 +190,7 @@ class GenericApiHandler(web.RequestHandler):
@check.not_exist
@check.updated_one_not_exist
@check.is_authorized
+ @check.is_allowed
def _update(self, data, query=None, **kwargs):
data = self.table_cls.from_dict(data)
update_req = self._update_requests(data)
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
index cbd1a4e..884dd68 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
@@ -12,6 +12,7 @@ import urllib
from opnfv_testapi.common import message
from opnfv_testapi.models import project_models
+from opnfv_testapi.models import testcase_models as tcm
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -23,6 +24,9 @@ class TestProjectBase(base.TestBase):
'qtip-ssh test')
self.req_e = project_models.ProjectCreateRequest('functest',
'functest test')
+ self.testcase_d = tcm.TestcaseCreateRequest.from_dict(
+ self.load_json('testcase_d'))
+ self.project = 'qtip'
self.get_res = project_models.Project
self.list_res = project_models.Projects
self.update_res = project_models.Project
@@ -150,6 +154,13 @@ class TestProjectUpdate(TestProjectBase):
return self.req_d, self.req_d.name
@executor.mock_valid_lfid()
+ @executor.update(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_updateNotAllowed(self):
+ self.create_help('/api/v1/projects/%s/cases', self.testcase_d, self.req_d.name)
+ req = project_models.ProjectUpdateRequest('apex', 'apex test')
+ return req, self.req_d.name
+
+ @executor.mock_valid_lfid()
@executor.update(httplib.OK, '_assert_update')
def test_success(self):
req = project_models.ProjectUpdateRequest('apex', 'apex test')
@@ -178,6 +189,12 @@ class TestProjectDelete(TestProjectBase):
return 'notFound'
@executor.mock_valid_lfid()
+ @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_deleteNotAllowed(self):
+ self.create_help('/api/v1/projects/%s/cases', self.testcase_d, self.req_d.name)
+ return self.req_d.name
+
+ @executor.mock_valid_lfid()
@executor.delete(httplib.OK, '_assert_delete')
def test_success(self):
return self.req_d.name
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/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 42cf873..c115a3c 100644
--- a/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
+++ b/testapi/opnfv_testapi/ui/shared/alerts/confirmModalFactory.js
@@ -11,7 +11,7 @@
* 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',
controller: 'CustomConfirmModalController as confirmModal',
@@ -20,8 +20,10 @@
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();
}
})();