Commit 89ab47cd authored by Alfredo Sumaran's avatar Alfredo Sumaran

Merge branch 'fix-karma-multiple-assignees' into 'multiple_assignees_review'

Fix karma tests for multiple assignees

See merge request !1750
parents 862e0eb5 26abb796
......@@ -37,8 +37,8 @@ class TargetBranchDropDown {
}
return SELECT_ITEM_MSG;
},
clicked(item, el, e) {
e.preventDefault();
clicked(options) {
options.e.preventDefault();
self.onClick.call(self);
},
fieldName: self.fieldName,
......
......@@ -24,6 +24,7 @@ export default {
title: this.title,
labels,
subscribed: true,
assignees: [],
});
if (Store.state.currentBoard) {
......
......@@ -3,6 +3,7 @@
/* global MilestoneSelect */
/* global LabelsSelect */
/* global Sidebar */
/* global Flash */
import Vue from 'vue';
import eventHub from '../../sidebar/event_hub';
......@@ -85,10 +86,14 @@ require('./sidebar/remove_issue');
saveAssignees () {
this.loadingAssignees = true;
function setLoadingFalse() {
this.loadingAssignees = false;
}
gl.issueBoards.BoardsStore.detail.issue.update(this.endpoint)
.then(() => this.loadingAssignees = false)
.then(setLoadingFalse)
.catch(() => {
this.loadingAssignees = false;
setLoadingFalse();
return new Flash('An error occurred while saving assignees');
});
},
......
......@@ -19,7 +19,7 @@ export default class SidebarMediator {
}
saveAssignees(field) {
const selected = this.store.assignees.map((u) => u.id);
const selected = this.store.assignees.map(u => u.id);
// If there are no ids, that means we have to unassign (which is id = 0)
// And it only accepts an array, hence [0]
......
.block.assignee{ ref: "assigneeBlock" }
%template{ "v-if" => "issue.assignees"}
%template{ "v-if" => "issue.assignees" }
%assignee-title{ ":number-of-assignees" => "issue.assignees.length",
":loading" => "loadingAssignees",
":editable" => can?(current_user, :admin_issue, @project) }
%assignees{ class: "value", "root-path" => "#{root_url}",
%assignees.value{ "root-path" => "#{root_url}",
":users" => "issue.assignees",
"@assign-self" => "assignSelf" }
......
......@@ -8,14 +8,14 @@
import Vue from 'vue';
import Cookies from 'js-cookie';
require('~/lib/utils/url_utility');
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
require('~/boards/models/user');
require('~/boards/services/board_service');
require('~/boards/stores/boards_store');
require('./mock_data');
import '~/lib/utils/url_utility';
import '~/boards/models/issue';
import '~/boards/models/label';
import '~/boards/models/list';
import '~/boards/models/assignee';
import '~/boards/services/board_service';
import '~/boards/stores/boards_store';
import './mock_data';
describe('Store', () => {
beforeEach(() => {
......@@ -212,7 +212,8 @@ describe('Store', () => {
title: 'Testing',
iid: 2,
confidential: false,
labels: []
labels: [],
assignees: [],
});
const list = gl.issueBoards.BoardsStore.addList(listObj);
......
......@@ -5,13 +5,13 @@
import Vue from 'vue';
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
require('~/boards/models/user');
require('~/boards/stores/boards_store');
require('~/boards/components/issue_card_inner');
require('./mock_data');
import '~/boards/models/issue';
import '~/boards/models/label';
import '~/boards/models/list';
import '~/boards/models/assignee';
import '~/boards/stores/boards_store';
import '~/boards/components/issue_card_inner';
import './mock_data';
describe('Issue card component', () => {
const user = new ListAssignee({
......@@ -151,19 +151,19 @@ describe('Issue card component', () => {
beforeEach((done) => {
component.issue.assignees = [
user,
new ListUser({
new ListAssignee({
id: 2,
name: 'user2',
username: 'user2',
avatar: 'test_image',
}),
new ListUser({
new ListAssignee({
id: 3,
name: 'user3',
username: 'user3',
avatar: 'test_image',
}),
new ListUser({
new ListAssignee({
id: 4,
name: 'user4',
username: 'user4',
......@@ -177,10 +177,9 @@ describe('Issue card component', () => {
expect(component.$el.querySelectorAll('.card-assignee .avatar').length).toEqual(4);
});
describe('more than four assignees', () => {
beforeEach((done) => {
component.issue.assignees.push(new ListUser({
component.issue.assignees.push(new ListAssignee({
id: 5,
name: 'user5',
username: 'user5',
......@@ -199,8 +198,8 @@ describe('Issue card component', () => {
});
it('renders 99+ avatar counter', (done) => {
for(let i = 5; i < 104; i++) {
const u = new ListUser({
for (let i = 5; i < 104; i += 1) {
const u = new ListAssignee({
id: i,
name: 'name',
username: 'username',
......@@ -215,7 +214,7 @@ describe('Issue card component', () => {
});
});
});
})
});
describe('labels', () => {
it('does not render any', () => {
......
......@@ -2,14 +2,14 @@
/* global BoardService */
/* global ListIssue */
require('~/lib/utils/url_utility');
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
require('~/boards/models/user');
require('~/boards/services/board_service');
require('~/boards/stores/boards_store');
require('./mock_data');
import '~/lib/utils/url_utility';
import '~/boards/models/issue';
import '~/boards/models/label';
import '~/boards/models/list';
import '~/boards/models/assignee';
import '~/boards/services/board_service';
import '~/boards/stores/boards_store';
import './mock_data';
describe('Issue model', () => {
let issue;
......
......@@ -8,14 +8,14 @@
import Vue from 'vue';
require('~/lib/utils/url_utility');
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
require('~/boards/models/user');
require('~/boards/services/board_service');
require('~/boards/stores/boards_store');
require('./mock_data');
import '~/lib/utils/url_utility';
import '~/boards/models/issue';
import '~/boards/models/label';
import '~/boards/models/list';
import '~/boards/models/assignee';
import '~/boards/services/board_service';
import '~/boards/stores/boards_store';
import './mock_data';
describe('List model', () => {
let list;
......
......@@ -38,7 +38,8 @@ const BoardsMockData = {
title: 'Testing',
iid: 1,
confidential: false,
labels: []
labels: [],
assignees: [],
}],
size: 1
},
......
/* global ListIssue */
require('~/boards/models/issue');
require('~/boards/models/label');
require('~/boards/models/list');
require('~/boards/models/user');
require('~/boards/stores/modal_store');
import '~/boards/models/issue';
import '~/boards/models/label';
import '~/boards/models/list';
import '~/boards/models/assignee';
import '~/boards/stores/modal_store';
describe('Modal store', () => {
let issue;
......
......@@ -2,7 +2,7 @@
import Vue from 'vue';
import '~/sidebar/components/time_tracking/time_tracker';
import timeTracker from '~/sidebar/components/time_tracking/time_tracker';
function initTimeTrackingComponent(opts) {
setFixtures(`
......@@ -16,187 +16,185 @@ function initTimeTrackingComponent(opts) {
time_spent: opts.timeSpent,
human_time_estimate: opts.timeEstimateHumanReadable,
human_time_spent: opts.timeSpentHumanReadable,
docsUrl: '/help/workflow/time_tracking.md',
rootPath: '/',
};
const TimeTrackingComponent = Vue.component('issuable-time-tracker');
const TimeTrackingComponent = Vue.extend(timeTracker);
this.timeTracker = new TimeTrackingComponent({
el: '#mock-container',
propsData: this.initialData,
});
}
((gl) => {
describe('Issuable Time Tracker', function() {
describe('Initialization', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 5000, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '1h 23m' });
});
describe('Issuable Time Tracker', function() {
describe('Initialization', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 5000, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '1h 23m' });
});
it('should return something defined', function() {
expect(this.timeTracker).toBeDefined();
});
it('should return something defined', function() {
expect(this.timeTracker).toBeDefined();
});
it ('should correctly set timeEstimate', function(done) {
Vue.nextTick(() => {
expect(this.timeTracker.timeEstimate).toBe(this.initialData.time_estimate);
done();
});
it ('should correctly set timeEstimate', function(done) {
Vue.nextTick(() => {
expect(this.timeTracker.timeEstimate).toBe(this.initialData.time_estimate);
done();
});
it ('should correctly set time_spent', function(done) {
Vue.nextTick(() => {
expect(this.timeTracker.timeSpent).toBe(this.initialData.time_spent);
done();
});
});
it ('should correctly set time_spent', function(done) {
Vue.nextTick(() => {
expect(this.timeTracker.timeSpent).toBe(this.initialData.time_spent);
done();
});
});
});
describe('Content Display', function() {
describe('Panes', function() {
describe('Comparison pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 5000, timeEstimateHumanReadable: '', timeSpentHumanReadable: '' });
describe('Content Display', function() {
describe('Panes', function() {
describe('Comparison pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 5000, timeEstimateHumanReadable: '', timeSpentHumanReadable: '' });
});
it('should show the "Comparison" pane when timeEstimate and time_spent are truthy', function(done) {
Vue.nextTick(() => {
const $comparisonPane = this.timeTracker.$el.querySelector('.time-tracking-comparison-pane');
expect(this.timeTracker.showComparisonState).toBe(true);
done();
});
});
it('should show the "Comparison" pane when timeEstimate and time_spent are truthy', function(done) {
describe('Remaining meter', function() {
it('should display the remaining meter with the correct width', function(done) {
Vue.nextTick(() => {
const $comparisonPane = this.timeTracker.$el.querySelector('.time-tracking-comparison-pane');
expect(this.timeTracker.showComparisonState).toBe(true);
const meterWidth = this.timeTracker.$el.querySelector('.time-tracking-comparison-pane .meter-fill').style.width;
const correctWidth = '5%';
expect(meterWidth).toBe(correctWidth);
done();
});
})
});
describe('Remaining meter', function() {
it('should display the remaining meter with the correct width', function(done) {
Vue.nextTick(() => {
const meterWidth = this.timeTracker.$el.querySelector('.time-tracking-comparison-pane .meter-fill').style.width;
const correctWidth = '5%';
expect(meterWidth).toBe(correctWidth);
done();
})
});
it('should display the remaining meter with the correct background color when within estimate', function(done) {
Vue.nextTick(() => {
const styledMeter = $(this.timeTracker.$el).find('.time-tracking-comparison-pane .within_estimate .meter-fill');
expect(styledMeter.length).toBe(1);
done()
});
it('should display the remaining meter with the correct background color when within estimate', function(done) {
Vue.nextTick(() => {
const styledMeter = $(this.timeTracker.$el).find('.time-tracking-comparison-pane .within_estimate .meter-fill');
expect(styledMeter.length).toBe(1);
done()
});
});
it('should display the remaining meter with the correct background color when over estimate', function(done) {
this.timeTracker.time_estimate = 100000;
this.timeTracker.time_spent = 20000000;
Vue.nextTick(() => {
const styledMeter = $(this.timeTracker.$el).find('.time-tracking-comparison-pane .over_estimate .meter-fill');
expect(styledMeter.length).toBe(1);
done();
});
it('should display the remaining meter with the correct background color when over estimate', function(done) {
this.timeTracker.time_estimate = 100000;
this.timeTracker.time_spent = 20000000;
Vue.nextTick(() => {
const styledMeter = $(this.timeTracker.$el).find('.time-tracking-comparison-pane .over_estimate .meter-fill');
expect(styledMeter.length).toBe(1);
done();
});
});
});
});
describe("Estimate only pane", function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 0, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '' });
});
describe("Estimate only pane", function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 100000, timeSpent: 0, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '' });
});
it('should display the human readable version of time estimated', function(done) {
Vue.nextTick(() => {
const estimateText = this.timeTracker.$el.querySelector('.time-tracking-estimate-only-pane').innerText;
const correctText = 'Estimated: 2h 46m';
it('should display the human readable version of time estimated', function(done) {
Vue.nextTick(() => {
const estimateText = this.timeTracker.$el.querySelector('.time-tracking-estimate-only-pane').innerText;
const correctText = 'Estimated: 2h 46m';
expect(estimateText).toBe(correctText);
done();
});
expect(estimateText).toBe(correctText);
done();
});
});
});
describe('Spent only pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 5000, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '1h 23m' });
});
describe('Spent only pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 5000, timeEstimateHumanReadable: '2h 46m', timeSpentHumanReadable: '1h 23m' });
});
it('should display the human readable version of time spent', function(done) {
Vue.nextTick(() => {
const spentText = this.timeTracker.$el.querySelector('.time-tracking-spend-only-pane').innerText;
const correctText = 'Spent: 1h 23m';
it('should display the human readable version of time spent', function(done) {
Vue.nextTick(() => {
const spentText = this.timeTracker.$el.querySelector('.time-tracking-spend-only-pane').innerText;
const correctText = 'Spent: 1h 23m';
expect(spentText).toBe(correctText);
done();
});
expect(spentText).toBe(correctText);
done();
});
});
});
describe('No time tracking pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 0, timeEstimateHumanReadable: 0, timeSpentHumanReadable: 0 });
});
describe('No time tracking pane', function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 0, timeEstimateHumanReadable: '', timeSpentHumanReadable: '' });
});
it('should only show the "No time tracking" pane when both timeEstimate and time_spent are falsey', function(done) {
Vue.nextTick(() => {
const $noTrackingPane = this.timeTracker.$el.querySelector('.time-tracking-no-tracking-pane');
const noTrackingText =$noTrackingPane.innerText;
const correctText = 'No estimate or time spent';
it('should only show the "No time tracking" pane when both timeEstimate and time_spent are falsey', function(done) {
Vue.nextTick(() => {
const $noTrackingPane = this.timeTracker.$el.querySelector('.time-tracking-no-tracking-pane');
const noTrackingText =$noTrackingPane.innerText;
const correctText = 'No estimate or time spent';
expect(this.timeTracker.showNoTimeTrackingState).toBe(true);
expect($noTrackingPane).toBeVisible();
expect(noTrackingText).toBe(correctText);
done();
});
expect(this.timeTracker.showNoTimeTrackingState).toBe(true);
expect($noTrackingPane).toBeVisible();
expect(noTrackingText).toBe(correctText);
done();
});
});
});
describe("Help pane", function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 0 });
});
describe("Help pane", function() {
beforeEach(function() {
initTimeTrackingComponent.call(this, { timeEstimate: 0, timeSpent: 0 });
});
it('should not show the "Help" pane by default', function(done) {
Vue.nextTick(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
it('should not show the "Help" pane by default', function(done) {
Vue.nextTick(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
expect(this.timeTracker.showHelpState).toBe(false);
expect($helpPane).toBeNull();
done();
});
expect(this.timeTracker.showHelpState).toBe(false);
expect($helpPane).toBeNull();
done();
});
});
it('should show the "Help" pane when help button is clicked', function(done) {
Vue.nextTick(() => {
$(this.timeTracker.$el).find('.help-button').click();
it('should show the "Help" pane when help button is clicked', function(done) {
Vue.nextTick(() => {
$(this.timeTracker.$el).find('.help-button').click();
setTimeout(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
expect(this.timeTracker.showHelpState).toBe(true);
expect($helpPane).toBeVisible();
done();
}, 10);
});
setTimeout(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
expect(this.timeTracker.showHelpState).toBe(true);
expect($helpPane).toBeVisible();
done();
}, 10);
});
});
it('should not show the "Help" pane when help button is clicked and then closed', function(done) {
Vue.nextTick(() => {
$(this.timeTracker.$el).find('.help-button').click();
it('should not show the "Help" pane when help button is clicked and then closed', function(done) {
Vue.nextTick(() => {
$(this.timeTracker.$el).find('.help-button').click();
setTimeout(() => {
setTimeout(() => {
$(this.timeTracker.$el).find('.close-help-button').click();
$(this.timeTracker.$el).find('.close-help-button').click();
setTimeout(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
setTimeout(() => {
const $helpPane = this.timeTracker.$el.querySelector('.time-tracking-help-state');
expect(this.timeTracker.showHelpState).toBe(false);
expect($helpPane).toBeNull();
expect(this.timeTracker.showHelpState).toBe(false);
expect($helpPane).toBeNull();
done();
}, 1000);
done();
}, 1000);
});
}, 1000);
});
});
});
});
});
})(window.gl || (window.gl = {}));
});
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