@@ -112,8 +122,6 @@
NO
-
Verified:
- YES
Capability Overview
diff --git a/refstack-ui/app/components/results-report/resultsReportController.js b/refstack-ui/app/components/results-report/resultsReportController.js
index b53184e7..39ba12a3 100644
--- a/refstack-ui/app/components/results-report/resultsReportController.js
+++ b/refstack-ui/app/components/results-report/resultsReportController.js
@@ -53,6 +53,7 @@
ctrl.getCapabilityTestCount = getCapabilityTestCount;
ctrl.getStatusTestCount = getStatusTestCount;
ctrl.openFullTestListModal = openFullTestListModal;
+ ctrl.openEditTestModal = openEditTestModal;
/** The testID extracted from the URL route. */
ctrl.testId = $stateParams.testID;
@@ -610,6 +611,27 @@
});
}
+ /**
+ * This will open the modal that will all a user to edit test run
+ * metadata.
+ */
+ function openEditTestModal() {
+ $uibModal.open({
+ templateUrl: '/components/results-report/partials' +
+ '/editTestModal.html',
+ backdrop: true,
+ windowClass: 'modal',
+ animation: true,
+ controller: 'EditTestModalController as modal',
+ size: 'lg',
+ resolve: {
+ resultsData: function () {
+ return ctrl.resultsData;
+ }
+ }
+ });
+ }
+
getResults();
}
@@ -644,4 +666,197 @@
return ctrl.tests.sort().join('\n');
};
}
+
+ angular
+ .module('refstackApp')
+ .controller('EditTestModalController', EditTestModalController);
+
+ EditTestModalController.$inject = [
+ '$uibModalInstance', '$http', '$state', 'raiseAlert',
+ 'refstackApiUrl', 'resultsData'
+ ];
+
+ /**
+ * Edit Test Modal Controller
+ * This controller is for the modal that appears if a user wants to edit
+ * test run metadata.
+ */
+ function EditTestModalController($uibModalInstance, $http, $state,
+ raiseAlert, refstackApiUrl, resultsData) {
+
+ var ctrl = this;
+
+ ctrl.getVersionList = getVersionList;
+ ctrl.getUserProducts = getUserProducts;
+ ctrl.associateProductVersion = associateProductVersion;
+ ctrl.getProductVersions = getProductVersions;
+ ctrl.saveChanges = saveChanges;
+
+ ctrl.resultsData = resultsData;
+ ctrl.metaCopy = angular.copy(resultsData.meta);
+ ctrl.prodVersionCopy = angular.copy(resultsData.product_version);
+
+ ctrl.getVersionList();
+ ctrl.getUserProducts();
+
+ /**
+ * Retrieve an array of available capability files from the Refstack
+ * API server, sort this array reverse-alphabetically, and store it in
+ * a scoped variable.
+ * Sample API return array: ["2015.03.json", "2015.04.json"]
+ */
+ function getVersionList() {
+ if (ctrl.versionList) {
+ return;
+ }
+ var content_url = refstackApiUrl + '/guidelines';
+ ctrl.versionsRequest =
+ $http.get(content_url).success(function (data) {
+ ctrl.versionList = data.sort().reverse();
+ }).error(function (error) {
+ raiseAlert('danger', error.title,
+ 'Unable to retrieve version list');
+ });
+ }
+
+ /**
+ * Get products user has management rights to or all products depending
+ * on the passed in parameter value.
+ */
+ function getUserProducts() {
+ var contentUrl = refstackApiUrl + '/products';
+ ctrl.productsRequest =
+ $http.get(contentUrl).success(function (data) {
+ ctrl.products = {};
+ angular.forEach(data.products, function(prod) {
+ if (prod.can_manage) {
+ ctrl.products[prod.id] = prod;
+ }
+ });
+ if (ctrl.prodVersionCopy) {
+ ctrl.selectedProduct = ctrl.products[
+ ctrl.prodVersionCopy.product_info.id
+ ];
+ }
+ ctrl.getProductVersions();
+ }).error(function (error) {
+ ctrl.products = null;
+ ctrl.showError = true;
+ ctrl.error =
+ 'Error retrieving Products listing from server: ' +
+ angular.toJson(error);
+ });
+ }
+
+ /**
+ * Send a PUT request to the API server to associate a product with
+ * a test result.
+ */
+ function associateProductVersion() {
+ var verId = (ctrl.selectedVersion ?
+ ctrl.selectedVersion.id : null);
+ var testId = resultsData.id;
+ var url = refstackApiUrl + '/results/' + testId;
+ ctrl.associateRequest = $http.put(url, {'product_version_id':
+ verId})
+ .error(function (error) {
+ ctrl.showError = true;
+ ctrl.showSuccess = false;
+ ctrl.error =
+ 'Error associating product version with test run: ' +
+ angular.toJson(error);
+ });
+ }
+
+ /**
+ * Get all versions for a product.
+ */
+ function getProductVersions() {
+ if (!ctrl.selectedProduct) {
+ ctrl.productVersions = [];
+ ctrl.selectedVersion = null;
+ return;
+ }
+
+ var url = refstackApiUrl + '/products/' +
+ ctrl.selectedProduct.id + '/versions';
+ ctrl.getVersionsRequest = $http.get(url)
+ .success(function (data) {
+ ctrl.productVersions = data;
+ if (ctrl.prodVersionCopy &&
+ ctrl.prodVersionCopy.product_info.id ==
+ ctrl.selectedProduct.id) {
+ ctrl.selectedVersion = ctrl.prodVersionCopy;
+ }
+ else {
+ angular.forEach(data, function(ver) {
+ if (!ver.version) {
+ ctrl.selectedVersion = ver;
+ }
+ });
+ }
+ }).error(function (error) {
+ raiseAlert('danger', error.title, error.detail);
+ });
+ }
+
+ /**
+ * Send a PUT request to the server with the changes.
+ */
+ function saveChanges() {
+ ctrl.showError = false;
+ ctrl.showSuccess = false;
+ var metaBaseUrl = [
+ refstackApiUrl, '/results/', resultsData.id, '/meta/'
+ ].join('');
+ var metaFields = ['target', 'guideline', 'shared'];
+ var meta = ctrl.metaCopy;
+ angular.forEach(metaFields, function(field) {
+ var oldMetaValue = (field in ctrl.resultsData.meta) ?
+ ctrl.resultsData.meta[field] : '';
+ if (field in meta && oldMetaValue != meta[field]) {
+ var metaUrl = metaBaseUrl + field;
+ if (meta[field]) {
+ ctrl.assocRequest = $http.post(metaUrl, meta[field])
+ .success(function(data) {
+ ctrl.resultsData.meta[field] = meta[field];
+ })
+ .error(function (error) {
+ ctrl.showError = true;
+ ctrl.showSuccess = false;
+ ctrl.error =
+ 'Error associating metadata with ' +
+ 'test run: ' + angular.toJson(error);
+ });
+ }
+ else {
+ ctrl.unassocRequest = $http.delete(metaUrl)
+ .success(function (data) {
+ delete ctrl.resultsData.meta[field];
+ delete meta[field];
+ })
+ .error(function (error) {
+ ctrl.showError = true;
+ ctrl.showSuccess = false;
+ ctrl.error =
+ 'Error associating metadata with ' +
+ 'test run: ' + angular.toJson(error);
+ });
+ }
+ }
+ });
+ ctrl.associateProductVersion();
+ if (!ctrl.showError) {
+ ctrl.showSuccess = true;
+ $state.reload();
+ }
+ }
+
+ /**
+ * This function will close/dismiss the modal.
+ */
+ ctrl.close = function () {
+ $uibModalInstance.dismiss('exit');
+ };
+ }
})();
diff --git a/refstack-ui/tests/unit/ControllerSpec.js b/refstack-ui/tests/unit/ControllerSpec.js
index c4ec94ac..0ef3a3dc 100644
--- a/refstack-ui/tests/unit/ControllerSpec.js
+++ b/refstack-ui/tests/unit/ControllerSpec.js
@@ -734,6 +734,17 @@ describe('Refstack controllers', function () {
ctrl.openFullTestListModal();
expect(modal.open).toHaveBeenCalled();
});
+
+ it('should have a method to open a modal for editing test metadata',
+ function () {
+ var modal;
+ inject(function ($uibModal) {
+ modal = $uibModal;
+ });
+ spyOn(modal, 'open');
+ ctrl.openEditTestModal();
+ expect(modal.open).toHaveBeenCalled();
+ });
});
describe('FullTestListModalController', function () {
@@ -766,6 +777,72 @@ describe('Refstack controllers', function () {
});
});
+ describe('EditTestModalController', function () {
+ var modalInstance, ctrl, state;
+ var fakeResultsData = {
+ 'results': ['test_id_1'],
+ 'id': 'some-id',
+ 'meta': {
+ 'public_key': 'ssh-rsa', 'guideline': '2015.04.json',
+ 'target': 'object'
+ }
+ };
+ var fakeProdResp = {'products': [{'id': 1234}]};
+ var fakeVersionResp = [{'id': 'ver1', 'version': '1.0'},
+ {'id': 'ver2', 'version': null}];
+
+ beforeEach(inject(function ($controller) {
+ modalInstance = {
+ dismiss: jasmine.createSpy('modalInstance.dismiss')
+ };
+ state = {
+ reload: jasmine.createSpy('state.reload')
+ };
+ ctrl = $controller('EditTestModalController',
+ {$uibModalInstance: modalInstance, $state: state,
+ resultsData: fakeResultsData}
+ );
+ $httpBackend.when('GET', fakeApiUrl +
+ '/guidelines').respond(['2015.03.json', '2015.04.json']);
+ $httpBackend.when('GET', fakeApiUrl + '/products')
+ .respond(200, fakeResultsData);
+ $httpBackend.when('GET', fakeApiUrl +
+ '/products/1234/versions').respond(fakeVersionResp);
+ }));
+
+ it('should be able to get product versions', function () {
+ ctrl.selectedProduct = {'id': '1234'};
+ ctrl.products = null;
+ $httpBackend.expectGET(fakeApiUrl + '/products/1234/versions')
+ .respond(200, fakeVersionResp);
+ ctrl.getProductVersions();
+ $httpBackend.flush();
+ expect(ctrl.productVersions).toEqual(fakeVersionResp);
+ var expected = {'id': 'ver2', 'version': null};
+ expect(ctrl.selectedVersion).toEqual(expected);
+ });
+
+ it('should have a method to save all changes made.', function () {
+ ctrl.metaCopy.target = 'platform';
+ ctrl.metaCopy.shared = 'true';
+ ctrl.selectedVersion = {'id': 'ver2', 'version': null};
+ ctrl.saveChanges();
+ // Only meta changed should send a POST request.
+ $httpBackend.expectPOST(
+ fakeApiUrl + '/results/some-id/meta/target',
+ 'platform')
+ .respond(201, '');
+ $httpBackend.expectPOST(
+ fakeApiUrl + '/results/some-id/meta/shared',
+ 'true')
+ .respond(201, '');
+ $httpBackend.expectPUT(fakeApiUrl + '/results/some-id',
+ {'product_version_id': 'ver2'})
+ .respond(201);
+ $httpBackend.flush();
+ });
+ });
+
describe('TestRaiseAlertModalController', function() {
var data, modalInstance, ctrl;