Add vendor UI

This adds the initial UI functionality for the UI in relations
to vendors.

Change-Id: I58a3b00a421d2d65d59014e586bacc974aa8637b
Co-Authored-By: Andrey Pavlov <andrey-mp@yandex.ru>
This commit is contained in:
Paul Van Eck 2016-06-09 15:45:22 -07:00
parent 9888cf2bc1
commit 3c82bc3443
11 changed files with 831 additions and 0 deletions

View File

@ -78,6 +78,21 @@
url: '/logout',
templateUrl: '/components/logout/logout.html',
controller: 'LogoutController as ctrl'
}).
state('userVendors', {
url: '/user_vendors',
templateUrl: '/components/vendors/vendors.html',
controller: 'VendorsController as ctrl'
}).
state('publicVendors', {
url: '/public_vendors',
templateUrl: '/components/vendors/vendors.html',
controller: 'VendorsController as ctrl'
}).
state('vendor', {
url: '/vendor/:vendorID',
templateUrl: '/components/vendors/vendor.html',
controller: 'VendorController as ctrl'
});
}

View File

@ -0,0 +1,85 @@
<div ng-show="ctrl.vendor" class="container-fluid">
<div class="row">
<div class="pull-left">
<div class="test-report">
<strong>Vendor ID:</strong> {{ctrl.vendorId}}<br />
<strong>Type:</strong>
<span ng-show="ctrl.vendor.type == 0">OpenStack</span>
<span ng-show="ctrl.vendor.type == 1" class="text-info">Private</span>
<span ng-show="ctrl.vendor.type == 2" class="text-warning">Pending Approval</span>
<span ng-show="ctrl.vendor.type == 3" class="text-success">Official</span>
<br />
<strong>Name:</strong> {{ctrl.vendor.name}}<br />
<strong>Description:</strong> {{ctrl.vendor.description}}<br />
</div>
</div>
<div class="pull-right">
<a ng-if="ctrl.vendor.canDelete" href="javascript:void(0)" ng-click="ctrl.deleteVendor()" confirm="Are you sure you want to delete this vendor?">Delete</a><br />
<a ng-if="ctrl.vendor.canRegister" href="javascript:void(0)" ng-click="ctrl.registerVendor()">Register with Foundation</a><br />
<a ng-if="ctrl.vendor.canApprove && ctrl.vendor.type == 2" href="javascript:void(0)" ng-click="ctrl.approveVendor()"
confirm="Are you sure you want to approve this vendor?">Approve registration</a><br />
<a ng-if="ctrl.vendor.canApprove && ctrl.vendor.type == 2" href="javascript:void(0)" ng-click="ctrl.declineVendor()">Decline registration</a><br />
</div>
</div>
<div class="row">
<div ng-if="ctrl.vendorProperties.reason">
<hr />
<strong>Decline reason:</strong> {{ctrl.vendorProperties.reason}}<br />
</div>
</div>
<div ng-show="ctrl.vendorUsers" class="row">
<hr />
<h3>Vendor Users</h3>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Open ID</th>
<th>Full Name</th>
<th>E-Mail</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in ctrl.vendorUsers">
<td>{{user.openid}}</td>
<td>{{user.fullname}}</td>
<td>{{user.email}}</td>
<td>
<a ng-if="user.openid != ctrl.currentUser"
href="javascript:void(0)"
ng-click="ctrl.removeUserFromVendor(user.openid)"
confirm="Are you sure you want to remove this user from vendor?">Remove</a>
</td>
</tr>
</tbody>
</table>
<div class="row form-group">
<div class="col-md-6">
<label for="new_user">Add user to vendor:</label>
<input type="text"
class="form-control"
id="new_user"
placeholder="Input Open ID"
ng-model="ctrl.userToAdd">
</div>
<div class="col-md-1" style="margin-top:25px;">
<button type="submit" class="btn btn-primary" ng-click="ctrl.addUserToVendor(ctrl.userToAdd)">Add User</button>
</div>
</div>
<hr />
</div>
</div>
<!-- Loading animation divs -->
<div cg-busy="{promise:ctrl.vendorRequest,message:'Loading'}"></div>
<div cg-busy="{promise:ctrl.usersRequest,message:'Loading'}"></div>
<div ng-show="ctrl.showError" 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>

View File

