Commit 68b6e89e authored by Filipa Lacerda's avatar Filipa Lacerda

Adds unit tests

parent 65dcaa31
......@@ -62,6 +62,7 @@ module.exports = Vue.component('deploy_boards_components', {
created() {
this.isLoading = true;
// If the response is 204, we make 3 more requests.
gl.utils.backOff((next, stop) => {
this.service.getDeployBoard(this.environmentID)
.then((resp) => {
......@@ -71,33 +72,30 @@ module.exports = Vue.component('deploy_boards_components', {
if (this.backOffRequestCounter < 3) {
next();
}
} else {
stop(resp);
}
stop(resp);
return resp;
})
.then(resp => resp.json())
.then((response) => {
if (!Object.keys(response).length && this.backOffRequestCounter === 3) {
this.hasError = true;
}
this.store.storeDeployBoard(this.environmentID, response);
return response;
})
.then((response) => {
if ((!Object.keys(response).length &&
this.backOffRequestCounter === 3) ||
Object.keys(response).length) {
this.isLoading = false;
}
})
.catch((error) => {
stop(error);
this.isLoading = false;
this.hasError = true;
});
.catch(stop);
}, Infinity)
.then(resp => resp.json())
.then((response) => {
if (!Object.keys(response).length && this.backOffRequestCounter === 3) {
this.hasError = true;
}
this.store.storeDeployBoard(this.environmentID, response);
return response;
})
.then((response) => {
if ((!Object.keys(response).length &&
this.backOffRequestCounter === 3) ||
Object.keys(response).length) {
this.isLoading = false;
}
})
.catch(() => {
this.isLoading = false;
new Flash('An error occurred while fetching the deploy board.', 'alert');
});
},
......
......@@ -35,7 +35,7 @@ module.exports = Vue.component('deploy_board_instance_component', {
computed: {
cssClass() {
return `js-deploy-board-instance deploy-board-instance deploy-board-instance-${this.status} has-tooltip`;
return `deploy-board-instance deploy-board-instance-${this.status} has-tooltip`;
},
},
......
......@@ -51,17 +51,20 @@ module.exports = Vue.component('environment-table-component', {
toggleDeployBoard: {
type: Function,
required: true,
required: false,
default: () => {},
},
store: {
type: Object,
required: true,
required: false,
default: () => ({}),
},
service: {
type: Object,
required: true,
required: false,
default: () => ({}),
},
},
......@@ -90,7 +93,7 @@ module.exports = Vue.component('environment-table-component', {
:commit-icon-svg="commitIconSvg"
:toggleDeployBoard="toggleDeployBoard.bind(model)"></tr>
<tr v-if="model.isDeployBoardVisible">
<tr v-if="model.isDeployBoardVisible" class="js-deploy-board-row">
<td colspan="6" class="deploy-board-container">
<deploy-board
......
......@@ -54,7 +54,7 @@ class EnvironmentsStore {
if (env.size === 1) {
filtered = Object.assign({}, env, {
isDeployBoardVisible: false,
deployBoardData: {}
deployBoardData: {},
});
}
......
......@@ -230,7 +230,7 @@ Vue.http.interceptors.push((request, next) => {
if (request.url === 'environments/{id}/status.json') {
next(request.respondWith(JSON.stringify(deployBoardData), {
status: 200,
status: 204,
}));
}
......
......@@ -242,7 +242,7 @@
border-top: 1px solid $border-color;
border-bottom: 1px solid $border-color;
padding: 10px;
background-color: #fbfbfb;
background-color: $gray-light;
min-height: 20px;
.fa-spinner {
......
const Vue = require('vue');
const DeployBoardComponent = require('~/environments/components/deploy_board_component');
const Service = require('~/environments/services/environments_service');
const { deployBoardMockData } = require('./mock_data');
describe('Deploy Board', () => {
preloadFixtures('static/environments/element.html.raw');
beforeEach(() => {
loadFixtures('static/environments/element.html.raw');
});
describe('successfull request', () => {
const deployBoardInterceptor = (request, next) => {
next(request.respondWith(JSON.stringify(deployBoardMockData), {
status: 200,
}));
};
let component;
beforeEach(() => {
Vue.http.interceptors.push(deployBoardInterceptor);
this.service = new Service('environments');
component = new DeployBoardComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
store: {},
service: this.service,
deployBoardData: deployBoardMockData,
environmentID: 1,
},
});
});
afterEach(() => {
Vue.http.interceptors = _.without(
Vue.http.interceptors, deployBoardInterceptor,
);
});
it('should render percentage with completion value provided', (done) => {
setTimeout(() => {
expect(
component.$el.querySelector('.deploy-board-information .percentage').textContent,
).toEqual(`${deployBoardMockData.completion}%`);
done();
}, 0);
});
it('should render all instances', (done) => {
setTimeout(() => {
const instances = component.$el.querySelectorAll('.deploy-board-instances-container div');
expect(instances.length).toEqual(deployBoardMockData.instances.length);
expect(
instances[2].classList.contains(`deploy-board-instance-${deployBoardMockData.instances[2].status}`),
).toBe(true);
done();
}, 0);
});
it('should render an abort and a rollback button with the provided url', (done) => {
setTimeout(() => {
const buttons = component.$el.querySelectorAll('.deploy-board-actions a');
expect(buttons[0].getAttribute('href')).toEqual(deployBoardMockData.rollback_url);
expect(buttons[1].getAttribute('href')).toEqual(deployBoardMockData.abort_url);
done();
}, 0);
});
});
});
require('vue');
const DeployBoardInstanceComponent = require('~/environments/components/deploy_board_instance_component');
describe('Deploy Board Instance', () => {
preloadFixtures('static/environments/element.html.raw');
beforeEach(() => {
loadFixtures('static/environments/element.html.raw');
});
it('should render a div with the correct css status and tooltip data', () => {
const component = new DeployBoardInstanceComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
status: 'ready',
tooltipText: 'This is a pod',
},
});
expect(component.$el.classList.contains('deploy-board-instance-ready')).toBe(true);
expect(component.$el.getAttribute('data-title')).toEqual('This is a pod');
});
it('should render a div without tooltip data', () => {
const component = new DeployBoardInstanceComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
status: 'deploying',
},
});
expect(component.$el.classList.contains('deploy-board-instance-deploying')).toBe(true);
expect(component.$el.getAttribute('data-title')).toEqual('');
});
});
......@@ -26,6 +26,9 @@ describe('Environment item', () => {
model: mockItem,
canCreateDeployment: false,
canReadEnvironment: true,
toggleDeployBoard: () => {},
store: {},
service: {},
},
});
});
......@@ -114,6 +117,9 @@ describe('Environment item', () => {
model: environment,
canCreateDeployment: true,
canReadEnvironment: true,
toggleDeployBoard: () => {},
store: {},
service: {},
},
});
});
......
......@@ -9,22 +9,95 @@ describe('Environment item', () => {
it('Should render a table', () => {
const mockItem = {
name: 'review',
folderName: 'review',
size: 3,
isFolder: true,
latest: {
environment_path: 'url',
},
environment_path: 'url',
};
const component = new EnvironmentTable({
el: document.querySelector('.test-dom-element'),
propsData: {
environments: [{ mockItem }],
environments: [mockItem],
canCreateDeployment: false,
canReadEnvironment: true,
toggleDeployBoard: () => {},
store: {},
service: {},
},
});
expect(component.$el.tagName).toEqual('TABLE');
});
it('should render deploy board container when data is provided', () => {
const mockItem = {
name: 'review',
size: 1,
environment_path: 'url',
id: 1,
deployBoardData: {
instances: [
{ status: 'ready', tooltip: 'foo' },
],
abort_url: 'url',
rollback_url: 'url',
completion: 100,
is_completed: true,
},
isDeployBoardVisible: true,
};
const component = new EnvironmentTable({
el: document.querySelector('.test-dom-element'),
propsData: {
environments: [mockItem],
canCreateDeployment: true,
canReadEnvironment: true,
toggleDeployBoard: () => {},
store: {},
service: {},
},
});
expect(component.$el.querySelector('.js-deploy-board-row')).toBeDefined();
expect(component.$el.querySelector('.deploy-board-icon i').classList).toContain('fa-caret-down');
});
it('should toggle deploy board visibility when arrow is clicked', () => {
const mockItem = {
name: 'review',
size: 1,
environment_path: 'url',
id: 1,
deployBoardData: {
instances: [
{ status: 'ready', tooltip: 'foo' },
],
abort_url: 'url',
rollback_url: 'url',
completion: 100,
is_completed: true,
},
isDeployBoardVisible: false,
};
const component = new EnvironmentTable({
el: document.querySelector('.test-dom-element'),
propsData: {
environments: [mockItem],
canCreateDeployment: true,
canReadEnvironment: true,
toggleDeployBoard: () => {},
store: {},
service: {},
},
});
expect(component.$el.querySelector('.deploy-board-icon')).toContain('fa-caret-right');
component.$el.querySelector('.deploy-board-icon').click();
// expect toggleDeployBoard to have been called
});
});
const Store = require('~/environments/stores/environments_store');
const { environmentsList, serverData } = require('./mock_data');
const { serverData } = require('./mock_data');
(() => {
describe('Store', () => {
......@@ -16,10 +16,51 @@ const { environmentsList, serverData } = require('./mock_data');
expect(store.state.paginationInformation).toEqual({});
});
it('should store environments', () => {
store.storeEnvironments(serverData);
expect(store.state.environments.length).toEqual(serverData.length);
expect(store.state.environments[0]).toEqual(environmentsList[0]);
describe('store environments', () => {
it('should store environments', () => {
store.storeEnvironments(serverData);
expect(store.state.environments.length).toEqual(serverData.length);
});
it('should store a non folder environment with deploy board if x key is provided', () => {
const environment = {
name: 'foo',
size: 1,
id: 1,
};
store.storeEnvironments([environment]);
expect(store.state.environments[0].isDeployBoardVisible).toEqual(false);
expect(store.state.environments[0].deployBoardData).toEqual({});
});
it('should add folder keys when environment is a folder', () => {
const environment = {
name: 'bar',
size: 3,
id: 2,
};
store.storeEnvironments([environment]);
expect(store.state.environments[0].isFolder).toEqual(true);
expect(store.state.environments[0].folderName).toEqual('bar');
});
it('should extract content of `latest` key when provided', () => {
const environment = {
name: 'bar',
size: 3,
id: 2,
latest: {
last_deployment: {},
isStoppable: true,
},
};
store.storeEnvironments([environment]);
expect(store.state.environments[0].last_deployment).toEqual({});
expect(store.state.environments[0].isStoppable).toEqual(true);
});
});
it('should store available count', () => {
......@@ -32,27 +73,39 @@ const { environmentsList, serverData } = require('./mock_data');
expect(store.state.stoppedCounter).toEqual(2);
});
it('should store pagination information', () => {
const pagination = {
'X-nExt-pAge': '2',
'X-page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '2',
'X-TOTAL': '37',
'X-Total-Pages': '2',
};
const expectedResult = {
perPage: 1,
page: 1,
total: 37,
totalPages: 2,
nextPage: 2,
previousPage: 2,
};
store.setPagination(pagination);
expect(store.state.paginationInformation).toEqual(expectedResult);
describe('store pagination', () => {
it('should store normalized and integer pagination information', () => {
const pagination = {
'X-nExt-pAge': '2',
'X-page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '2',
'X-TOTAL': '37',
'X-Total-Pages': '2',
};
const expectedResult = {
perPage: 1,
page: 1,
total: 37,
totalPages: 2,
nextPage: 2,
previousPage: 2,
};
store.setPagination(pagination);
expect(store.state.paginationInformation).toEqual(expectedResult);
});
});
describe('deploy boards', () => {
it('should toggle deploy board property for given environment id', () => {
});
it('should store deploy board data for given environment id', () => {
});
});
});
})();
......@@ -85,8 +85,45 @@ const environment = {
},
};
const deployBoardMockData = {
instances: [
{ status: 'finished', tooltip: 'tanuki-2334 Finished' },
{ status: 'finished', tooltip: 'tanuki-2335 Finished' },
{ status: 'finished', tooltip: 'tanuki-2336 Finished' },
{ status: 'finished', tooltip: 'tanuki-2337 Finished' },
{ status: 'finished', tooltip: 'tanuki-2338 Finished' },
{ status: 'finished', tooltip: 'tanuki-2339 Finished' },
{ status: 'finished', tooltip: 'tanuki-2340 Finished' },
{ status: 'finished', tooltip: 'tanuki-2334 Finished' },
{ status: 'finished', tooltip: 'tanuki-2335 Finished' },
{ status: 'finished', tooltip: 'tanuki-2336 Finished' },
{ status: 'finished', tooltip: 'tanuki-2337 Finished' },
{ status: 'finished', tooltip: 'tanuki-2338 Finished' },
{ status: 'finished', tooltip: 'tanuki-2339 Finished' },
{ status: 'finished', tooltip: 'tanuki-2340 Finished' },
{ status: 'deploying', tooltip: 'tanuki-2341 Deploying' },
{ status: 'deploying', tooltip: 'tanuki-2342 Deploying' },
{ status: 'deploying', tooltip: 'tanuki-2343 Deploying' },
{ status: 'failed', tooltip: 'tanuki-2344 Failed' },
{ status: 'ready', tooltip: 'tanuki-2345 Ready' },
{ status: 'ready', tooltip: 'tanuki-2346 Ready' },
{ status: 'preparing', tooltip: 'tanuki-2348 Preparing' },
{ status: 'preparing', tooltip: 'tanuki-2349 Preparing' },
{ status: 'preparing', tooltip: 'tanuki-2350 Preparing' },
{ status: 'preparing', tooltip: 'tanuki-2353 Preparing' },
{ status: 'waiting', tooltip: 'tanuki-2354 Waiting' },
{ status: 'waiting', tooltip: 'tanuki-2355 Waiting' },
{ status: 'waiting', tooltip: 'tanuki-2356 Waiting' },
],
abort_url: 'url',
rollback_url: 'url',
completion: 100,
is_completed: true,
};
module.exports = {
environmentsList,
environment,
serverData,
deployBoardMockData,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment