Update test list UI to use API
The UI will now allow more flexibility in selecting what test list should be listed/downloaded. Change-Id: Ie7f928e297b1329a501d7fdf532461fc0a87fe64
This commit is contained in:
parent
d2467afcfc
commit
d0f0d640ca
@ -69,6 +69,17 @@ h1, h2, h3, h4, h5, h6 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.checkbox-test-list {
|
||||
word-spacing: normal;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.checkbox-test-list .info-hover {
|
||||
font-size: 12px;
|
||||
color: #878787;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.capabilities {
|
||||
color: #4B4B4B;
|
||||
}
|
||||
@ -179,6 +190,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||
|
||||
.tests-modal-content textarea {
|
||||
font-size: .9em;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.test-detail {
|
||||
|
@ -34,7 +34,6 @@
|
||||
ctrl.updateTargetCapabilities = updateTargetCapabilities;
|
||||
ctrl.filterStatus = filterStatus;
|
||||
ctrl.getObjectLength = getObjectLength;
|
||||
ctrl.getTestList = getTestList;
|
||||
ctrl.openTestListModal = openTestListModal;
|
||||
|
||||
/** The target OpenStack marketing program to show capabilities for. */
|
||||
@ -184,33 +183,6 @@
|
||||
return Object.keys(object).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will give a list of tests belonging to capabilities with
|
||||
* the selected status(es).
|
||||
*/
|
||||
function getTestList() {
|
||||
if (!ctrl.guidelines) {
|
||||
return;
|
||||
}
|
||||
var caps = ctrl.guidelines.capabilities;
|
||||
var tests = [];
|
||||
angular.forEach(ctrl.targetCapabilities,
|
||||
function (status, cap) {
|
||||
if (ctrl.status[status]) {
|
||||
if (ctrl.guidelines.schema === '1.2') {
|
||||
tests.push.apply(tests, caps[cap].tests);
|
||||
}
|
||||
else {
|
||||
angular.forEach(caps[cap].tests,
|
||||
function(info, test) {
|
||||
tests.push(test);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will open the modal that will show a list of all tests
|
||||
* belonging to capabilities with the selected status(es).
|
||||
@ -225,15 +197,12 @@
|
||||
controller: 'TestListModalController as modal',
|
||||
size: 'lg',
|
||||
resolve: {
|
||||
tests: function () {
|
||||
return ctrl.getTestList();
|
||||
},
|
||||
version: function () {
|
||||
if (!ctrl.version) {
|
||||
return;
|
||||
}
|
||||
return ctrl.version.slice(0, -5);
|
||||
},
|
||||
target: function () {
|
||||
return ctrl.target;
|
||||
},
|
||||
status: function () {
|
||||
return ctrl.status;
|
||||
}
|
||||
@ -249,7 +218,8 @@
|
||||
.controller('TestListModalController', TestListModalController);
|
||||
|
||||
TestListModalController.$inject = [
|
||||
'$uibModalInstance', '$window', 'tests', 'version', 'status'
|
||||
'$uibModalInstance', '$window', '$http', 'version',
|
||||
'target', 'status', 'refstackApiUrl'
|
||||
];
|
||||
|
||||
/**
|
||||
@ -258,17 +228,20 @@
|
||||
* test list corresponding to DefCore capabilities with the selected
|
||||
* statuses.
|
||||
*/
|
||||
function TestListModalController($uibModalInstance, $window, tests,
|
||||
version, status) {
|
||||
function TestListModalController($uibModalInstance, $window, $http, version,
|
||||
target, status, refstackApiUrl) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.tests = tests;
|
||||
ctrl.version = version;
|
||||
ctrl.target = target;
|
||||
ctrl.status = status;
|
||||
ctrl.url = refstackApiUrl;
|
||||
ctrl.close = close;
|
||||
ctrl.getTestListString = getTestListString;
|
||||
ctrl.downloadTestList = downloadTestList;
|
||||
ctrl.updateTestListString = updateTestListString;
|
||||
|
||||
ctrl.aliases = true;
|
||||
ctrl.flagged = false;
|
||||
|
||||
/**
|
||||
* This function will close/dismiss the modal.
|
||||
@ -278,33 +251,62 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return a string representing the sorted
|
||||
* tests list separated by newlines.
|
||||
* This function will return a list of statuses based on which ones
|
||||
* are selected.
|
||||
*/
|
||||
function getTestListString() {
|
||||
if (!ctrl.tests) {
|
||||
return;
|
||||
}
|
||||
return ctrl.tests.sort().join('\n');
|
||||
function getStatusList() {
|
||||
var statusList = [];
|
||||
angular.forEach(ctrl.status, function(value, key) {
|
||||
if (value) {
|
||||
statusList.push(key);
|
||||
}
|
||||
});
|
||||
return statusList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve the test list as a downloadable file.
|
||||
* This will get the list of tests from the API and update the
|
||||
* controller's test list string variable.
|
||||
*/
|
||||
function downloadTestList() {
|
||||
var blob = new Blob([ctrl.getTestListString()], {type: 'text/csv'});
|
||||
var filename = ctrl.version + '-test-list.txt';
|
||||
if ($window.navigator.msSaveOrOpenBlob) {
|
||||
$window.navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
else {
|
||||
var a = $window.document.createElement('a');
|
||||
a.href = $window.URL.createObjectURL(blob);
|
||||
a.download = filename;
|
||||
$window.document.body.appendChild(a);
|
||||
a.click();
|
||||
$window.document.body.removeChild(a);
|
||||
function updateTestListString() {
|
||||
var statuses = getStatusList();
|
||||
if (!statuses.length) {
|
||||
ctrl.error = 'No tests matching selected criteria.';
|
||||
return;
|
||||
}
|
||||
ctrl.testListUrl = [
|
||||
ctrl.url, '/guidelines/', ctrl.version, '/tests?',
|
||||
'target=', ctrl.target, '&',
|
||||
'type=', statuses.join(','), '&',
|
||||
'alias=', ctrl.aliases.toString(), '&',
|
||||
'flag=', ctrl.flagged.toString()
|
||||
].join('');
|
||||
ctrl.testListRequest =
|
||||
$http.get(ctrl.testListUrl).
|
||||
then(function successCallback(response) {
|
||||
ctrl.error = null;
|
||||
ctrl.testListString = response.data;
|
||||
if (!ctrl.testListString) {
|
||||
ctrl.testListCount = 0;
|
||||
}
|
||||
else {
|
||||
ctrl.testListCount =
|
||||
ctrl.testListString.split('\n').length;
|
||||
}
|
||||
}, function errorCallback(response) {
|
||||
ctrl.testListString = null;
|
||||
ctrl.testListCount = null;
|
||||
if (angular.isObject(response.data) &&
|
||||
response.data.message) {
|
||||
ctrl.error = 'Error retrieving test list: ' +
|
||||
response.data.message;
|
||||
}
|
||||
else {
|
||||
ctrl.error = 'Unknown error retrieving test list.';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateTestListString();
|
||||
}
|
||||
})();
|
||||
|
@ -1,24 +1,46 @@
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" aria-hidden="true" ng-click="modal.close()">×</button>
|
||||
<h4>Test List ({{modal.tests.length}})</h4>
|
||||
<h4>Test List ({{modal.testListCount}})</h4>
|
||||
<p>Use this test list with <a title="refstack-client" target="_blank"href="https://github.com/openstack/refstack-client">refstack-client</a>
|
||||
to run only tests in the {{modal.version}} DefCore guideline from capabilities with the following statuses:
|
||||
</p>
|
||||
<ul class="list-inline">
|
||||
<li class="required" ng-if="modal.status.required"> Required</li>
|
||||
<li class="advisory" ng-if="modal.status.advisory"> Advisory</li>
|
||||
<li class="deprecated" ng-if="modal.status.deprecated"> Deprecated</li>
|
||||
<li class="removed" ng-if="modal.status.removed"> Removed</li>
|
||||
</ul>
|
||||
<ul class="list-inline">
|
||||
<li class="required" ng-if="modal.status.required"> Required</li>
|
||||
<li class="advisory" ng-if="modal.status.advisory"> Advisory</li>
|
||||
<li class="deprecated" ng-if="modal.status.deprecated"> Deprecated</li>
|
||||
<li class="removed" ng-if="modal.status.removed"> Removed</li>
|
||||
</ul>
|
||||
<div class="checkbox checkbox-test-list">
|
||||
<label><input type="checkbox" ng-model="modal.aliases" ng-change="modal.updateTestListString()">Aliases</label>
|
||||
<span class="glyphicon glyphicon-info-sign info-hover" aria-hidden="true"
|
||||
title="Include test aliases as tests may have been renamed over time. It does not hurt to include these."></span>
|
||||
|
||||
<label><input type="checkbox" ng-model="modal.flagged" ng-change="modal.updateTestListString()">Flagged</label>
|
||||
<span class="glyphicon glyphicon-info-sign info-hover" aria-hidden="true"
|
||||
title="Include flagged tests.">
|
||||
</span>
|
||||
</div>
|
||||
<p ng-hide="modal.error"> Alternatively, get the test list directly from the API on your CLI:</p>
|
||||
<code ng-hide="modal.error">wget "{{modal.testListUrl}}" -O {{modal.version}}-test-list.txt</code>
|
||||
</div>
|
||||
<div class="modal-body tests-modal-content">
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="20" id="tests" wrap="off">{{modal.getTestListString()}}</textarea>
|
||||
</div>
|
||||
<div cg-busy="{promise:modal.testListRequest,message:'Loading'}"></div>
|
||||
<div ng-show="modal.error" class="alert alert-danger" role="alert">
|
||||
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||
<span class="sr-only">Error:</span>
|
||||
{{modal.error}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" rows="16" id="tests" wrap="off">{{modal.testListString}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" ng-if="modal.tests.length>0" type="button" ng-click="modal.downloadTestList()">Download</button>
|
||||
<a target="_blank" href="{{modal.testListUrl}}" download="{{modal.version + '-test-list.txt'}}">
|
||||
<button class="btn btn-primary" ng-if="modal.testListCount > 0" type="button">
|
||||
Download
|
||||
</button>
|
||||
</a>
|
||||
<button class="btn btn-primary" type="button" ng-click="modal.close()">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -153,42 +153,6 @@ describe('Refstack controllers', function () {
|
||||
expect(ctrl.getObjectLength(testObject)).toBe(2);
|
||||
});
|
||||
|
||||
it('should have a function to get a list of tests belonging to ' +
|
||||
'capabilities with the selected statuses',
|
||||
function () {
|
||||
ctrl.targetCapabilities = {'cap-1': 'required',
|
||||
'cap-2': 'advisory'};
|
||||
ctrl.guidelines = {
|
||||
'schema': '1.4',
|
||||
'capabilities' : {
|
||||
'cap-1': {
|
||||
'tests': {
|
||||
'test_1': {'idempotent_id': 'id-1234'},
|
||||
'test_2': {'idempotent_id': 'id-5678'}
|
||||
}
|
||||
},
|
||||
'cap-2': {
|
||||
'tests': {
|
||||
'test_3': {'idempotent_id': 'id-1233'}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
expect(ctrl.getTestList()).toEqual(['test_1', 'test_2']);
|
||||
ctrl.guidelines = {
|
||||
'schema': '1.2',
|
||||
'capabilities' : {
|
||||
'cap-1': {
|
||||
'tests': ['test_1', 'test_2']
|
||||
},
|
||||
'cap-2': {
|
||||
'tests': ['test_3']
|
||||
}
|
||||
}
|
||||
};
|
||||
expect(ctrl.getTestList()).toEqual(['test_1', 'test_2']);
|
||||
});
|
||||
|
||||
it('should have a method to open a modal for the relevant test list',
|
||||
function () {
|
||||
var modal;
|
||||
@ -211,51 +175,27 @@ describe('Refstack controllers', function () {
|
||||
$window = _$window_;
|
||||
ctrl = $controller('TestListModalController',
|
||||
{$uibModalInstance: modalInstance,
|
||||
tests: ['t1', 't2'],
|
||||
target: 'platform',
|
||||
version: '2016.01',
|
||||
status: {required: true, advisory: false}}
|
||||
);
|
||||
}));
|
||||
|
||||
it('should assign inputs to variables', function () {
|
||||
expect(ctrl.tests).toEqual(['t1', 't2']);
|
||||
expect(ctrl.version).toEqual('2016.01');
|
||||
expect(ctrl.status).toEqual({required: true, advisory: false});
|
||||
});
|
||||
|
||||
it('should have a method to close the modal',
|
||||
function () {
|
||||
ctrl.close();
|
||||
expect(modalInstance.dismiss).toHaveBeenCalledWith('exit');
|
||||
});
|
||||
|
||||
it('should have a method to convert the tests to a string',
|
||||
it('should have a method to download the test list string',
|
||||
function () {
|
||||
ctrl.tests = ['t2', 't1', 't3'];
|
||||
var expectedString = 't1\nt2\nt3';
|
||||
expect(ctrl.getTestListString()).toEqual(expectedString);
|
||||
});
|
||||
|
||||
it('should have a method to download a test list',
|
||||
function () {
|
||||
var fakeElement = $window.document.createElement('a');
|
||||
spyOn($window.document, 'createElement').and.callFake(
|
||||
function() {
|
||||
return fakeElement;
|
||||
});
|
||||
spyOn($window.document.body, 'appendChild').and.callFake(
|
||||
function() {
|
||||
return true;
|
||||
});
|
||||
spyOn($window.document.body, 'removeChild').and.callFake(
|
||||
function() {
|
||||
return true;
|
||||
});
|
||||
ctrl.downloadTestList();
|
||||
var doc = $window.document;
|
||||
expect(doc.createElement).toHaveBeenCalledWith('a');
|
||||
expect(doc.body.appendChild).toHaveBeenCalled();
|
||||
expect(doc.body.removeChild).toHaveBeenCalled();
|
||||
var fakeResp = 'test1\ntest2\ntest3';
|
||||
$httpBackend.expectGET(fakeApiUrl +
|
||||
'/guidelines/2016.01/tests?target=platform&' +
|
||||
'type=required&alias=true&flag=false').respond(fakeResp);
|
||||
$httpBackend.flush();
|
||||
ctrl.updateTestListString();
|
||||
expect(ctrl.testListCount).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user