@ -0,0 +1,185 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function () {
'use strict';
angular
.module('refstackApp')
.controller('VendorController', VendorController);
VendorController.$inject = [
'$rootScope', '$scope', '$http', '$state', '$stateParams', '$window',
'refstackApiUrl', 'raiseAlert', 'confirmModal'
];
/**
* RefStack Vendor Controller
* This controller is for the '/vendor/' details page where owner can
* view details of the Vendor and manage users.
*/
function VendorController($rootScope, $scope, $http, $state, $stateParams,
$window, refstackApiUrl, raiseAlert, confirmModal) {
var ctrl = this;
ctrl.getVendor = getVendor;
ctrl.getVendorUsers = getVendorUsers;
ctrl.registerVendor = registerVendor;
ctrl.approveVendor = approveVendor;
ctrl.declineVendor = declineVendor;
ctrl.deleteVendor = deleteVendor;
ctrl.removeUserFromVendor = removeUserFromVendor;
ctrl.addUserToVendor = addUserToVendor;
/** The vendor id extracted from the URL route. */
ctrl.vendorId = $stateParams.vendorID;
// Should only be on user-vendors-page if authenticated.
if (!$scope.auth.isAuthenticated) {
$state.go('home');
}
/**
* This will contact the Refstack API to get a vendor information.
*/
function getVendor() {
ctrl.showError = false;
ctrl.vendor = null;
// Construct the API URL based on user-specified filters.
var contentUrl = refstackApiUrl + '/vendors/' + ctrl.vendorId;
ctrl.vendorRequest =
$http.get(contentUrl).success(function(data) {
ctrl.vendor = data;
var isAdmin = $rootScope.auth.currentUser.is_admin;
ctrl.vendor.canDelete = ctrl.vendor.type != 0
&& (ctrl.vendor.can_manage || isAdmin);
ctrl.vendor.canRegister =
ctrl.vendor.type == 1;
ctrl.vendor.canApprove = isAdmin;
ctrl.vendorProperties = angular.fromJson(data.properties);
}).error(function(error) {
ctrl.showError = true;
ctrl.error =
'Error retrieving from server: ' +
angular.toJson(error);
});
}
ctrl.getVendor();
/**
* This will 'send' application for registration.
*/
function registerVendor() {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId,
'/action'].join('');
$http.post(url, {register: null}).success(function() {
ctrl.getVendor();
}).error(function(error) {
raiseAlert('danger', 'Error: ', error.detail);
});
}
/**
* This will approve application for registration.
*/
function approveVendor() {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId,
'/action'].join('');
$http.post(url, {approve: null}).success(function() {
ctrl.getVendor();
}).error(function(error) {
raiseAlert('danger', 'Error: ', error.detail);
});
}
/**
* This will decline a vendor's application for registration.
*/
function declineVendor() {
confirmModal('Please input decline reason', function(reason) {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId,
'/action'].join('');
$http.post(url, {deny: null, reason: reason}).success(
function() {
ctrl.getVendor();
}).error(function(error) {
raiseAlert('danger', 'Error: ', error.detail);
});
});
}
/**
* Delete the current vendor.
*/
function deleteVendor() {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId].join('');
$http.delete(url).success(function () {
$window.location.href = '/';
}).error(function (error) {
raiseAlert('danger', 'Error: ', error.detail);
});
}
/**
* Updates list of users in the vendor's group
*/
function getVendorUsers() {
ctrl.showError = false;
var contentUrl = refstackApiUrl + '/vendors/' + ctrl.vendorId
+ '/users';
ctrl.usersRequest =
$http.get(contentUrl).success(function(data) {
ctrl.vendorUsers = data;
ctrl.currentUser = $rootScope.auth.currentUser.openid;
}).error(function(error) {
ctrl.showError = true;
ctrl.error =
'Error retrieving from server: ' +
angular.toJson(error);
});
}
ctrl.getVendorUsers();
/**
* Removes user with specific openid from vendor's group
* @param {Object} openid
*/
function removeUserFromVendor(openid) {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId,
'/users/', btoa(openid)].join('');
$http.delete(url).success(function () {
ctrl.getVendorUsers();
}).error(function (error) {
raiseAlert('danger', 'Error: ', error.detail);
});
}
/**
* Adds a user to a vendor group given an Open ID.
* @param {Object} openid
*/
function addUserToVendor(openid) {
var url = [refstackApiUrl, '/vendors/', ctrl.vendorId,
'/users/', btoa(openid)].join('');
$http.put(url).success(function() {
ctrl.userToAdd = '';
ctrl.getVendorUsers();
}).error(function(error) {
raiseAlert('danger', 'Problem adding user. ' +
'Is the Open ID correct? Error: ',
error.detail);
});
}
}
})();

