Dashboard: Created tests + refactoring of last workspaces

Signed-off-by: Lucia Jelinkova <ljelinko@redhat.com>
7.20.x
Lucia Jelinkova 2019-04-05 15:27:59 +02:00 committed by Anna Shumilova
parent 601990fba4
commit 1bd375bfd0
4 changed files with 296 additions and 17 deletions

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
import { DashboardLastWorkspacesController } from "./last-workspaces.controller";
import { CheWorkspace } from "../../../components/api/workspace/che-workspace.factory";
import { CheNotification } from "../../../components/notification/che-notification.factory";
/**
* @author Lucia Jelinkova
*/
describe(`Last workspaces controller >`, () => {
let controller: DashboardLastWorkspacesController;
let cheWorkspace: CheWorkspace;
let cheNotification: CheNotification;
beforeEach(() => {
// tell angular to mock the module
angular.mock.module('userDashboard');
// retrieve all necessary services
inject((
_$controller_: ng.IControllerService,
_cheWorkspace_: CheWorkspace,
_cheNotification_: CheNotification) => {
// get the tested controller from ng.IControllerService
controller = _$controller_('DashboardLastWorkspacesController');
cheWorkspace = _cheWorkspace_;
cheNotification = _cheNotification_
})
});
it('loadData - workspaces pre-loaded', async () => {
spyOn(cheWorkspace, 'getWorkspaces').and.returnValue([jasmine.createSpy('IWorkspace')]);
spyOn(cheWorkspace, 'fetchWorkspaces');
spyOn(cheNotification, 'showError');
expect(controller.isLoading).toBeTruthy();
await controller.loadData();
expect(controller.isLoading).toBeFalsy();
expect(cheWorkspace.getWorkspaces).toHaveBeenCalledTimes(1);
expect(cheWorkspace.fetchWorkspaces).not.toHaveBeenCalled();
expect(cheNotification.showError).not.toHaveBeenCalled();
expect(controller.workspaces.length).toBe(1);
});
it('loadData - fetch workspaces - no workspaces', async () => {
spyOn(cheWorkspace, 'getWorkspaces').and.returnValue([]);
spyOn(cheWorkspace, 'fetchWorkspaces').and.returnValue(Promise.resolve([]));
spyOn(cheNotification, 'showError');
expect(controller.isLoading).toBeTruthy();
await controller.loadData();
expect(controller.isLoading).toBeFalsy();
expect(cheWorkspace.getWorkspaces).toHaveBeenCalledTimes(1);
expect(cheWorkspace.fetchWorkspaces).toHaveBeenCalledTimes(1);
expect(cheNotification.showError).not.toHaveBeenCalled();
expect(controller.workspaces.length).toBe(0);
});
it('loadData - fetch workspaces', async () => {
spyOn(cheWorkspace, 'getWorkspaces').and.returnValue([]);
spyOn(cheWorkspace, 'fetchWorkspaces').and.returnValue(Promise.resolve([jasmine.createSpy('IWorkspace')]));
spyOn(cheNotification, 'showError');
expect(controller.isLoading).toBeTruthy();
await controller.loadData();
expect(controller.isLoading).toBeFalsy();
expect(cheWorkspace.getWorkspaces).toHaveBeenCalledTimes(1);
expect(cheWorkspace.fetchWorkspaces).toHaveBeenCalledTimes(1);
expect(cheNotification.showError).not.toHaveBeenCalled();
expect(controller.workspaces.length).toBe(1);
});
it('loadData - general error handling', async () => {
spyOn(cheWorkspace, 'getWorkspaces').and.returnValue([]);
spyOn(cheWorkspace, 'fetchWorkspaces').and.returnValue(createGeneralError());
spyOn(cheNotification, 'showError').and.callFake((args) => {
expect(args).toBe('Update workspaces failed.');
});
expect(controller.isLoading).toBeTruthy();
await controller.loadData();
expect(controller.isLoading).toBeFalsy();
expect(cheWorkspace.getWorkspaces).toHaveBeenCalledTimes(1);
expect(cheWorkspace.fetchWorkspaces).toHaveBeenCalledTimes(1);
expect(cheNotification.showError).toHaveBeenCalledTimes(1);
});
it('loadData - http error handling', async () => {
spyOn(cheWorkspace, 'getWorkspaces').and.returnValue([]);
spyOn(cheWorkspace, 'fetchWorkspaces').and.returnValue(createHTTPError('Error message'));
spyOn(cheNotification, 'showError').and.callFake((args) => {
expect(args).toBe('Error message');
});
expect(controller.isLoading).toBeTruthy();
await controller.loadData();
expect(controller.isLoading).toBeFalsy();
expect(cheWorkspace.getWorkspaces).toHaveBeenCalledTimes(1);
expect(cheWorkspace.fetchWorkspaces).toHaveBeenCalledTimes(1);
expect(cheNotification.showError).toHaveBeenCalledTimes(1);
});
function createGeneralError(): Promise<any> {
return Promise.reject("This is some error");
}
function createHTTPError(message: string): Promise<any> {
var error = {
'status': status,
'data': {
'message': message
}
}
return Promise.reject(error);
}
});

