未验证 提交 07e7d5d3 编写于 作者: B bryk

Config category page

And a few fixes to the pagination in admin page.
上级 3230343c
......@@ -755,4 +755,7 @@
<translation id="5207082267245498149" key="MSG_BREADCRUMBS_SERVICES_AND_DISCOVERY_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label 'Services and discovery' that appears as a breadcrumbs on the action bar.">Services and discovery</translation>
<translation id="352791570684627676" key="MSG_SERVICES_AND_DISCOVERY_INGRESS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Ingress</translation>
<translation id="6306881076646050049" key="MSG_SERVICES_AND_DISCOVERY_SERVICES_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Services</translation>
<translation id="954605561178153927" key="MSG_BREADCRUMBS_CONFIG_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label 'Config' that appears as a breadcrumbs on the action bar.">Config</translation>
<translation id="3342283564584066330" key="MSG_CONFIG_CONFIG_MAPS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Config Maps</translation>
<translation id="7622819125555178514" key="MSG_CONFIG_SECRETS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Secrets</translation>
</translationbundle>
\ No newline at end of file
......@@ -948,4 +948,7 @@
<translation id="5207082267245498149" key="MSG_BREADCRUMBS_SERVICES_AND_DISCOVERY_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label 'Services and discovery' that appears as a breadcrumbs on the action bar.">Services and discovery</translation>
<translation id="352791570684627676" key="MSG_SERVICES_AND_DISCOVERY_INGRESS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Ingress</translation>
<translation id="6306881076646050049" key="MSG_SERVICES_AND_DISCOVERY_SERVICES_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Services</translation>
<translation id="954605561178153927" key="MSG_BREADCRUMBS_CONFIG_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label 'Config' that appears as a breadcrumbs on the action bar.">Config</translation>
<translation id="3342283564584066330" key="MSG_CONFIG_CONFIG_MAPS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Config Maps</translation>
<translation id="7622819125555178514" key="MSG_CONFIG_SECRETS_LABEL" source="/usr/local/google/home/bryk/src/github.com/kubernetes/dashboard/.tmp/serve/app-dev.js" desc="Label that appears above the list of resources.">Secrets</translation>
</translationbundle>
\ No newline at end of file
......@@ -26,6 +26,7 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/client"
"github.com/kubernetes/dashboard/src/app/backend/resource/admin"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"github.com/kubernetes/dashboard/src/app/backend/resource/config"
"github.com/kubernetes/dashboard/src/app/backend/resource/configmap"
"github.com/kubernetes/dashboard/src/app/backend/resource/container"
"github.com/kubernetes/dashboard/src/app/backend/resource/daemonset"
......@@ -198,6 +199,15 @@ func CreateHTTPAPIHandler(client *clientK8s.Client, heapsterClient client.Heapst
To(apiHandler.handleGetServicesAndDiscovery).
Writes(servicesanddiscovery.ServicesAndDiscovery{}))
apiV1Ws.Route(
apiV1Ws.GET("/config").
To(apiHandler.handleGetConfig).
Writes(config.Config{}))
apiV1Ws.Route(
apiV1Ws.GET("/config/{namespace}").
To(apiHandler.handleGetConfig).
Writes(config.Config{}))
apiV1Ws.Route(
apiV1Ws.GET("/replicaset").
To(apiHandler.handleGetReplicaSets).
......@@ -805,6 +815,19 @@ func (apiHandler *APIHandler) handleGetServicesAndDiscovery(
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleGetConfig(
request *restful.Request, response *restful.Response) {
namespace := parseNamespacePathParameter(request)
result, err := config.GetConfig(apiHandler.client, namespace)
if err != nil {
handleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
// Handles get Replica Sets list API call.
func (apiHandler *APIHandler) handleGetReplicaSets(
request *restful.Request, response *restful.Response) {
......@@ -1266,6 +1289,7 @@ func (apiHandler *APIHandler) handleGetResourceQuotaDetail(request *restful.Requ
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
// Handles log API call.
func (apiHandler *APIHandler) handleLogs(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
......
......@@ -74,9 +74,12 @@ type ResourceChannels struct {
// List and error channels to PetSets.
PetSetList PetSetListChannel
// List and error channels to PetSets.
// List and error channels to ConfigMaps.
ConfigMapList ConfigMapListChannel
// List and error channels to Secrets.
SecretList SecretListChannel
// List and error channels to PodMetrics.
PodMetrics PodMetricsChannel
......@@ -526,6 +529,39 @@ func GetConfigMapListChannel(client client.ConfigMapsNamespacer, nsQuery *Namesp
return channel
}
// SecretListChannel is a list and error channels to Secrets.
type SecretListChannel struct {
List chan *api.SecretList
Error chan error
}
// GetSecretListChannel returns a pair of channels to a Secret list and errors that
// both must be read numReads times.
func GetSecretListChannel(client client.SecretsNamespacer, nsQuery *NamespaceQuery, numReads int) SecretListChannel {
channel := SecretListChannel{
List: make(chan *api.SecretList, numReads),
Error: make(chan error, numReads),
}
go func() {
list, err := client.Secrets(nsQuery.ToRequestParam()).List(listEverything)
var filteredItems []api.Secret
for _, item := range list.Items {
if nsQuery.Matches(item.ObjectMeta.Namespace) {
filteredItems = append(filteredItems, item)
}
}
list.Items = filteredItems
for i := 0; i < numReads; i++ {
channel.List <- list
channel.Error <- err
}
}()
return channel
}
// PersistentVolumeListChannel is a list and error channels to PersistentVolumes.
type PersistentVolumeListChannel struct {
List chan *api.PersistentVolumeList
......
// 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.
package config
import (
"log"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"github.com/kubernetes/dashboard/src/app/backend/resource/configmap"
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"github.com/kubernetes/dashboard/src/app/backend/resource/secret"
k8sClient "k8s.io/kubernetes/pkg/client/unversioned"
)
// Config structure contains all resource lists grouped into the config category.
type Config struct {
ConfigMapList configmap.ConfigMapList `json:"configMapList"`
SecretList secret.SecretList `json:"secretList"`
}
// GetConfig returns a list of all config resources in the cluster.
func GetConfig(client *k8sClient.Client, nsQuery *common.NamespaceQuery) (
*Config, error) {
log.Printf("Getting config category")
channels := &common.ResourceChannels{
ConfigMapList: common.GetConfigMapListChannel(client, nsQuery, 1),
SecretList: common.GetSecretListChannel(client, nsQuery, 1),
}
return GetConfigFromChannels(channels)
}
// GetConfigFromChannels returns a list of all config in the cluster, from the
// channel sources.
func GetConfigFromChannels(channels *common.ResourceChannels) (
*Config, error) {
configMapChan := make(chan *configmap.ConfigMapList)
secretChan := make(chan *secret.SecretList)
numErrs := 2
errChan := make(chan error, numErrs)
go func() {
items, err := configmap.GetConfigMapListFromChannels(channels,
dataselect.DefaultDataSelect)
errChan <- err
configMapChan <- items
}()
go func() {
items, err := secret.GetSecretListFromChannels(channels, dataselect.DefaultDataSelect)
errChan <- err
secretChan <- items
}()
for i := 0; i < numErrs; i++ {
err := <-errChan
if err != nil {
return nil, err
}
}
config := &Config{
ConfigMapList: *(<-configMapChan),
SecretList: *(<-secretChan),
}
return config, nil
}
......@@ -16,11 +16,11 @@ package secret
import (
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
)
// SecretSpec - common interface for the specification of different secrets.
......@@ -86,6 +86,21 @@ func GetSecretList(client *client.Client, namespace *common.NamespaceQuery,
return NewSecretList(secretList.Items, dsQuery), err
}
// GetSecretListFromChannels returns a list of all Config Maps in the cluster
// reading required resource list once from the channels.
func GetSecretListFromChannels(channels *common.ResourceChannels, dsQuery *dataselect.DataSelectQuery) (
*SecretList, error) {
list := <-channels.SecretList.List
if err := <-channels.SecretList.Error; err != nil {
return nil, err
}
result := NewSecretList(list.Items, dsQuery)
return result, nil
}
// CreateSecret - create a single secret using the cluster API client
func CreateSecret(client *client.Client, spec SecretSpec) (*Secret, error) {
namespace := spec.GetNamespace()
......
......@@ -156,6 +156,14 @@ backendApi.Admin;
*/
backendApi.ServicesAndDiscovery;
/**
* @typedef {{
* configMapList: !backendApi.ConfigMapList,
* secretList: !backendApi.SecretList,
* }}
*/
backendApi.Config;
/**
* @typedef {{
* timestamp: string,
......@@ -919,7 +927,8 @@ backendApi.Secret;
/**
* @typedef {{
* secrets: !Array<!backendApi.Secret>
* secrets: !Array<!backendApi.Secret>,
* listMeta: !backendApi.ListMeta
* }}
*/
backendApi.SecretList;
......
......@@ -23,7 +23,7 @@ limitations under the License.
</kd-title>
<kd-content>
<kd-namespace-card-list namespace-list="$ctrl.admin.namespaceList" with-statuses="true"
namespace-list-resource="$ctrl.namespaceListResource">
namespace-list-resource="$ctrl.kdNamespaceListResource">
</kd-namespace-card-list>
</kd-content>
</kd-content-card>
......@@ -35,7 +35,7 @@ limitations under the License.
</kd-title>
<kd-content>
<kd-node-card-list node-list="$ctrl.admin.nodeList" with-statuses="true"
node-list-resource="$ctrl.nodeListResource">
node-list-resource="$ctrl.kdNodeListResource">
</kd-node-card-list>
</kd-content>
</kd-content-card>
......@@ -48,7 +48,7 @@ limitations under the License.
<kd-content>
<kd-persistent-volume-card-list persistent-volume-list="$ctrl.admin.persistentVolumeList"
with-statuses="true"
persistent-volume-list-resource="$ctrl.persistentVolumeListResource">
persistent-volume-list-resource="$ctrl.kdPersistentVolumeListResource">
</kd-persistent-volume-card-list>
</kd-content>
</kd-content-card>
......
......@@ -13,6 +13,7 @@
// limitations under the License.
import {stateName as adminState} from 'admin/state';
import {stateName as configState} from 'config/state';
import {stateName as configMapState} from 'configmaplist/configmaplist_state';
import {stateName as daemonSetState} from 'daemonsetlist/daemonsetlist_state';
import {stateName as deploymentState} from 'deploymentlist/deploymentlist_state';
......@@ -31,6 +32,7 @@ import {stateName as serviceState} from 'servicelist/servicelist_state';
import {stateName as servicesanddiscoveryState} from 'servicesanddiscovery/state';
import {stateName as workloadState} from 'workloads/workloads_state';
/**
* @final
*/
......@@ -66,6 +68,7 @@ export class NavController {
'configMap': configMapState,
'ingress': ingressState,
'serviceDiscovery': servicesanddiscoveryState,
'config': configState,
};
/** @export */
......
<!--
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.
-->
<div ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card ng-if="$ctrl.config.secretList.secrets.length">
<kd-title>
<a ui-sref="secret">
{{::$ctrl.i18n.MSG_CONFIG_SECRETS_LABEL}}
</a>
</kd-title>
<kd-content>
<kd-secret-card-list secret-list="$ctrl.config.secretList" with-statuses="true"
secret-list-resource="$ctrl.kdSecretListResource">
</kd-secret-card-list>
</kd-content>
</kd-content-card>
<kd-content-card ng-if="$ctrl.config.configMapList.items.length">
<kd-title>
<a ui-sref="configmap">
{{::$ctrl.i18n.MSG_CONFIG_CONFIG_MAPS_LABEL}}
</a>
</kd-title>
<kd-content>
<kd-config-map-card-list config-map-list="$ctrl.config.configMapList" with-statuses="true"
config-map-list-resource="$ctrl.kdConfigMapListResource">
</kd-config-map-card-list>
</kd-content>
</kd-content-card>
</div>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-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.
/**
* @final
*/
export class ConfigController {
/**
* @param {!backendApi.Config} config
* @param {!angular.Resource} kdConfigMapListResource
* @param {!angular.Resource} kdSecretListResource
* @ngInject
*/
constructor(config, kdConfigMapListResource, kdSecretListResource) {
/** @export {!backendApi.Config} */
this.config = config;
/** @export {!angular.Resource} */
this.kdConfigMapListResource = kdConfigMapListResource;
/** @export {!angular.Resource} */
this.kdSecretListResource = kdSecretListResource;
/** @export */
this.i18n = i18n;
}
/**
* @return {boolean}
* @export
*/
shouldShowZeroState() {
/** @type {number} */
let resourcesLength =
this.config.configMapList.listMeta.totalItems + this.config.secretList.listMeta.totalItems;
return resourcesLength === 0;
}
}
const i18n = {
/** @export {string} @desc Label that appears above the list of resources. */
MSG_CONFIG_CONFIG_MAPS_LABEL: goog.getMsg('Config Maps'),
/** @export {string} @desc Label that appears above the list of resources. */
MSG_CONFIG_SECRETS_LABEL: goog.getMsg('Secrets'),
};
// 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 chromeModule from 'chrome/chrome_module';
import configMapModule from 'configmaplist/configmaplist_module';
import secretModule from 'secretlist/module';
import stateConfig from './stateconfig';
/**
* Module for the config category.
*/
export default angular
.module(
'kubernetesDashboard.config',
[
'ngMaterial',
'ngResource',
'ui.router',
chromeModule.name,
configMapModule.name,
secretModule.name,
])
.config(stateConfig)
.factory('kdConfigResource', resource);
/**
* @param {!angular.$resource} $resource
* @return {!angular.Resource}
* @ngInject
*/
function resource($resource) {
return $resource('api/v1/config/:namespace');
}
// 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.
/** Name of the state. Can be used in, e.g., $state.go method. */
export const stateName = 'config';
/** Absolute URL of the state. */
export const stateUrl = '/config';
// 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 chromeStateName} from 'chrome/chrome_state';
import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service';
import {ConfigController} from './controller';
import {stateName} from './state';
import {stateUrl} from './state';
/**
* @param {!ui.router.$stateProvider} $stateProvider
* @ngInject
*/
export default function stateConfig($stateProvider) {
$stateProvider.state(stateName, {
url: stateUrl,
parent: chromeStateName,
resolve: {
'config': resolveResource,
},
data: {
[breadcrumbsConfig]: {
'label': i18n.MSG_BREADCRUMBS_CONFIG_LABEL,
},
},
views: {
'': {
controller: ConfigController,
controllerAs: '$ctrl',
templateUrl: 'config/config.html',
},
},
});
}
/**
* @param {!angular.$resource} kdConfigResource
* @param {!./../chrome/chrome_state.StateParams} $stateParams
* @param {!./../common/pagination/pagination_service.PaginationService} kdPaginationService
* @return {!angular.$q.Promise}
* @ngInject
*/
export function resolveResource(kdConfigResource, $stateParams, kdPaginationService) {
let paginationQuery = kdPaginationService.getDefaultResourceQuery($stateParams.namespace);
return kdConfigResource.get(paginationQuery).$promise;
}
const i18n = {
/** @type {string} @desc Label 'Config' that appears as a breadcrumbs on the
action bar. */
MSG_BREADCRUMBS_CONFIG_LABEL: goog.getMsg('Config'),
};
......@@ -18,6 +18,7 @@
*/
import adminModule from './admin/module';
import chromeModule from './chrome/chrome_module';
import configModule from './config/module';
import configMapDetailModule from './configmapdetail/configmapdetail_module';
import configMapListModule from './configmaplist/configmaplist_module';
import deployModule from './deploy/deploy_module';
......@@ -91,6 +92,7 @@ export default angular
ingressListModule.name,
ingressDetailModule.name,
servicesanddiscoveryModule.name,
configModule.name,
])
.config(indexConfig)
.config(routeConfig);
......@@ -23,7 +23,7 @@ limitations under the License.
</kd-title>
<kd-content>
<kd-service-card-list service-list="$ctrl.servicesAndDiscovery.serviceList" with-statuses="true"
service-list-resource="$ctrl.serviceListResource">
service-list-resource="$ctrl.kdServiceListResource">
</kd-service-card-list>
</kd-content>
</kd-content-card>
......@@ -35,7 +35,7 @@ limitations under the License.
</kd-title>
<kd-content>
<kd-ingress-card-list ingress-list="$ctrl.servicesAndDiscovery.ingressList" with-statuses="true"
ingress-list-resource="$ctrl.ingressListResource">
ingress-list-resource="$ctrl.kdIngressListResource">
</kd-ingress-card-list>
</kd-content>
</kd-content-card>
......
// 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 {ConfigController} from 'config/controller';
import module from 'config/module';
describe('Config list controller', () => {
/** @type {!config/config_controller.ConfigController}
*/
let ctrl;
beforeEach(() => {
angular.mock.module(module.name);
angular.mock.inject(
($controller) => { ctrl = $controller(ConfigController, {config: {config: []}}); });
});
it('should initialize config', angular.mock.inject(($controller) => {
let config = {config: 'foo-bar'};
/** @type {!ConfigController} */
let ctrl = $controller(ConfigController, {config: config});
expect(ctrl.config).toBe(config);
}));
it('should show zero state', () => {
// given
ctrl.config = {
secretList: {listMeta: {totalItems: 0}},
configMapList: {listMeta: {totalItems: 0}},
};
expect(ctrl.shouldShowZeroState()).toBe(true);
});
it('should hide zero state', () => {
// given
ctrl.config = {
secretList: {listMeta: {totalItems: 0}},
configMapList: {listMeta: {totalItems: 1}},
};
// then
expect(ctrl.shouldShowZeroState()).toBe(false);
});
});
// 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 module from 'config/module';
describe('Config module ', () => {
beforeEach(() => { angular.mock.module(module.name); });
it('should provide kdConfigResource', angular.mock.inject((kdConfigResource, $httpBackend) => {
kdConfigResource.get();
$httpBackend.expectGET('api/v1/config').respond();
$httpBackend.flush();
}));
});
// 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 module from 'config/module';
import {resolveResource} from 'config/stateconfig';
describe('StateConfig for config list', () => {
/** @type {!common/pagination/pagination_service.PaginationService} */
let kdPaginationService;
beforeEach(() => {
angular.mock.module(module.name);
angular.mock.inject(
(_kdPaginationService_) => { kdPaginationService = _kdPaginationService_; });
});
it('should resolve config', angular.mock.inject(($q) => {
let promise = $q.defer().promise;
let resource = jasmine.createSpyObj('$resource', ['get']);
resource.get.and.callFake(function() { return {$promise: promise}; });
let actual = resolveResource(resource, {namespace: 'foo-ns'}, kdPaginationService);
expect(resource.get)
.toHaveBeenCalledWith(kdPaginationService.getDefaultResourceQuery('foo-ns'));
expect(actual).toBe(promise);
}));
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册