View File

@ -0,0 +1,69 @@
<h3>{{ctrl.pageHeader}}</h3>
<p>{{ctrl.pageParagraph}}</p>
<div cg-busy="{promise:ctrl.authRequest,message:'Loading'}"></div>
<div cg-busy="{promise:ctrl.vendorsRequest,message:'Loading'}"></div>
<div ng-show="ctrl.data" class="vendors-table">
<label ng-if="ctrl.isAdminView && ctrl.isUserVendors">
<input type="checkbox" ng-model="ctrl.withPrivate" ng-change="ctrl.updateData();">&nbsp;Show private vendors
</label>
<br />
<table ng-show="ctrl.data" class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="vendor in ctrl.data.vendors">
<td ng-if="ctrl.isUserVendors"><a ui-sref="vendor({vendorID: vendor.id})">{{vendor.name}}</a></td>
<td ng-if="!ctrl.isUserVendors">{{vendor.name}}</td>
<td>{{vendor.description || '-'}}</td>
<td>
<span ng-show="vendor.type == 0" class="glyphicon glyphicon-exclamation-sign">&nbsp;OpenStack</span>
<span ng-show="vendor.type == 1" class="glyphicon glyphicon-eye-close">&nbsp;Private</span>
<span ng-show="vendor.type == 2" class="glyphicon glyphicon-transfer">&nbsp;Pending Approval</span>
<span ng-show="vendor.type == 3" class="glyphicon glyphicon-check">&nbsp;Official</span>
</td>
</tr>
</tbody>
</table>
</div>
<div ng-if="ctrl.isUserVendors">
<hr />
<h4>Add new vendor</h4>
<p>Creating a vendor allows you to associate test results to specific vendors/products.
Created vendors are private, but vendors can be registered with the Foundation to become public and official.
This will require approval by a Foundation administrator.</p>
<div class="row">
<div class="col-md-3">
<label>Name</label>
<p class="input-group">
<input type="text" class="form-control"
ng-model="ctrl.name" close-text="Close" />
</p>
</div>
<div class="col-md-6">
<label>Description</label>
<p class="input-group">
<input type="text" class="form-control" size="80"
ng-model="ctrl.description" close-text="Close" />
</p>
</div>
<div class="col-md-3" style="margin-top:24px;">
<button type="submit" class="btn btn-primary" ng-click="ctrl.addVendor()">Add Vendor</button>
</div>
</div>
</div>
<div cg-busy="{promise:ctrl.vendorsRequest,message:'Loading'}"></div>
<div ng-show="ctrl.showError" 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>

View File