View File

@ -25,8 +25,8 @@ export class DashboardLastWorkspacesController {
cheWorkspace: CheWorkspace;
cheNotification: CheNotification;
workspaces: Array<che.IWorkspace>;
isLoading: boolean;
workspaces: Array<che.IWorkspace> = [];
isLoading: boolean = true;
/**
* Default constructor
@ -35,28 +35,28 @@ export class DashboardLastWorkspacesController {
this.cheWorkspace = cheWorkspace;
this.cheNotification = cheNotification;
this.workspaces = cheWorkspace.getWorkspaces();
if (this.workspaces.length === 0) {
this.updateData();
}
this.loadData();
}
/**
* Update workspaces
* Load workspaces
*/
updateData(): void {
this.isLoading = true;
loadData(): void {
this.workspaces = this.cheWorkspace.getWorkspaces();
if (this.workspaces.length > 0) {
this.isLoading = false;
return;
}
let promise = this.cheWorkspace.fetchWorkspaces();
promise.then(() => {
promise.then((result) => {
this.workspaces = result;
this.isLoading = false;
}, (error: any) => {
this.isLoading = false;
if (error.status === 304) {
return;
}
this.cheNotification.showError(error.data.message !== null ? error.data.message : 'Update workspaces failed.');
this.cheNotification.showError(error.data && error.data.message ? error.data.message : 'Update workspaces failed.');
});
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2015-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
import { IAugmentedJQuery, ITemplateCacheService, ICompileService, IRootScopeService, ICompileProvider } from "angular";
import { CheHttpBackend } from "../../../components/api/test/che-http-backend";
/**
* @author Lucia Jelinkova
*/
describe(`Last workspaces directive >`, () => {
let $compile: ICompileService;
let $scope: any;
let directiveElement: IAugmentedJQuery;
beforeAll(() => {
// this call replaces the inner directive <che-workspace-item> with mocked value.
// the reason is that we want to test only <dashboard-last-workspaces> itself and not
// underlying directives. Those should be tested separately.
// NOTE: it is possible that if another test mocks the same directive, it will fail. In that
// case the whole call needs to be extracted and executed before all .spec files.
angular.module('userDashboard').config(function ($compileProvider: ICompileProvider) {
$compileProvider.directive('cheWorkspaceItem', function () {
var def = {
// directive with the highest priority is executed first
priority: 100,
// if set to false also directives with lower priorities would be executed
terminal: true,
// the same as original directive
restrict: 'E',
// mocked output
template: '<div class="workspace-mock">Mocked workspace</div>',
};
return def;
});
});
});
beforeEach(() => {
angular.mock.module('userDashboard');
inject((
_$compile_: ng.ICompileService,
_$rootScope_: IRootScopeService,
_cheHttpBackend_: CheHttpBackend) => {
$compile = _$compile_;
$scope = _$rootScope_.$new();
let $httpBackend = _cheHttpBackend_.getHttpBackend();
$httpBackend.whenGET(/.*/).respond(200, '');
$httpBackend.when('OPTIONS', '/api/').respond({});
})
});
beforeEach(() => {
directiveElement = $compile(" <dashboard-last-workspaces></dashboard-last-workspaces>")($scope);
$scope.$digest();
});
it('no workspaces', async () => {
noWorkspacesDirectiveTest();
});
it('one workspace', async () => {
moreWorkspacesDirectiveTest(1);
});
it('5 workspaces', async () => {
moreWorkspacesDirectiveTest(5);
});
it('6 workspaces', async () => {
moreWorkspacesDirectiveTest(6, 5);
});
it('progress bar - loading', async () => {
$scope.dashboardLastWorkspacesController.isLoading = true;
$scope.$digest();
let progressBar = directiveElement.find('md-progress-linear');
let mainDiv = directiveElement.find('#last-workspaces');
expect(progressBar.length).toBe(1);
expect(progressBar.attr('class')).not.toContain('ng-hide');
expect(mainDiv.length).toBe(1);
expect(mainDiv.attr('class')).toContain('ng-hide');
});
it('progress bar - not loading', async () => {
$scope.dashboardLastWorkspacesController.isLoading = false;
$scope.$digest();
let progressBar = directiveElement.find('md-progress-linear');
let mainDiv = directiveElement.find('#last-workspaces');
expect(progressBar.length).toBe(1);
expect(progressBar.attr('class')).toContain('ng-hide');
expect(mainDiv.length).toBe(1);
expect(mainDiv.attr('class')).not.toContain('ng-hide');
});
function noWorkspacesDirectiveTest() {
$scope.dashboardLastWorkspacesController.workspaces = [];
$scope.$digest();
let emptyLabel = directiveElement.find('.last-workspaces-empty-label');
let workspaceList = directiveElement.find('#last-workspaces-list');
let workspaceItems = directiveElement.find('.workspace-mock');
expect(emptyLabel.length).toBe(1);
expect(emptyLabel.attr('class')).not.toContain('ng-hide');
expect(workspaceList.length).toBe(1);
expect(workspaceList.attr('class')).toContain('ng-hide');
expect(workspaceItems.length).toBe(0);
}
function moreWorkspacesDirectiveTest(workspacesCount: number, workspacesDisplayedCount: number = workspacesCount) {
$scope.dashboardLastWorkspacesController.workspaces =
Array.from(new Array(workspacesCount)).map((x, i) => {return {} });
$scope.$digest();
let emptyLabel = directiveElement.find('.last-workspaces-empty-label');
let workspaceList = directiveElement.find('#last-workspaces-list');
let workspaceItems = directiveElement.find('.workspace-mock');
expect(emptyLabel.length).toBe(1);
expect(emptyLabel.attr('class')).toContain('ng-hide');
expect(workspaceList.length).toBe(1);
expect(workspaceList.attr('class')).not.toContain('ng-hide');
expect(workspaceItems.length).toBe(workspacesDisplayedCount);
}
});

View File

@ -1,14 +1,14 @@
<dashboard-panel panel-title="Recent Workspaces">
<md-progress-linear md-mode="indeterminate"
ng-show="dashboardLastWorkspacesController.isLoading"></md-progress-linear>
<div ng-hide="dashboardLastWorkspacesController.isLoading">
<div id='last-workspaces' ng-hide="dashboardLastWorkspacesController.isLoading">
<div class="dashboard-add-button">
<che-button-primary che-button-title="Create Workspace"
ng-href="#/create-workspace"></che-button-primary>
</div>
<span ng-show="dashboardLastWorkspacesController.getWorkspaces().length === 0"
class="last-workspaces-empty-label">No workspaces found</span>
<che-list ng-show="dashboardLastWorkspacesController.getWorkspaces().length > 0">
<che-list id='last-workspaces-list' ng-show="dashboardLastWorkspacesController.getWorkspaces().length > 0">
<che-workspace-item ng-repeat="workspace in dashboardLastWorkspacesController.getWorkspaces()
| orderBy:['attributes.updated', 'attributes.created']:'reverse'
| limitTo:'5'"