summaryrefslogtreecommitdiffstats
path: root/testapi/opnfv_testapi
diff options
context:
space:
mode:
Diffstat (limited to 'testapi/opnfv_testapi')
-rw-r--r--testapi/opnfv_testapi/common/check.py21
-rw-r--r--testapi/opnfv_testapi/handlers/base_handlers.py4
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_pod.py37
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py12
-rw-r--r--testapi/opnfv_testapi/ui/app.js15
-rw-r--r--testapi/opnfv_testapi/ui/components/deploy-results/deployResults.html4
-rw-r--r--testapi/opnfv_testapi/ui/components/pods/pods.html2
-rw-r--r--testapi/opnfv_testapi/ui/components/projects/projects.html2
-rw-r--r--testapi/opnfv_testapi/ui/components/results/results.html21
9 files changed, 89 insertions, 29 deletions
diff --git a/testapi/opnfv_testapi/common/check.py b/testapi/opnfv_testapi/common/check.py
index 7f866dd..77b48f5 100644
--- a/testapi/opnfv_testapi/common/check.py
+++ b/testapi/opnfv_testapi/common/check.py
@@ -35,7 +35,7 @@ def is_authorized(method):
if type(query) is not dict:
query_data = query()
else:
- if self.json_args is None:
+ if self.json_args is None or 'name' not in self.json_args:
query_data = query
else:
query_data = self.json_args
@@ -47,13 +47,22 @@ def is_authorized(method):
return wrapper
-def is_allowed(method):
+def is_reource_tied(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)
+ query_data = {}
+ tied_map_tables = {
+ 'projects': ('testcases', 'project_name'),
+ 'pods': ('results', 'pod_name'),
+ 'testcases': ('results', 'case_name')
+ }
+ if self.table in tied_map_tables:
+ if method.__name__ == '_update':
+ if 'name' not in self.json_args:
+ ret = yield gen.coroutine(method)(self, *args, **kwargs)
+ raise gen.Return(ret)
+ query_data[tied_map_tables[self.table][1]] = kwargs.get('query')['name']
+ data = yield dbapi.db_find_one(tied_map_tables[self.table][0], query_data)
if data:
raises.Unauthorized(message.tied_with_resource())
ret = yield gen.coroutine(method)(self, *args, **kwargs)
diff --git a/testapi/opnfv_testapi/handlers/base_handlers.py b/testapi/opnfv_testapi/handlers/base_handlers.py
index ed4aeb2..350c38d 100644
--- a/testapi/opnfv_testapi/handlers/base_handlers.py
+++ b/testapi/opnfv_testapi/handlers/base_handlers.py
@@ -179,7 +179,7 @@ class GenericApiHandler(web.RequestHandler):
@gen.coroutine
@check.not_exist
@check.is_authorized
- @check.is_allowed
+ @check.is_reource_tied
def _delete(self, data, query=None):
yield dbapi.db_delete(self.table, query)
self.finish_request()
@@ -190,7 +190,7 @@ class GenericApiHandler(web.RequestHandler):
@check.not_exist
@check.updated_one_not_exist
@check.is_authorized
- @check.is_allowed
+ @check.is_reource_tied
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_pod.py b/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py
index d1eedc0..28d29b5 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py
@@ -10,6 +10,7 @@ import httplib
from opnfv_testapi.common import message
from opnfv_testapi.models import pod_models as pm
+from opnfv_testapi.models import result_models as rm
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit import fake_pymongo
from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -23,6 +24,8 @@ class TestPodBase(base.TestBase):
self.basePath = '/api/v1/pods'
self.req_d = pm.PodCreateRequest.from_dict(self.pod_d.format())
self.req_e = pm.PodCreateRequest.from_dict(self.pod_e.format())
+ self.results_d = rm.ResultCreateRequest.from_dict(
+ self.load_json('test_result'))
def assert_get_body(self, pod, req=None):
if not req:
@@ -101,3 +104,37 @@ class TestPodGet(TestPodBase):
self.assert_get_body(pod)
else:
self.assert_get_body(pod, self.req_e)
+
+
+class TestPodDelete(TestPodBase):
+ @executor.mock_valid_lfid()
+ def setUp(self):
+ super(TestPodDelete, self).setUp()
+ fake_pymongo.pods.insert(self.pod_d.format())
+ fake_pymongo.projects.insert({'name': self.results_d.project_name})
+ fake_pymongo.testcases.insert({'name': self.results_d.case_name,
+ 'project_name': self.results_d.project_name})
+
+ @executor.delete(httplib.BAD_REQUEST, message.not_login())
+ def test_notlogin(self):
+ return self.pod_d.name
+
+ @executor.delete(httplib.NOT_FOUND, message.not_found_base)
+ def test_notFound(self):
+ return 'notFound'
+
+ @executor.mock_valid_lfid()
+ @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_deleteNotAllowed(self):
+ self.create_help('/api/v1/results', self.results_d)
+ return self.pod_d.name
+
+ @executor.mock_valid_lfid()
+ @executor.delete(httplib.OK, '_assert_delete')
+ def test_success(self):
+ return self.pod_d.name
+
+ def _assert_delete(self, body):
+ self.assertEqual(body, '')
+ code, body = self.get(self.pod_d.name)
+ self.assertEqual(code, httplib.NOT_FOUND)
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py b/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py
index 9a2bf58..78f3ab1 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py
@@ -10,6 +10,7 @@ import httplib
from opnfv_testapi.common import message
from opnfv_testapi.models import testcase_models as tcm
+from opnfv_testapi.models import result_models as rm
from opnfv_testapi.tests.unit import executor
from opnfv_testapi.tests.unit import fake_pymongo
from opnfv_testapi.tests.unit.handlers import test_base as base
@@ -32,6 +33,8 @@ class TestCaseBase(base.TestBase):
self.basePath = '/api/v1/projects/%s/cases'
fake_pymongo.projects.insert(self.project_e.format())
print self.req_d.format()
+ self.results_d = rm.ResultCreateRequest.from_dict(
+ self.load_json('test_result'))
def assert_body(self, case, req=None):
if not req:
@@ -176,11 +179,20 @@ class TestCaseDelete(TestCaseBase):
def setUp(self):
super(TestCaseDelete, self).setUp()
self.create_d()
+ fake_pymongo.pods.insert(self.pod_d.format())
+ fake_pymongo.projects.insert({'name': self.results_d.project_name})
+ fake_pymongo.testcases.insert({'name': self.results_d.case_name,
+ 'project_name': self.results_d.project_name})
@executor.delete(httplib.NOT_FOUND, message.not_found_base)
def test_notFound(self):
return 'notFound'
+ @executor.delete(httplib.UNAUTHORIZED, message.tied_with_resource())
+ def test_deleteNotAllowed(self):
+ print self.create_help('/api/v1/results', self.results_d)
+ return self.results_d.case_name
+
@executor.delete(httplib.OK, '_delete_success')
def test_success(self):
return self.req_d.name
diff --git a/testapi/opnfv_testapi/ui/app.js b/testapi/opnfv_testapi/ui/app.js
index ae50166..def88d2 100644
--- a/testapi/opnfv_testapi/ui/app.js
+++ b/testapi/opnfv_testapi/ui/app.js
@@ -42,6 +42,21 @@
};
}]);
+ angular
+ .module('testapiApp')
+ .directive('ngEnter', function () {
+ return function (scope, element, attrs) {
+ element.bind("keydown keypress", function (event) {
+ if(event.which === 13) {
+ scope.$apply(function (){
+ scope.$eval(attrs.ngEnter);
+ });
+ event.preventDefault();
+ }
+ });
+ };
+ });
+
configureRoutes.$inject = ['$stateProvider', '$urlRouterProvider'];
/**
diff --git a/testapi/opnfv_testapi/ui/components/deploy-results/deployResults.html b/testapi/opnfv_testapi/ui/components/deploy-results/deployResults.html
index 6fbaaea..380416f 100644
--- a/testapi/opnfv_testapi/ui/components/deploy-results/deployResults.html
+++ b/testapi/opnfv_testapi/ui/components/deploy-results/deployResults.html
@@ -15,7 +15,7 @@
<div class="col-sm-2 pull-right" ng-class="{'hidden': ctrl.filter=='start_date' || ctrl.filter=='end_date'}">
<span style="margin-top:6px">Search:&nbsp;&nbsp;</span>
<input list="filter" name="filter" class="form-control search" style="display:inline;width:105px;padding-left:6px;"
- ng-Model="ctrl.filterText" placeholder="Search String">
+ ng-enter="ctrl.filterList()" ng-Model="ctrl.filterText" placeholder="Search String">
<datalist id="filter" ng-class="{ 'hidden' : ctrl.filterOption.length<0}">
<option ng-repeat="(index, filterValue) in ctrl.filterOption " value="{{filterValue}}">{{filterValue}}</option>
</datalist>
@@ -24,6 +24,7 @@
<span style="margin-top:6px">Start&nbsp;Date:&nbsp;&nbsp;</span>
<p class="input-group" style="width:48%;display:inline-flex;">
<input type="text" class="form-control"
+ ng-enter="ctrl.filterList()"
uib-datepicker-popup="{{ctrl.format}}"
ng-model="ctrl.filterText" is-open="ctrl.startOpen"
close-text="Close" />
@@ -38,6 +39,7 @@
<span style="margin-top:6px">End&nbsp;Date:&nbsp;&nbsp;</span>
<p class="input-group" style="width:48%;display:inline-flex;">
<input type="text" class="form-control"
+ ng-enter="ctrl.filterList()"
uib-datepicker-popup="{{ctrl.format}}"
ng-model="ctrl.filterText" is-open="ctrl.endOpen"
close-text="Close" />
diff --git a/testapi/opnfv_testapi/ui/components/pods/pods.html b/testapi/opnfv_testapi/ui/components/pods/pods.html
index 7873977..8e66a9c 100644
--- a/testapi/opnfv_testapi/ui/components/pods/pods.html
+++ b/testapi/opnfv_testapi/ui/components/pods/pods.html
@@ -22,7 +22,7 @@
</div>
<div class="col-sm-3 pull-right">
<span style="margin-top:6px">Search:&nbsp;&nbsp;</span>
- <input type="text" class="form-control search" ng-Model="ctrl.filterText" placeholder="Search String">
+ <input type="text" class="form-control search" ng-enter="ctrl.listPods()" ng-Model="ctrl.filterText" placeholder="Search String">
</div>
</div>
<div class="col-md-12">
diff --git a/testapi/opnfv_testapi/ui/components/projects/projects.html b/testapi/opnfv_testapi/ui/components/projects/projects.html
index b6b73d4..84902f8 100644
--- a/testapi/opnfv_testapi/ui/components/projects/projects.html
+++ b/testapi/opnfv_testapi/ui/components/projects/projects.html
@@ -18,7 +18,7 @@
</div>
<div class="col-sm-3 pull-right">
<span style="margin-top:6px">Search:&nbsp;&nbsp;</span>
- <input type="text" class="form-control search" ng-Model="ctrl.filterText" style="width:80%;" placeholder="Search By Name">
+ <input type="text" class="form-control search" ng-enter="ctrl.listProjects()" ng-Model="ctrl.filterText" style="width:80%;" placeholder="Search By Name">
</div>
</div>
<div class='clo-md-12'>
diff --git a/testapi/opnfv_testapi/ui/components/results/results.html b/testapi/opnfv_testapi/ui/components/results/results.html
index 2756bb0..e1413d5 100644
--- a/testapi/opnfv_testapi/ui/components/results/results.html
+++ b/testapi/opnfv_testapi/ui/components/results/results.html
@@ -1,22 +1,5 @@
<h3>{{ctrl.pageHeader}}</h3>
<p>{{ctrl.pageParagraph}}</p>
-<form class="form-inline" ng-show="ctrl.isUserResults">
-<h4>Upload Results</h4>
-<div class="form-group col-m-3">
- <input class="form-contrl btn btn-default" type = "file" file-model = "resultFile"/>
-</div>
-<div class="checkbox col-m-1">
- <label>
- <input type="checkbox" ng-model="ctrl.isPublic">public
- </label>
-</div>
-<div class="form-group col-m-3">
- <button class="btn btn-primary" ng-click = "ctrl.uploadFile()">upload result</button>
-</div>
-<div>
-<lable>{{ctrl.uploadState}}</label>
-</div>
-</form>
<div class="row" style="margin-bottom:24px;"></div>
<div class="result-filters" style="border-top: none;">
<div class="row podTable" style="vertical-align:middle">
@@ -31,7 +14,7 @@
</div>
<div class="col-sm-2 pull-right" ng-class="{'hidden': ctrl.filter=='start_date' || ctrl.filter=='end_date'}">
<span style="margin-top:6px">Search:&nbsp;&nbsp;</span>
- <input list="filter" name="filter" class="form-control search" style="display:inline;width:105px;padding-left:6px;"
+ <input list="filter" ng-enter="ctrl.filterList()" name="filter" class="form-control search" style="display:inline;width:105px;padding-left:6px;"
ng-Model="ctrl.filterText" placeholder="Search String">
<datalist id="filter" ng-class="{ 'hidden' : ctrl.filterOption.length<0}">
<option ng-repeat="(index, filterValue) in ctrl.filterOption " value="{{filterValue}}">{{filterValue}}</option>
@@ -41,6 +24,7 @@
<span style="margin-top:6px">Start&nbsp;Date:&nbsp;&nbsp;</span>
<p class="input-group" style="width:48%;display:inline-flex;">
<input type="text" class="form-control"
+ ng-enter="ctrl.filterList()"
uib-datepicker-popup="{{ctrl.format}}"
ng-model="ctrl.filterText" is-open="ctrl.startOpen"
close-text="Close" />
@@ -55,6 +39,7 @@
<span style="margin-top:6px">End&nbsp;Date:&nbsp;&nbsp;</span>
<p class="input-group" style="width:48%;display:inline-flex;">
<input type="text" class="form-control"
+ ng-enter="ctrl.filterList()"
uib-datepicker-popup="{{ctrl.format}}"
ng-model="ctrl.filterText" is-open="ctrl.endOpen"
close-text="Close" />