@ -0,0 +1,162 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function () {
'use strict';
angular
.module('refstackApp')
.controller('VendorsController', VendorsController);
VendorsController.$inject = [
'$rootScope', '$scope', '$http', '$state',
'refstackApiUrl','raiseAlert'
];
/**
* RefStack Vendors Controller
* This controller is for the '/user_vendors' or '/public_vendors' page
* where a user can browse a listing of his/her vendors or public vendors.
*/
function VendorsController($rootScope, $scope, $http, $state,
refstackApiUrl, raiseAlert) {
var ctrl = this;
ctrl.update = update;
ctrl.updateData = updateData;
ctrl._filterVendor = _filterVendor;
ctrl.addVendor = addVendor;
/** Check to see if this page should display user-specific vendors. */
ctrl.isUserVendors = $state.current.name === 'userVendors';
/** Show private vendors in list for foundation admin */
ctrl.withPrivate = false;
/** Properties for adding new vendor */
ctrl.name = '';
ctrl.description = '';
// Should only be on user-vendors-page if authenticated.
if (ctrl.isUserVendors && !$scope.auth.isAuthenticated) {
$state.go('home');
}
ctrl.pageHeader = ctrl.isUserVendors ?
'My Vendors' : 'Public Vendors';
ctrl.pageParagraph = ctrl.isUserVendors ?
'Your added vendors are listed here.' :
'Public Vendors approved by the OpenStack Foundation are ' +
'listed here.';
if (ctrl.isUserVendors) {
ctrl.authRequest = $scope.auth.doSignCheck()
.then(ctrl.update);
} else {
ctrl.update();
}
ctrl.rawData = null;
ctrl.isAdminView = $rootScope.auth
&& $rootScope.auth.currentUser
&& $rootScope.auth.currentUser.is_admin;
/**
* This will contact the Refstack API to get a listing of test run
* results.
*/
function update() {
ctrl.showError = false;
ctrl.data = null;
// Construct the API URL based on user-specified filters.
var contentUrl = refstackApiUrl + '/vendors';
if (typeof ctrl.rawData == 'undefined'
|| ctrl.rawData === null) {
ctrl.vendorsRequest =
$http.get(contentUrl).success(function (data) {
ctrl.rawData = data;
ctrl.updateData();
}).error(function (error) {
ctrl.rawData = null;
ctrl.showError = true;
ctrl.error =
'Error retrieving vendors listing from server: ' +
angular.toJson(error);
});
} else {
ctrl.updateData();
}
}
/**
* This will update data for view with current settings on page.
*/
function updateData() {
ctrl.data = {};
ctrl.data.vendors = ctrl.rawData.vendors.filter(function(vendor) {
return ctrl._filterVendor(vendor);
});
ctrl.data.vendors.sort(function(a, b) {
if (a.type > b.type) {
return 1;
}
if (a.type < b.type) {
return -1;
}
return a.name.localeCompare(b.name);
});
}
/**
* Returns true if vendor can be displayed on this page.
*/
function _filterVendor(vendor) {
if (!ctrl.isUserVendors) {
return (vendor.type == 0 || vendor.type == 3);
}
if (!$rootScope.auth || !$rootScope.auth.currentUser) {
return false;
}
if ($rootScope.auth.currentUser.is_admin) {
return vendor.type != 1 || ctrl.withPrivate;
}
return vendor.can_manage;
}
/**
* This will add a new vendor record.
*/
function addVendor() {
var url = refstackApiUrl + '/vendors';
var data = {
name: ctrl.name,
description: ctrl.description
};
ctrl.name = '';
ctrl.description = '';
$http.post(url, data).success(function (data) {
ctrl.rawData = null;
ctrl.update();
}).error(function (error) {
ctrl.showError = true;
ctrl.error =
'Error adding new vendor: ' + angular.toJson(error);
});
}
}
})();

View File

@ -38,12 +38,15 @@
<!-- Controllers -->
<script src="shared/header/headerController.js"></script>
<script src="shared/alerts/alertModalFactory.js"></script>
<script src="shared/alerts/confirmModalFactory.js"></script>
<script src="components/guidelines/guidelinesController.js"></script>
<script src="components/results/resultsController.js"></script>
<script src="components/results-report/resultsReportController.js"></script>
<script src="components/profile/profileController.js"></script>
<script src="components/auth-failure/authFailureController.js"></script>
<script src="components/logout/logoutController.js"></script>
<script src="components/vendors/vendorController.js"></script>
<script src="components/vendors/vendorsController.js"></script>
<!-- Filters -->
<script src="shared/filters.js"></script>

View File

@ -0,0 +1,13 @@
<div class="modal-header"><h3 class="modal-title">Confirm</h3></div>
<div class="modal-body">
<div class="form-group">
<label for="confirmText">{{confirmModal.data.text}}:</label>
<textarea type="text" class="form-control"
rows="5" ng-model="confirmModal.inputText" id="confirmText">
</textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="confirmModal.confirm()">Ok</button>
<button class="btn btn-default" ng-click="confirmModal.cancel()">Cancel</button>
</div>

View File

@ -0,0 +1,67 @@
(function () {
'use strict';
angular
.module('refstackApp')
.factory('confirmModal', confirmModal);
confirmModal.$inject = ['$uibModal'];
/**
* Opens confirm modal dialog with input textbox
*/
function confirmModal($uibModal) {
return function(text, successHandler) {
$uibModal.open({
templateUrl: '/shared/alerts/confirmModal.html',
controller: 'CustomConfirmModalController as confirmModal',
size: 'md',
resolve: {
data: function () {
return {
text: text,
successHandler: successHandler
};
}
}
});
};
}
angular
.module('refstackApp')
.controller('CustomConfirmModalController',
CustomConfirmModalController);
CustomConfirmModalController.$inject = ['$uibModalInstance', 'data'];
/**
* This is the controller for the alert pop-up.
*/
function CustomConfirmModalController($uibModalInstance, data) {
var ctrl = this;
ctrl.confirm = confirm;
ctrl.cancel = cancel;
ctrl.data = angular.copy(data);
/**
* Initiate confirmation and call the success handler with the
* input text.
*/
function confirm() {
$uibModalInstance.close();
if (angular.isDefined(ctrl.data.successHandler)) {
ctrl.data.successHandler(ctrl.inputText);
}
}
/**
* Close the confirm modal without initiating changes.
*/
function cancel() {
$uibModalInstance.dismiss('cancel');
}
}
})();

