提交 17965879 编写于 作者: S Sebastian Florek

Add generic delete actionbar item component

上级 e70b59c1
......@@ -13,7 +13,11 @@
// limitations under the License.
import {actionbarComponent} from './actionbar_component';
import {actionbarDeleteItemComponent} from './actionbardeleteitem_component';
import {breadcrumbsComponent} from './../breadcrumbs/breadcrumbs_component';
import {BreadcrumbsService} from './../breadcrumbs/breadcrumbs_service';
import resourceModule from 'common/resource/resource_module';
/**
* Module containing common actionbar.
*/
......@@ -23,6 +27,9 @@ export default angular
[
'ngMaterial',
'ui.router',
resourceModule.name,
])
.component('kdActionbar', actionbarComponent)
.component('kdBreadcrumbs', breadcrumbsComponent);
.component('kdBreadcrumbs', breadcrumbsComponent)
.component('kdActionbarDeleteItem', actionbarDeleteItemComponent)
.service('kdBreadcrumbsService', BreadcrumbsService);
<!--
Copyright 2015 Google Inc. All Rights Reserved.
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.
-->
<md-button ng-class="$ctrl.buttonClasses"
ng-click="$ctrl.remove()">
<md-icon class="kd-actionbar-icon-button">delete</md-icon>
<md-tooltip md-direction="bottom">Delete {{::$ctrl.resourceKindName}}</md-tooltip>
</md-button>
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
/**
* Controller for the action bar delete item component. It adds option to delete item from
* details page action bar.
*
* @final
*/
export class ActionbarDeleteItemController {
/**
* @param {!./../../resource/verber_service.VerberService} kdResourceVerberService
* @param {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} kdBreadcrumbsService
* @param {!ui.router.$state} $state
* @ngInject
*/
constructor(kdResourceVerberService, kdBreadcrumbsService, $state) {
/** @export {string} Initialized from a binding. */
this.resourceKindName;
/** @export {!backendApi.TypeMeta} Initialized from a binding. */
this.typeMeta;
/** @export {!backendApi.ObjectMeta} Initialized from a binding. */
this.objectMeta;
/** @export {boolean} Initialized from a binding. */
this.buttonClasses;
/** @private {!./../../resource/verber_service.VerberService} */
this.kdResourceVerberService_ = kdResourceVerberService;
/** @private {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} */
this.kdBreadcrumbsService_ = kdBreadcrumbsService;
/** @private {!ui.router.$state}} */
this.state_ = $state;
}
/**
* @export
*/
remove() {
this.kdResourceVerberService_
.showDeleteDialog(this.resourceKindName, this.typeMeta, this.objectMeta)
.then(() => {
let parentStateName =
this.kdBreadcrumbsService_.getParentStateName(this.state_['$current']);
this.state_.go(parentStateName);
});
}
}
/**
* Action bar delete item component should be used only on resource details page in order to
* add button that allows deletion of this resource.
*
* @type {!angular.Component}
*/
export const actionbarDeleteItemComponent = {
templateUrl: 'common/components/actionbar/actionbardeleteitem.html',
bindings: {
'resourceKindName': '@',
'typeMeta': '<',
'objectMeta': '<',
'buttonClasses': '@',
},
bindToController: true,
replace: true,
controller: ActionbarDeleteItemController,
};
......@@ -14,9 +14,6 @@
import Breadcrumb from './breadcrumb';
/** Breadcrumbs config string used on state config. **/
export const breadcrumbsConfig = 'kdBreadcrumbs';
/**
* @final
*/
......@@ -26,9 +23,10 @@ export default class BreadcrumbsController {
*
* @param {!ui.router.$state} $state
* @param {!angular.$interpolate} $interpolate
* @param {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} kdBreadcrumbsService
* @ngInject
*/
constructor($state, $interpolate) {
constructor($state, $interpolate, kdBreadcrumbsService) {
/** @private {!ui.router.$state} */
this.state_ = $state;
......@@ -40,6 +38,9 @@ export default class BreadcrumbsController {
/** @export {!Array<!Breadcrumb>} - Initialized in $onInit method. Used in template */
this.breadcrumbs;
/** @private {!./breadcrumbs_service.BreadcrumbsService} */
this.kdBreadcrumbsService_ = kdBreadcrumbsService;
}
/**
......@@ -67,7 +68,7 @@ export default class BreadcrumbsController {
breadcrumbs.push(breadcrumb);
}
state = this.getParentState_(state);
state = this.kdBreadcrumbsService_.getParentState(state);
}
return breadcrumbs.reverse();
......@@ -85,42 +86,6 @@ export default class BreadcrumbsController {
return this.limit === undefined || this.limit > breadcrumbs.length;
}
/**
* Returns breadcrumb config object if it is defined on state, undefined otherwise.
*
* @param {!ui.router.$state} state
* @return {Object}
* @private
*/
getBreadcrumbConfig_(state) {
let conf = state['data'];
if (conf) {
conf = conf[breadcrumbsConfig];
}
return conf;
}
/**
* Returns parent state of the given state based on defined state parent name or if it is not
* defined then based on direct parent state.
*
* @param {!ui.router.$state} state
* @return {!ui.router.$state}
* @private
*/
getParentState_(state) {
let conf = this.getBreadcrumbConfig_(state);
let result = state['parent'];
if (conf && conf.parent) {
result = this.state_.get(conf.parent);
}
return result;
}
/**
* Creates breadcrumb object based on state object.
*
......@@ -149,7 +114,7 @@ export default class BreadcrumbsController {
* @private
*/
getDisplayName_(state) {
let conf = this.getBreadcrumbConfig_(state);
let conf = this.kdBreadcrumbsService_.getBreadcrumbConfig(state);
let areLocalsDefined = !!state['locals'];
let interpolationContext = state;
......
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
import {stateName as defaultStateName} from 'workloads/workloads_state';
/** Breadcrumbs config string used on state config. **/
export const breadcrumbsConfig = 'kdBreadcrumbs';
export class BreadcrumbsService {
/**
* @param {!ui.router.$state} $state
* @ngInject
*/
constructor($state) { this.state_ = $state; }
/**
* Returns breadcrumb config object if it is defined on state, undefined otherwise.
*
* @param {!ui.router.$state} state
* @return {Object}
*/
getBreadcrumbConfig(state) {
let conf = state['data'];
if (conf) {
conf = conf[breadcrumbsConfig];
}
return conf;
}
/**
* Returns parent state of the given state based on defined state parent name or if it is not
* defined then based on direct parent state.
*
* @param {!ui.router.$state} state
* @return {!ui.router.$state}
*/
getParentState(state) {
let conf = this.getBreadcrumbConfig(state);
let result = state['parent'];
if (conf && conf.parent) {
result = this.state_.get(conf.parent);
}
return result;
}
/**
* Returns parent state name of the given state based on defined state parent name or if it is not
* defined then default state name is returned.
*
* @param {!ui.router.$state} state
* @return {string}
*/
getParentStateName(state) {
let conf = this.getBreadcrumbConfig(state);
if (conf && conf.parent) {
return conf.parent;
}
return defaultStateName;
}
}
......@@ -20,10 +20,9 @@ export class ResourceCardDeleteMenuItemController {
/**
* @param {!./../../resource/verber_service.VerberService} kdResourceVerberService
* @param {!ui.router.$state} $state
* @param {!md.$dialog} $mdDialog
* @ngInject
*/
constructor(kdResourceVerberService, $state, $mdDialog) {
constructor(kdResourceVerberService, $state) {
/**
* Initialized from require just before $onInit is called.
* @export {!./resourcecard_component.ResourceCardController}
......@@ -38,9 +37,6 @@ export class ResourceCardDeleteMenuItemController {
/** @private {!ui.router.$state}} */
this.state_ = $state;
/** @private {!md.$dialog} */
this.mdDialog_ = $mdDialog;
}
/**
......@@ -50,20 +46,10 @@ export class ResourceCardDeleteMenuItemController {
this.kdResourceVerberService_
.showDeleteDialog(
this.resourceKindName, this.resourceCardCtrl.typeMeta, this.resourceCardCtrl.objectMeta)
.then(
() => {
// For now just reload the state. Later we can remove the item in place.
this.state_.reload();
},
(/** angular.$http.Response|null */ err) => {
if (err) {
// Show dialog if there was an error, not user canceling dialog.
this.mdDialog_.show(this.mdDialog_.alert()
.ok('Ok')
.title(err.statusText || 'Internal server error')
.textContent(err.data || 'Could not delete the resource'));
}
});
.then(() => {
// For now just reload the state. Later we can remove the item in place.
this.state_.reload();
});
}
}
......
......@@ -21,6 +21,7 @@ export class DeleteResourceController {
/**
* @param {!md.$dialog} $mdDialog
* @param {!angular.$resource} $resource
* @param {string} resourceKindName
* @param {!backendApi.TypeMeta} typeMeta
* @param {!backendApi.ObjectMeta} objectMeta
* @ngInject
......
......@@ -23,6 +23,7 @@ export default angular
'kubernetesDashboard.common.resource',
[
'ngMaterial',
'ui.router',
'ngResource',
])
.service('kdResourceVerberService', VerberService);
......@@ -22,11 +22,15 @@ import showDeleteDialog from './deleteresource_dialog';
export class VerberService {
/**
* @param {!md.$dialog} $mdDialog
* @param {!angular.$q} $q
* @ngInject
*/
constructor($mdDialog) {
constructor($mdDialog, $q) {
/** @private {!md.$dialog} */
this.mdDialog_ = $mdDialog;
/** @private {!angular.$q} */
this.q_ = $q;
}
/**
......@@ -38,6 +42,30 @@ export class VerberService {
* @return {!angular.$q.Promise}
*/
showDeleteDialog(resourceKindName, typeMeta, objectMeta) {
return showDeleteDialog(this.mdDialog_, resourceKindName, typeMeta, objectMeta);
let deferred = this.q_.defer();
showDeleteDialog(this.mdDialog_, resourceKindName, typeMeta, objectMeta)
.then(() => { deferred.resolve(); })
.catch((err) => {
this.deleteErrorCallback(err);
deferred.reject(err);
});
return deferred.promise;
}
/**
* Callback function to show dialog with error message if resource deletion fails.
*
* @param {angular.$http.Response|null} err
*/
deleteErrorCallback(err) {
if (err) {
// Show dialog if there was an error, not user canceling dialog.
this.mdDialog_.show(this.mdDialog_.alert()
.ok('Ok')
.title(err.statusText || 'Internal server error')
.textContent(err.data || 'Could not delete the resource'));
}
}
}
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {DeploymentListController} from './deploymentlist_controller';
import {stateName, stateUrl} from './deploymentlist_state';
import {stateName as workloadsState} from 'workloads/workloads_state';
......
......@@ -19,7 +19,9 @@ limitations under the License.
<div class="kd-replicationcontrollerevents-options" layout="row">
<md-input-container>
<label>Type</label>
<md-select ng-model="$ctrl.eventType" ng-change="$ctrl.handleEventFiltering()" required>
<md-select aria-label="Event Type" ng-model="$ctrl.eventType"
ng-change="$ctrl.handleEventFiltering()"
required>
<md-option ng-repeat="type in $ctrl.eventTypeFilter" ng-value="type">
{{type}}
</md-option>
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {PodDetailController} from './poddetail_controller';
import {stateName as podList, stateUrl} from 'podlist/podlist_state';
import {stateName} from './poddetail_state';
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {PodListController} from './podlist_controller';
import {stateName, stateUrl} from './podlist_state';
import {stateName as workloadsState} from 'workloads/workloads_state';
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {ReplicaSetDetailController} from './replicasetdetail_controller';
import {stateName as replicaSetList, stateUrl} from 'replicasetlist/replicasetlist_state';
import {stateName} from './replicasetdetail_state';
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {ReplicaSetListController} from './replicasetlist_controller';
import {stateName, stateUrl} from './replicasetlist_state';
import {stateName as workloadsState} from 'workloads/workloads_state';
......
......@@ -13,10 +13,10 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {stateName} from './replicationcontrollerdetail_state';
import {stateName as replicationControllers} from 'replicationcontrollerlist/replicationcontrollerlist_state';
import ReplicationControllerDetailActionBarController from './replicationcontrollerdetailactionbar_controller';
import {ReplicationControllerDetailActionBarController} from './replicationcontrollerdetailactionbar_controller';
import ReplicationControllerDetailController from './replicationcontrollerdetail_controller';
/**
......
......@@ -23,10 +23,11 @@ limitations under the License.
<md-icon class="kd-actionbar-icon-button">mode_edit</md-icon>
<md-tooltip md-direction="bottom">Edit number of pods</md-tooltip>
</md-button>
<md-button class="md-icon-button" ng-click="ctrl.handleDeleteReplicationControllerDialog()">
<md-icon class="kd-actionbar-icon-button">delete</md-icon>
<md-tooltip md-direction="bottom">Delete replication controller</md-tooltip>
</md-button>
<kd-actionbar-delete-item resource-kind-name="Replication Controller"
type-meta="ctrl.details.typeMeta"
object-meta="ctrl.details.objectMeta"
button-classes="md-icon-button">
</kd-actionbar-delete-item>
</div>
<div hide-gt-sm>
......@@ -38,10 +39,11 @@ limitations under the License.
</md-button>
</md-fab-trigger>
<md-fab-actions>
<md-button class="md-fab md-raised md-mini" ng-click="ctrl.handleDeleteReplicationControllerDialog()">
<md-icon class="kd-actionbar-icon-button">delete</md-icon>
<md-tooltip md-direction="bottom">Delete replication controller</md-tooltip>
</md-button>
<kd-actionbar-delete-item resource-kind-name="Replication Controller"
type-meta="ctrl.details.typeMeta"
object-meta="ctrl.details.objectMeta"
button-classes="md-fab md-raised md-mini">
</kd-actionbar-delete-item>
<md-button class="md-fab md-raised md-mini" ng-click="ctrl.handleUpdateReplicasDialog()">
<md-icon class="kd-actionbar-icon-button">mode_edit</md-icon>
<md-tooltip md-direction="bottom">Edit number of pods</md-tooltip>
......
......@@ -13,39 +13,29 @@
// limitations under the License.
import {stateName as deploy} from 'deploy/deploy_state';
import {stateName as replicationcontrollers} from 'replicationcontrollerlist/replicationcontrollerlist_state';
/**
* @final
*/
export default class ReplicationControllerDetailActionBarController {
export class ReplicationControllerDetailActionBarController {
/**
* Constructs action bar on rc detail page.
*
* @param {ui.router.$state} $state
* @param {!./replicationcontrollerdetail_state.StateParams} $stateParams
* @param {!angular.$log} $log
* @param {!backendApi.ReplicationControllerDetail} replicationControllerDetail
* @param {!./replicationcontroller_service.ReplicationControllerService}
* kdReplicationControllerService
* @ngInject
*/
constructor(
$state, $stateParams, $log, replicationControllerDetail, kdReplicationControllerService) {
constructor($state, replicationControllerDetail, kdReplicationControllerService) {
/** @private {ui.router.$state} */
this.state_ = $state;
/** @private {!./replicationcontrollerdetail_state.StateParams} */
this.stateParams_ = $stateParams;
/** @private {!angular.$log} */
this.log_ = $log;
/** @private {!./replicationcontroller_service.ReplicationControllerService} */
this.kdReplicationControllerService_ = kdReplicationControllerService;
/** @private {!backendApi.ReplicationControllerDetail} */
this.details_ = replicationControllerDetail;
/** @export {!backendApi.ReplicationControllerDetail} */
this.details = replicationControllerDetail;
/** @export {boolean} */
this.showFabIcons = false;
......@@ -72,32 +62,7 @@ export default class ReplicationControllerDetailActionBarController {
*/
handleUpdateReplicasDialog() {
this.kdReplicationControllerService_.showUpdateReplicasDialog(
this.details_.objectMeta.namespace, this.details_.objectMeta.name,
this.details_.podInfo.current, this.details_.podInfo.desired);
}
/**
* Handles replication controller delete dialog.
* @export
*/
handleDeleteReplicationControllerDialog() {
this.kdReplicationControllerService_
.showDeleteDialog(this.details_.typeMeta, this.details_.objectMeta)
.then(this.onReplicationControllerDeleteSuccess_.bind(this));
}
/**
* Callbacks used after clicking dialog confirmation button in order to delete replication
* controller or log unsuccessful operation error.
*/
/**
* Changes state back to replication controller list after successful deletion of replication
* controller.
* @private
*/
onReplicationControllerDeleteSuccess_() {
this.log_.info('Replication controller successfully deleted.');
this.state_.go(replicationcontrollers);
this.details.objectMeta.namespace, this.details.objectMeta.name,
this.details.podInfo.current, this.details.podInfo.desired);
}
}
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {ReplicationControllerListController} from './replicationcontrollerlist_controller';
import {stateName, stateUrl} from './replicationcontrollerlist_state';
import {stateName as workloadsState} from 'workloads/workloads_state';
......
......@@ -13,7 +13,7 @@
// limitations under the License.
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {stateName} from './servicedetail_state';
import {stateName as serviceList, stateUrl} from './../servicelist/servicelist_state';
import {ServiceDetailController} from './servicedetail_controller';
......
......@@ -14,7 +14,7 @@
import {ServiceListController} from './servicelist_controller';
import {actionbarViewName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {stateName, stateUrl} from './servicelist_state';
/**
......
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import componentsModule from 'common/components/components_module';
describe('Actionbar delete item component', () => {
/** @type {BreadcrumbsController} */
let ctrl;
/** @type {ui.router.$state} */
let state;
/** @type !{!common/resource/verber_service.VerberService} */
let kdResourceVerberService;
/** @type {!angular.$q} **/
let q;
/** @type {!angular.$scope} **/
let scope;
/**
* Create simple mock object for state.
*
* @param {string} stateName
* @param {string} stateLabel
* @param {string} stateParent
* @return {{name: string, kdBreadcrumbs: {label: string}}}
*/
function getStateMock(stateName, stateLabel, stateParent) {
return {
name: stateName,
data: {
[breadcrumbsConfig]: {
label: stateLabel,
parent: stateParent,
},
},
};
}
beforeEach(() => {
angular.mock.module(componentsModule.name);
angular.mock.inject(
($componentController, $state, _kdBreadcrumbsService_, _kdResourceVerberService_, $q,
$rootScope) => {
state = $state;
kdResourceVerberService = _kdResourceVerberService_;
q = $q;
scope = $rootScope.$new();
ctrl = $componentController(
'kdActionbarDeleteItem', {
$state: state,
kdBreadcrumbsService: _kdBreadcrumbsService_,
kdResourceVerberService: _kdResourceVerberService_,
},
{
resourceKindName: 'resource',
typeMeta: {},
objectMeta: {},
});
});
});
it('should go to parent state on delete success', () => {
// given
let deferred = q.defer();
let httpStatusOk = 200;
spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise);
spyOn(state, 'go');
state.$current = getStateMock('testState', 'testLabel', 'testParent');
// when
ctrl.remove();
deferred.resolve(httpStatusOk);
scope.$digest();
// then
expect(state.go).toHaveBeenCalledWith('testParent');
});
});
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import componentsModule from 'common/components/components_module';
describe('Breadcrumbs controller ', () => {
......@@ -66,13 +66,14 @@ describe('Breadcrumbs controller ', () => {
beforeEach(() => {
angular.mock.module(componentsModule.name);
angular.mock.inject(($componentController, $state, $interpolate) => {
angular.mock.inject(($componentController, $state, $interpolate, _kdBreadcrumbsService_) => {
state = $state;
interpolate = $interpolate;
ctrl = $componentController(
'kdBreadcrumbs', {
$state: state,
$interpolate: interpolate,
kdBreadcrumbsService: _kdBreadcrumbsService_,
},
{
limit: breadcrumbsLimit,
......@@ -144,30 +145,6 @@ describe('Breadcrumbs controller ', () => {
expect(canBeAdded).toBeFalsy();
});
it('should return parent state when breadcrumb parent is not defined', () => {
// given
state.parent = getStateMock('parentState');
// when
let parent = ctrl.getParentState_(state);
// expect
expect(parent).toEqual(state.parent);
});
it('should return defined parent when breadcrumb parent is defined', () => {
// given
state.data = {kdBreadcrumbs: {parent: 'parentState'}};
let parent = getStateMock('parentState');
spyOn(state, 'get').and.returnValue(parent);
// when
let result = ctrl.getParentState_(state);
// expect
expect(result).toEqual(parent);
});
it('should return breadcrumb object', () => {
// given
spyOn(state, 'href').and.returnValue('stateLink');
......@@ -221,23 +198,4 @@ describe('Breadcrumbs controller ', () => {
// then
expect(result).toEqual(state.name);
});
it('should return breadcrumb config when it is defined', () => {
// given
let stateMock = getStateMock('testState');
// when
let result = ctrl.getBreadcrumbConfig_(stateMock);
// then
expect(result).toBeDefined();
});
it('should return undefined when breadcrumb config is not defined', () => {
// when
let result = ctrl.getBreadcrumbConfig_(state);
// then
expect(result).toBeUndefined();
});
});
// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {stateName as defaultStateName} from 'workloads/workloads_state';
import componentsModule from 'common/components/components_module';
describe('Breadcrumbs service ', () => {
/** @type {ui.router.$state} */
let state;
/** @type {BreadcrumbsController} */
let breadcrumbsService;
/**
* Create simple mock object for state.
*
* @param {string} stateName
* @param {string} stateLabel
* @param {string} stateParent
* @return {{name: string, kdBreadcrumbs: {label: string}}}
*/
function getStateMock(stateName, stateLabel, stateParent) {
return {
name: stateName,
data: {
[breadcrumbsConfig]: {
label: stateLabel,
parent: stateParent,
},
},
};
}
beforeEach(() => {
angular.mock.module(componentsModule.name);
angular.mock.inject((_kdBreadcrumbsService_, $state) => {
state = $state;
breadcrumbsService = _kdBreadcrumbsService_;
});
});
it('should return parent state when breadcrumb parent is not defined', () => {
// given
state.parent = getStateMock('parentState');
// when
let parent = breadcrumbsService.getParentState(state);
// expect
expect(parent).toEqual(state.parent);
});
it('should return defined parent when breadcrumb parent is defined', () => {
// given
state.data = {kdBreadcrumbs: {parent: 'parentState'}};
let parent = getStateMock('parentState');
spyOn(state, 'get').and.returnValue(parent);
// when
let result = breadcrumbsService.getParentState(state);
// expect
expect(result).toEqual(parent);
});
it('should return breadcrumb config when it is defined', () => {
// given
let stateMock = getStateMock('testState');
// when
let result = breadcrumbsService.getBreadcrumbConfig(stateMock);
// then
expect(result).toBeDefined();
});
it('should return undefined when breadcrumb config is not defined', () => {
// when
let result = breadcrumbsService.getBreadcrumbConfig(state);
// then
expect(result).toBeUndefined();
});
it('should return default state name when parent not defined', () => {
// when
let result = breadcrumbsService.getParentStateName(state);
// then
expect(result).toEqual(defaultStateName);
});
it('should return parent state name when it is defined', () => {
// given
let stateMock = getStateMock('testState', 'testLabel', 'testParent');
// when
let result = breadcrumbsService.getParentStateName(stateMock);
// then
expect(result).toEqual('testParent');
});
});
......@@ -19,18 +19,29 @@ describe('Verber service', () => {
let verber;
/** @type {!md.$dialog} */
let mdDialog;
/** @type {!angular.$q} **/
let q;
/** @type {!angular.$scope} **/
let scope;
/** @type {!ui.router.State} **/
let state;
beforeEach(() => angular.mock.module(resourceModule.name));
beforeEach(angular.mock.inject((kdResourceVerberService, $mdDialog) => {
beforeEach(angular.mock.inject((kdResourceVerberService, $mdDialog, $q, $rootScope, $state) => {
verber = kdResourceVerberService;
mdDialog = $mdDialog;
q = $q;
scope = $rootScope.$new();
state = $state;
}));
it('should show delete dialog resource', () => {
let promise = {};
spyOn(mdDialog, 'show').and.returnValue(promise);
let actual = verber.showDeleteDialog('Foo resource', {foo: 'bar'}, {baz: 'qux'});
let deferred = q.defer();
spyOn(mdDialog, 'show').and.returnValue(deferred.promise);
verber.showDeleteDialog('Foo resource', {foo: 'bar'}, {baz: 'qux'});
expect(mdDialog.show).toHaveBeenCalledWith(jasmine.objectContaining({
locals: {
'resourceKindName': 'Foo resource',
......@@ -38,6 +49,18 @@ describe('Verber service', () => {
'objectMeta': {baz: 'qux'},
},
}));
expect(actual).toBe(promise);
});
it('should show alert window on error', () => {
let deferred = q.defer();
spyOn(mdDialog, 'show').and.returnValue(deferred.promise);
spyOn(state, 'reload');
spyOn(mdDialog, 'alert').and.callThrough();
verber.showDeleteDialog();
deferred.reject({data: 'foo-data', statusText: 'foo-text'});
scope.$digest();
expect(state.reload).not.toHaveBeenCalled();
expect(mdDialog.alert).toHaveBeenCalled();
});
});
......@@ -50,12 +50,13 @@ describe('Delete resource menu item', () => {
it('should delete the resource', () => {
let deferred = q.defer();
let httpStatusOk = 200;
spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise);
spyOn(state, 'reload');
ctrl.remove();
expect(state.reload).not.toHaveBeenCalled();
deferred.resolve();
deferred.resolve(httpStatusOk);
scope.$digest();
expect(state.reload).toHaveBeenCalled();
});
......@@ -72,17 +73,4 @@ describe('Delete resource menu item', () => {
expect(state.reload).not.toHaveBeenCalled();
expect(mdDialog.alert).not.toHaveBeenCalled();
});
it('should show alert window on error', () => {
let deferred = q.defer();
spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise);
spyOn(state, 'reload');
spyOn(mdDialog, 'alert').and.callThrough();
ctrl.remove();
deferred.reject({data: 'foo-data', statusText: 'foo-text'});
scope.$digest();
expect(state.reload).not.toHaveBeenCalled();
expect(mdDialog.alert).toHaveBeenCalled();
});
});
......@@ -12,52 +12,40 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import ReplicationControllerDetailActionBarController from 'replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller';
import {ReplicationControllerDetailActionBarController} from 'replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller';
import replicationControllerDetailModule from 'replicationcontrollerdetail/replicationcontrollerdetail_module';
import {stateName as replicationcontrollers} from 'replicationcontrollerlist/replicationcontrollerlist_state';
import {stateName as deploy} from 'deploy/deploy_state';
describe('Replication Controller Detail Action Bar controller', () => {
/**
* Replication Controller Detail controller.
* @type {!ReplicationControllerDetailController}
* Replication Controller Detail Action Bar controller.
* @type {!ReplicationControllerDetailActionBarController}
*/
let ctrl;
/** @type
* {!replicationcontrollerdetail/replicationcontroller_service.ReplicationControllerService} */
let kdReplicationControllerService;
/** @type {!angular.$q} */
let q;
/** @type {!ui.router.$state} */
let state;
/** @type {!angular.$log} */
let log;
beforeEach(() => {
angular.mock.module(replicationControllerDetailModule.name);
angular.mock.inject(
($controller, $state, $log, $resource, $q, _kdReplicationControllerService_) => {
q = $q;
state = $state;
log = $log;
kdReplicationControllerService = _kdReplicationControllerService_;
ctrl = $controller(ReplicationControllerDetailActionBarController, {
$state: state,
$stateParams: {
replicationController:
{objectMeta: {name: 'foo-replicationcontroller', namespace: 'foo-namespace'}},
},
replicationControllerDetail: {},
kdReplicationControllerService: _kdReplicationControllerService_,
});
});
angular.mock.inject(($controller, $state, $resource, _kdReplicationControllerService_) => {
state = $state;
kdReplicationControllerService = _kdReplicationControllerService_;
ctrl = $controller(ReplicationControllerDetailActionBarController, {
$state: state,
replicationControllerDetail: {},
kdReplicationControllerService: _kdReplicationControllerService_,
});
});
});
it('should show edit replicas dialog', () => {
// given
ctrl.details_ = {
ctrl.details = {
objectMeta: {
namespace: 'foo-namespace',
name: 'foo-name',
......@@ -76,31 +64,6 @@ describe('Replication Controller Detail Action Bar controller', () => {
expect(kdReplicationControllerService.showUpdateReplicasDialog).toHaveBeenCalled();
});
it('should show delete replicas dialog', () => {
// given
let deferred = q.defer();
spyOn(kdReplicationControllerService, 'showDeleteDialog').and.returnValue(deferred.promise);
// when
ctrl.handleDeleteReplicationControllerDialog();
// then
expect(kdReplicationControllerService.showDeleteDialog).toHaveBeenCalled();
});
it('should change state to replication controller and log on delete success', () => {
// given
spyOn(state, 'go');
spyOn(log, 'info');
// when
ctrl.onReplicationControllerDeleteSuccess_();
// then
expect(state.go).toHaveBeenCalledWith(replicationcontrollers);
expect(log.info).toHaveBeenCalledWith('Replication controller successfully deleted.');
});
it('should redirect to deploy page', () => {
// given
spyOn(state, 'go');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册