summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testapi/3rd_party/static/testapi-ui/assets/css/style.css6
-rw-r--r--testapi/opnfv_testapi/handlers/project_handlers.py28
-rw-r--r--testapi/opnfv_testapi/tests/unit/handlers/test_project.py28
-rw-r--r--testapi/opnfv_testapi/ui/components/projects/projects.html28
-rw-r--r--testapi/opnfv_testapi/ui/components/projects/projectsController.js49
5 files changed, 114 insertions, 25 deletions
diff --git a/testapi/3rd_party/static/testapi-ui/assets/css/style.css b/testapi/3rd_party/static/testapi-ui/assets/css/style.css
index f348092..91e8ba2 100644
--- a/testapi/3rd_party/static/testapi-ui/assets/css/style.css
+++ b/testapi/3rd_party/static/testapi-ui/assets/css/style.css
@@ -226,3 +226,9 @@ a.glyphicon {
.modal-body .row {
margin-bottom: 10px;
}
+
+.alert{
+ background-color: white;
+ border-color: white;
+ margin-top: 5px;
+} \ No newline at end of file
diff --git a/testapi/opnfv_testapi/handlers/project_handlers.py b/testapi/opnfv_testapi/handlers/project_handlers.py
index 30d9ab3..3ba1a80 100644
--- a/testapi/opnfv_testapi/handlers/project_handlers.py
+++ b/testapi/opnfv_testapi/handlers/project_handlers.py
@@ -6,6 +6,7 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+import re
from opnfv_testapi.handlers import base_handlers
from opnfv_testapi.models import project_models
@@ -20,16 +21,33 @@ class GenericProjectHandler(base_handlers.GenericApiHandler):
self.table = 'projects'
self.table_cls = project_models.Project
+ def set_query(self):
+ query = dict()
+ for k in self.request.query_arguments.keys():
+ v = self.get_query_argument(k)
+ if k == 'name':
+ query['name'] = re.compile(v, re.IGNORECASE)
+ return query
+
class ProjectCLHandler(GenericProjectHandler):
- @swagger.operation(nickname="listAllProjects")
+ @swagger.operation(nickname="listProjects")
def get(self):
"""
- @description: list all projects
- @return 200: return all projects, empty list is no project exist
- @rtype: L{Projects}
+ @description: Retrieve project(s) on a specific details.
+ @notes: Retrieve project(s) on a specific details.
+ Available filters for this request are :
+ - name : project name
+
+ GET /projects?name=functest
+ @return 200: all projects consist with query,
+ empty list if no result is found
+ @param name: project name
+ @type name: L{string}
+ @in name: query
+ @required name: False
"""
- self._list()
+ self._list(query=self.set_query())
@swagger.operation(nickname="createProject")
def post(self):
diff --git a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
index 9bc0e86..cbd1a4e 100644
--- a/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
+++ b/testapi/opnfv_testapi/tests/unit/handlers/test_project.py
@@ -8,6 +8,7 @@
##############################################################################
import httplib
import unittest
+import urllib
from opnfv_testapi.common import message
from opnfv_testapi.models import project_models
@@ -25,6 +26,7 @@ class TestProjectBase(base.TestBase):
self.get_res = project_models.Project
self.list_res = project_models.Projects
self.update_res = project_models.Project
+ self.name = 'functest'
self.basePath = '/api/v1/projects'
def assert_body(self, project, req=None):
@@ -89,6 +91,10 @@ class TestProjectGet(TestProjectBase):
def test_list(self):
return None
+ @executor.query(httplib.OK, '_query_success', 1)
+ def test_queryName(self):
+ return self._set_query('name')
+
def _assert_list(self, body):
for project in body.projects:
if self.req_d.name == project.name:
@@ -96,6 +102,19 @@ class TestProjectGet(TestProjectBase):
else:
self.assert_body(project, self.req_e)
+ def _set_query(self, *args, **kwargs):
+ def get_value(arg):
+ return self.__getattribute__(arg)
+ query = []
+ for arg in args:
+ query.append((arg, get_value(arg)))
+ for k, v in kwargs.iteritems():
+ query.append((k, v))
+ return urllib.urlencode(query)
+
+ def _query_success(self, body, number):
+ self.assertEqual(number, len(body.projects))
+
class TestProjectUpdate(TestProjectBase):
@executor.mock_valid_lfid()
@@ -106,6 +125,11 @@ class TestProjectUpdate(TestProjectBase):
self.index_d = get_res._id
self.create_e()
+ @executor.update(httplib.BAD_REQUEST, message.not_login())
+ def test_notlogin(self):
+ req = project_models.ProjectUpdateRequest('apex', 'apex test')
+ return req, self.req_d.name
+
@executor.update(httplib.BAD_REQUEST, message.no_body())
def test_withoutBody(self):
return None, 'noBody'
@@ -145,6 +169,10 @@ class TestProjectDelete(TestProjectBase):
super(TestProjectDelete, self).setUp()
self.create_d()
+ @executor.delete(httplib.BAD_REQUEST, message.not_login())
+ def test_notlogin(self):
+ return self.req_d.name
+
@executor.delete(httplib.NOT_FOUND, message.not_found_base)
def test_notFound(self):
return 'notFound'
diff --git a/testapi/opnfv_testapi/ui/components/projects/projects.html b/testapi/opnfv_testapi/ui/components/projects/projects.html
index 55f8683..28c08b1 100644
--- a/testapi/opnfv_testapi/ui/components/projects/projects.html
+++ b/testapi/opnfv_testapi/ui/components/projects/projects.html
@@ -23,12 +23,12 @@
<button type="submit" class="btn btn-primary" ng-click="ctrl.create()">Create</button>
</div>
<div class="col-md-11 col-sm-11 col-xs-11">
- <div ng-show="ctrl.showError" class="alert alert-danger" role="alert">
+ <div ng-show="ctrl.showCreateError" class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
{{ctrl.error}}
</div>
- <div ng-show="ctrl.showSuccess" class="alert alert-success" role="alert">
+ <div ng-show="ctrl.showCreateSuccess" class="alert alert-success" role="alert">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
Create Success
</div>
@@ -37,6 +37,30 @@
</div>
+<div class="project-filters">
+ <h4>Filters</h4>
+ <div class="row">
+ <div class="col-md-3">
+ <label for="cpid">Name</label>
+ <input type="text" class="form-control"
+ ng-model="ctrl.filterName"/>
+ </div>
+ <div class="col-md-1" style="margin-top:24px;">
+ <button type="submit" class="btn btn-primary" ng-click="ctrl.update()">Filter</button>
+ </div>
+ <div class="col-md-1" style="margin-top:24px;">
+ <button type="submit" class="btn btn-primary btn-danger" ng-click="ctrl.clearFilters()">Clear</button>
+ </div>
+ <div class="col-md-7" style="margin-top:10px;">
+ <div ng-show="ctrl.showUpdateError" class="alert alert-danger" role="alert">
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+ <span class="sr-only">Error:</span>
+ {{ctrl.error}}
+ </div>
+ </div>
+ </div>
+</div>
+
<div ng-show="ctrl.data" class="projects-table" style="margin-top:24px; margin-left:8px;">
<table ng-data="ctrl.data.projects" ng-show="ctrl.data" class="table table-striped table-hover">
<tbody>
diff --git a/testapi/opnfv_testapi/ui/components/projects/projectsController.js b/testapi/opnfv_testapi/ui/components/projects/projectsController.js
index 16002f6..468407b 100644
--- a/testapi/opnfv_testapi/ui/components/projects/projectsController.js
+++ b/testapi/opnfv_testapi/ui/components/projects/projectsController.js
@@ -34,6 +34,7 @@
ctrl.url = testapiApiUrl + '/projects';
ctrl.create = create;
ctrl.update = update;
+ ctrl.clearFilters = clearFilters;
ctrl.createRequirements = [
{label: 'name', type: 'text', required: true},
@@ -42,13 +43,13 @@
ctrl.name = '';
ctrl.details = '';
-
+ ctrl.filterName='';
/**
* This will contact the TestAPI to create a new project.
*/
function create() {
- ctrl.showError = false;
- ctrl.showSuccess = false;
+ ctrl.showCreateError = false;
+ ctrl.showCreateSuccess = false;
if(ctrl.name != ""){
var projects_url = ctrl.url;
var body = {
@@ -57,18 +58,17 @@
};
ctrl.projectsRequest =
$http.post(projects_url, body).success(function (data){
- ctrl.showSuccess = true ;
+ ctrl.showCreateSuccess = true ;
ctrl.update();
- })
- .error(function (data) {
- ctrl.showError = true;
- ctrl.error = 'Error creating the new Project from server:' + angular.toJson(data);
+ }).catch(function (data) {
+ ctrl.showCreateError = true;
+ ctrl.error = data.statusText;
});
ctrl.name = "";
ctrl.description="";
}
else{
- ctrl.showError = true;
+ ctrl.showCreateError = true;
ctrl.error = 'Name is missing.'
}
}
@@ -77,18 +77,31 @@
* This will contact the TestAPI to get a listing of declared projects.
*/
function update() {
- ctrl.showError = false;
- ctrl.projectsRequest =
- $http.get(ctrl.url).success(function (data) {
+ ctrl.showUpdateError = false;
+ var content_url = ctrl.url + '?';
+ var name = ctrl.filterName;
+ if(name){
+ content_url = content_url + 'name=' +
+ name;
+ }
+ ctrl.resultsRequest =
+ $http.get(content_url).success(function (data) {
ctrl.data = data;
- }).error(function (error) {
+ }).catch(function (data) {
ctrl.data = null;
- ctrl.showError = true;
- ctrl.error =
- 'Error retrieving projects from server: ' +
- angular.toJson(error);
+ ctrl.showUpdateError = true;
+ ctrl.error = data.statusText;
});
}
- ctrl.update();
+
+ /**
+ * This function will clear all filters and update the projects
+ * listing.
+ */
+ function clearFilters() {
+ ctrl.filterName = null;
+ ctrl.showUpdateError = false;
+ ctrl.update();
+ }
}
})();