View File

@ -19,9 +19,25 @@ RefStack
<li ng-class="{ active: header.isActive('/about')}"><a ui-sref="about">About</a></li>
<li ng-class="{ active: header.isActive('/guidelines')}"><a ui-sref="guidelines">DefCore Guidelines</a></li>
<li ng-class="{ active: header.isActive('/community_results')}"><a ui-sref="communityResults">Community Results</a></li>
<li ng-class="{ active: header.isCatalogActive('public')}" class="dropdown" uib-dropdown>
<a role="button" class="dropdown-toggle" uib-dropdown-toggle>
Catalog <strong class="caret"></strong>
</a>
<ul class="dropdown-menu">
<li><a ui-sref="publicVendors">Vendors</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li ng-class="{ active: header.isActive('/user_results')}" ng-if="auth.isAuthenticated"><a ui-sref="userResults">My Results</a></li>
<li ng-if="auth.isAuthenticated" ng-class="{ active: header.isCatalogActive('user')}" class="dropdown" uib-dropdown>
<a role="button" class="dropdown-toggle" uib-dropdown-toggle>
My Catalog <strong class="caret"></strong>
</a>
<ul class="dropdown-menu">
<li><a ui-sref="userVendors">My Vendors</a></li>
</ul>
</li>
<li ng-class="{ active: header.isActive('/profile')}" ng-if="auth.isAuthenticated"><a ui-sref="profile">Profile</a></li>
<li ng-if="auth.isAuthenticated"><a href="" ng-click="auth.doSignOut()">Sign Out</a></li>
<li ng-if="!auth.isAuthenticated"><a href="" ng-click="auth.doSignIn()">Sign In / Sign Up</a></li>

View File

@ -30,6 +30,7 @@
var ctrl = this;
ctrl.isActive = isActive;
ctrl.isCatalogActive = isCatalogActive;
/** Whether the Navbar is collapsed for small displays. */
ctrl.navbarCollapsed = true;
@ -49,5 +50,13 @@
}
return false;
}
/** This determines the active state for the catalog dropdown. Type
* parameter should be passed in to specify if the catalog is the
* public or user one.
*/
function isCatalogActive(type) {
return ctrl.isActive('/' + type + '_vendors');
}
}
})();

View File

@ -724,6 +724,40 @@ describe('Refstack controllers', function () {
});
});
describe('TestCustomConfirmModalController', function() {
var data, someFunc, modalInstance, ctrl;
beforeEach(inject(function ($controller) {
modalInstance = {
dismiss: jasmine.createSpy('modalInstance.dismiss'),
close: jasmine.createSpy('modalInstance.close')
};
someFunc = jasmine.createSpy('someFunc');
data = {
text: 'Some input',
successHandler: someFunc
};
ctrl = $controller('CustomConfirmModalController',
{$uibModalInstance: modalInstance, data: data}
);
}));
it('should have a function to confirm',
function () {
ctrl.inputText = 'foo';
ctrl.confirm();
expect(someFunc).toHaveBeenCalledWith('foo');
});
it('should have a function to dismiss the modal',
function () {
ctrl.cancel();
expect(modalInstance.dismiss).toHaveBeenCalledWith('cancel');
});
});
describe('AuthFailureController', function() {
var $location, ctrl;
@ -740,4 +774,177 @@ describe('Refstack controllers', function () {
expect(ctrl.message).toBe('some_error_message');
});
});
describe('VendorController', function() {
var rootScope, scope, stateParams, ctrl;
var confirmModal = jasmine.createSpy('confirmModal');
var fakeResp = {'id': 'fake-id', 'type': 1,
'can_manage': true, 'properties' : {}};
var fakeUsersResp = [{'openid': 'foo'}];
var fakeWindow = {
location: {
href: ''
}
};
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
rootScope = $rootScope.$new();
rootScope.auth = {'currentUser' : {'is_admin': false,
'openid': 'foo'}
};
stateParams = {vendorID: 1234};
ctrl = $controller('VendorController',
{$rootScope: rootScope, $scope: scope,
$stateParams: stateParams, $window: fakeWindow,
confirmModal: confirmModal}
);
$httpBackend.when('GET', fakeApiUrl +
'/vendors/1234').respond(fakeResp);
$httpBackend.when('GET', fakeApiUrl +
'/vendors/1234/users').respond(fakeUsersResp);
}));
it('should have a function to get vendor info from API',
function () {
ctrl.getVendor();
$httpBackend.flush();
expect(ctrl.vendor.id).toEqual('fake-id');
expect(ctrl.vendor.can_manage).toEqual(true);
expect(ctrl.vendor.canDelete).toEqual(true);
expect(ctrl.vendor.canRegister).toEqual(true);
expect(ctrl.vendor.canApprove).toEqual(false);
});
it('should have a function to get vendor users',
function () {
ctrl.getVendorUsers();
$httpBackend.flush();
expect(ctrl.vendorUsers).toEqual(fakeUsersResp);
expect(ctrl.currentUser).toEqual('foo');
});
it('should have a function to register a vendor',
function () {
$httpBackend.expectPOST(
fakeApiUrl + '/vendors/1234/action',
{'register': null})
.respond(201, '');
ctrl.registerVendor();
$httpBackend.flush();
});
it('should have a function to approve a vendor',
function () {
$httpBackend.expectPOST(
fakeApiUrl + '/vendors/1234/action',
{'approve': null})
.respond(201, '');
ctrl.approveVendor();
$httpBackend.flush();
});
it('a confirmation modal should come up when declining a vendor',
function () {
ctrl.declineVendor();
expect(confirmModal).toHaveBeenCalled();
});
it('should have a function to delete a vendor',
function () {
$httpBackend.expectDELETE(
fakeApiUrl + '/vendors/1234').respond(202, '');
ctrl.deleteVendor();
$httpBackend.flush();
expect(fakeWindow.location.href).toEqual('/');
});
it('should have to a function to remove a user from a vendor',
function () {
var fakeId = 'fake-id';
$httpBackend.expectDELETE(
fakeApiUrl + '/vendors/1234/users/' + btoa(fakeId))
.respond(202, '');
ctrl.removeUserFromVendor(fakeId);
$httpBackend.flush();
});
it('should have to a function to add a user to a vendor',
function () {
var fakeId = 'fake-id';
$httpBackend.expectPUT(
fakeApiUrl + '/vendors/1234/users/' + btoa(fakeId))
.respond(204, '');
ctrl.addUserToVendor(fakeId);
$httpBackend.flush();
});
});
describe('VendorsController', function() {
var rootScope, scope, ctrl;
var fakeResp = {'vendors': [{'can_manage': true,
'type': 3,
'name': 'Foo'},
{'can_manage': true,
'type': 3,
'name': 'Bar'}]};
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
rootScope = $rootScope.$new();
rootScope.auth = {'currentUser' : {'is_admin': false,
'openid': 'foo'}
};
ctrl = $controller('VendorsController',
{$rootScope: rootScope, $scope: scope}
);
$httpBackend.when('GET', fakeApiUrl +
'/vendors').respond(fakeResp);
}));
it('should have a function to get a listing of all vendors',
function () {
$httpBackend.expectGET(fakeApiUrl + '/vendors')
.respond(fakeResp);
ctrl.update();
$httpBackend.flush();
expect(ctrl.rawData).toEqual(fakeResp);
});
it('should have a function to update/sort data based on settings',
function () {
ctrl.rawData = fakeResp;
ctrl.updateData();
var expectedResponse = {'vendors': [{'can_manage': true,
'type': 3,
'name' : 'Bar'},
{'can_manage': true,
'type': 3,
'name': 'Foo'}]};
expect(ctrl.data).toEqual(expectedResponse);
});
it('should have a function to determine if a vendor should be shown',
function () {
var fakeVendor = {'type': 0, 'can_manage': false};
expect(ctrl._filterVendor(fakeVendor)).toEqual(true);
ctrl.isUserVendors = true;
expect(ctrl._filterVendor(fakeVendor)).toEqual(false);
ctrl.isUserVendors = false;
rootScope.auth.currentUser.is_admin = true;
expect(ctrl._filterVendor(fakeVendor)).toEqual(true);
});
it('should have a function to add a new vendor',
function () {
ctrl.name = 'New Vendor';
ctrl.description = 'A description';
$httpBackend.expectPOST(
fakeApiUrl + '/vendors',
{name: ctrl.name, description: ctrl.description})
.respond(200, fakeResp);
ctrl.addVendor();
$httpBackend.flush();
});
});
});