summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2017-06-07 15:05:37 +0000
committerDouwe Maan <douwe@gitlab.com>2017-06-07 15:05:37 +0000
commit0bcb1d35ecb7db43a075c0a4ae9782991f724f1a (patch)
tree5ef82ca038eb3cb97e0eb351f33eb58261c3c536
parenta5757c72d967acd82865f9f7cb288d5b61b0b35c (diff)
parent1633d3d7d8b8589a3d04358d6473cfd168633a10 (diff)
downloadgitlab-ce-0bcb1d35ecb7db43a075c0a4ae9782991f724f1a.tar.gz
Merge branch 'expand-backlog-closed-lists-issue-boards' into 'master'
Expand/collapse close & backlog lists in issue boards Closes #23917 See merge request !11820
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js4
-rw-r--r--app/assets/javascripts/boards/components/board.js23
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js1
-rw-r--r--app/assets/javascripts/boards/components/modal/footer.js3
-rw-r--r--app/assets/javascripts/boards/components/modal/lists_dropdown.js2
-rw-r--r--app/assets/javascripts/boards/models/list.js4
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js8
-rw-r--r--app/assets/stylesheets/pages/boards.scss42
-rw-r--r--app/controllers/projects/boards/lists_controller.rb4
-rw-r--r--app/models/board.rb4
-rw-r--r--app/models/list.rb2
-rw-r--r--app/services/boards/create_service.rb1
-rw-r--r--app/services/boards/issues/list_service.rb2
-rw-r--r--app/services/boards/lists/list_service.rb2
-rw-r--r--app/views/projects/boards/_show.html.haml1
-rw-r--r--app/views/projects/boards/components/_board.html.haml11
-rw-r--r--changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml4
-rw-r--r--spec/controllers/projects/boards/lists_controller_spec.rb2
-rw-r--r--spec/factories/lists.rb6
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb4
-rw-r--r--spec/features/boards/boards_spec.rb174
-rw-r--r--spec/features/boards/issue_ordering_spec.rb36
-rw-r--r--spec/features/boards/new_issue_spec.rb6
-rw-r--r--spec/features/boards/sidebar_spec.rb8
-rw-r--r--spec/fixtures/api/schemas/list.json2
-rw-r--r--spec/javascripts/boards/components/board_spec.js112
-rw-r--r--spec/javascripts/fixtures/boards.rb28
-rw-r--r--spec/services/boards/create_service_spec.rb5
-rw-r--r--spec/services/boards/issues/list_service_spec.rb11
-rw-r--r--spec/services/boards/lists/list_service_spec.rb31
-rw-r--r--spec/support/javascript_fixtures_helpers.rb2
31 files changed, 402 insertions, 143 deletions
diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js
index 0e4aa39226b..b94009ee76b 100644
--- a/app/assets/javascripts/boards/boards_bundle.js
+++ b/app/assets/javascripts/boards/boards_bundle.js
@@ -88,6 +88,8 @@ $(() => {
if (list.type === 'closed') {
list.position = Infinity;
list.label = { description: 'Shows all closed issues. Moving an issue to this list closes it' };
+ } else if (list.type === 'backlog') {
+ list.position = -1;
}
});
@@ -128,7 +130,7 @@ $(() => {
},
computed: {
disabled() {
- return !this.store.lists.filter(list => list.type !== 'blank' && list.type !== 'done').length;
+ return !this.store.lists.filter(list => !list.preset).length;
},
tooltipTitle() {
if (this.disabled) {
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js
index 9ba84489910..adb7360327c 100644
--- a/app/assets/javascripts/boards/components/board.js
+++ b/app/assets/javascripts/boards/components/board.js
@@ -1,6 +1,7 @@
/* eslint-disable comma-dangle, space-before-function-paren, one-var */
/* global Sortable */
import Vue from 'vue';
+import AccessorUtilities from '../../lib/utils/accessor';
import boardList from './board_list';
import boardBlankState from './board_blank_state';
import './board_delete';
@@ -22,6 +23,10 @@ gl.issueBoards.Board = Vue.extend({
disabled: Boolean,
issueLinkBase: String,
rootPath: String,
+ boardId: {
+ type: String,
+ required: true,
+ },
},
data () {
return {
@@ -78,7 +83,16 @@ gl.issueBoards.Board = Vue.extend({
methods: {
showNewIssueForm() {
this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
- }
+ },
+ toggleExpanded(e) {
+ if (this.list.isExpandable && !e.target.classList.contains('js-no-trigger-collapse')) {
+ this.list.isExpanded = !this.list.isExpanded;
+
+ if (AccessorUtilities.isLocalStorageAccessSafe()) {
+ localStorage.setItem(`boards.${this.boardId}.${this.list.type}.expanded`, this.list.isExpanded);
+ }
+ }
+ },
},
mounted () {
this.sortableOptions = gl.issueBoards.getBoardSortableDefaultOptions({
@@ -102,4 +116,11 @@ gl.issueBoards.Board = Vue.extend({
this.sortable = Sortable.create(this.$el.parentNode, this.sortableOptions);
},
+ created() {
+ if (this.list.isExpandable && AccessorUtilities.isLocalStorageAccessSafe()) {
+ const isCollapsed = localStorage.getItem(`boards.${this.boardId}.${this.list.type}.expanded`) === 'false';
+
+ this.list.isExpanded = !isCollapsed;
+ }
+ },
});
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js
index 4699ef5a51c..daef01bc93d 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.js
+++ b/app/assets/javascripts/boards/components/issue_card_inner.js
@@ -152,6 +152,7 @@ gl.issueBoards.IssueCardInner = Vue.extend({
<div class="card-assignee">
<user-avatar-link
v-for="(assignee, index) in issue.assignees"
+ :key="assignee.id"
v-if="shouldRenderAssignee(index)"
class="js-no-trigger"
:link-href="assigneeUrl(assignee)"
diff --git a/app/assets/javascripts/boards/components/modal/footer.js b/app/assets/javascripts/boards/components/modal/footer.js
index fe7ab2db85d..478a1335b2b 100644
--- a/app/assets/javascripts/boards/components/modal/footer.js
+++ b/app/assets/javascripts/boards/components/modal/footer.js
@@ -26,7 +26,8 @@ gl.issueBoards.ModalFooter = Vue.extend({
},
methods: {
addIssues() {
- const list = this.modal.selectedList || this.state.lists[0];
+ const firstListIndex = 1;
+ const list = this.modal.selectedList || this.state.lists[firstListIndex];
const selectedIssues = ModalStore.getSelectedIssues();
const issueIds = selectedIssues.map(issue => issue.globalId);
diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.js b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
index 8cd15df90fa..4684ea76647 100644
--- a/app/assets/javascripts/boards/components/modal/lists_dropdown.js
+++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.js
@@ -11,7 +11,7 @@ gl.issueBoards.ModalFooterListsDropdown = Vue.extend({
},
computed: {
selected() {
- return this.modal.selectedList || this.state.lists[0];
+ return this.modal.selectedList || this.state.lists[1];
},
},
destroyed() {
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
index 8514e7df1d3..548de1a4c52 100644
--- a/app/assets/javascripts/boards/models/list.js
+++ b/app/assets/javascripts/boards/models/list.js
@@ -12,7 +12,9 @@ class List {
this.position = obj.position;
this.title = obj.title;
this.type = obj.list_type;
- this.preset = ['closed', 'blank'].indexOf(this.type) > -1;
+ this.preset = ['backlog', 'closed', 'blank'].indexOf(this.type) > -1;
+ this.isExpandable = ['backlog', 'closed'].indexOf(this.type) > -1;
+ this.isExpanded = true;
this.page = 1;
this.loading = true;
this.loadingMore = false;
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 7bddcdc3c1d..1e12d4ca415 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -32,10 +32,14 @@ gl.issueBoards.BoardsStore = {
},
new (listObj) {
const list = this.addList(listObj);
+ const backlogList = this.findList('type', 'backlog', 'backlog');
list
.save()
.then(() => {
+ // Remove any new issues from the backlog
+ // as they will be visible in the new list
+ list.issues.forEach(backlogList.removeIssue.bind(backlogList));
this.state.lists = _.sortBy(this.state.lists, 'position');
})
.catch(() => {
@@ -48,7 +52,7 @@ gl.issueBoards.BoardsStore = {
},
shouldAddBlankState () {
// Decide whether to add the blank state
- return !(this.state.lists.filter(list => list.type !== 'closed')[0]);
+ return !(this.state.lists.filter(list => list.type !== 'backlog' && list.type !== 'closed')[0]);
},
addBlankState () {
if (!this.shouldAddBlankState() || this.welcomeIsHidden() || this.disabled) return;
@@ -101,7 +105,7 @@ gl.issueBoards.BoardsStore = {
issueTo.removeLabel(listFrom.label);
}
- if (listTo.type === 'closed') {
+ if (listTo.type === 'closed' && listFrom.type !== 'backlog') {
issueLists.forEach((list) => {
list.removeIssue(issue);
});
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index e3e94c8ca50..740e383dbb5 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -96,9 +96,51 @@
@media (min-width: $screen-sm-min) {
width: 400px;
}
+
+ &.is-expandable {
+ .board-header {
+ cursor: pointer;
+ }
+ }
+
+ &.is-collapsed {
+ width: 50px;
+
+ .board-header {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
+
+ .board-title {
+ position: initial;
+ padding: 0;
+ border-bottom: 0;
+
+ > span {
+ display: block;
+ transform: rotate(90deg) translate(25px, 0);
+ }
+ }
+
+ .board-title-expandable-toggle {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-left: -10px;
+ }
+
+ .board-list-component,
+ .board-issue-count-holder {
+ display: none;
+ }
+ }
}
.board-inner {
+ position: relative;
height: 100%;
font-size: $issue-boards-font-size;
background: $gray-light;
diff --git a/app/controllers/projects/boards/lists_controller.rb b/app/controllers/projects/boards/lists_controller.rb
index 67e3c9add81..ad53bb749a0 100644
--- a/app/controllers/projects/boards/lists_controller.rb
+++ b/app/controllers/projects/boards/lists_controller.rb
@@ -5,7 +5,9 @@ module Projects
before_action :authorize_read_list!, only: [:index]
def index
- render json: serialize_as_json(board.lists)
+ lists = ::Boards::Lists::ListService.new(project, current_user).execute(board)
+
+ render json: serialize_as_json(lists)
end
def create
diff --git a/app/models/board.rb b/app/models/board.rb
index cf8317891b5..18081a32157 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -5,6 +5,10 @@ class Board < ActiveRecord::Base
validates :project, presence: true
+ def backlog_list
+ lists.merge(List.backlog).take
+ end
+
def closed_list
lists.merge(List.closed).take
end
diff --git a/app/models/list.rb b/app/models/list.rb
index ba7353a1325..918275be142 100644
--- a/app/models/list.rb
+++ b/app/models/list.rb
@@ -2,7 +2,7 @@ class List < ActiveRecord::Base
belongs_to :board
belongs_to :label
- enum list_type: { label: 1, closed: 2 }
+ enum list_type: { backlog: 0, label: 1, closed: 2 }
validates :board, :list_type, presence: true
validates :label, :position, presence: true, if: :label?
diff --git a/app/services/boards/create_service.rb b/app/services/boards/create_service.rb
index fd9ff115eab..68f6a8619e5 100644
--- a/app/services/boards/create_service.rb
+++ b/app/services/boards/create_service.rb
@@ -12,6 +12,7 @@ module Boards
def create_board!
board = project.boards.create
+ board.lists.create(list_type: :backlog)
board.lists.create(list_type: :closed)
board
diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb
index 533e6787855..418fa9afd6e 100644
--- a/app/services/boards/issues/list_service.rb
+++ b/app/services/boards/issues/list_service.rb
@@ -3,7 +3,7 @@ module Boards
class ListService < BaseService
def execute
issues = IssuesFinder.new(current_user, filter_params).execute
- issues = without_board_labels(issues) unless list
+ issues = without_board_labels(issues) unless movable_list?
issues = with_list_label(issues) if movable_list?
issues.order_by_position_and_priority
end
diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb
index c579ed4c869..df2a01a69e5 100644
--- a/app/services/boards/lists/list_service.rb
+++ b/app/services/boards/lists/list_service.rb
@@ -2,6 +2,8 @@ module Boards
module Lists
class ListService < BaseService
def execute(board)
+ board.lists.create(list_type: :backlog) unless board.lists.backlog.exists?
+
board.lists
end
end
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index efec69662f3..6684ecfce81 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -26,6 +26,7 @@
":disabled" => "disabled",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath",
+ ":board-id" => "boardId",
":key" => "_uid" }
= render "projects/boards/components/sidebar"
%board-add-issues-modal{ "blank-state-image" => render('shared/empty_states/icons/issues.svg'),
diff --git a/app/views/projects/boards/components/_board.html.haml b/app/views/projects/boards/components/_board.html.haml
index bc5c727bf0d..55c4d51be14 100644
--- a/app/views/projects/boards/components/_board.html.haml
+++ b/app/views/projects/boards/components/_board.html.haml
@@ -1,8 +1,11 @@
-.board{ ":class" => '{ "is-draggable": !list.preset }',
+.board{ ":class" => '{ "is-draggable": !list.preset, "is-expandable": list.isExpandable, "is-collapsed": !list.isExpanded }',
":data-id" => "list.id" }
.board-inner
- %header.board-header{ ":class" => '{ "has-border": list.label }', ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" }
+ %header.board-header{ ":class" => '{ "has-border": list.label && list.label.color }', ":style" => "{ borderTopColor: (list.label && list.label.color ? list.label.color : null) }", "@click" => "toggleExpanded($event)" }
%h3.board-title.js-board-handle{ ":class" => '{ "user-can-drag": (!disabled && !list.preset) }' }
+ %i.fa.fa-fw.board-title-expandable-toggle{ "v-if": "list.isExpandable",
+ ":class": "{ \"fa-caret-down\": list.isExpanded, \"fa-caret-right\": !list.isExpanded && list.position === -1, \"fa-caret-left\": !list.isExpanded && list.position !== -1 }",
+ "aria-hidden": "true" }
%span.has-tooltip{ ":title" => '(list.label ? list.label.description : "")',
data: { container: "body", placement: "bottom" } }
{{ list.title }}
@@ -10,13 +13,13 @@
%span.board-issue-count.pull-left{ ":class" => '{ "has-btn": list.type !== "closed" && !disabled }' }
{{ list.issuesSize }}
- if can?(current_user, :admin_issue, @project)
- %button.btn.btn-small.btn-default.pull-right.has-tooltip{ type: "button",
+ %button.btn.btn-small.btn-default.pull-right.has-tooltip.js-no-trigger-collapse{ type: "button",
"@click" => "showNewIssueForm",
"v-if" => 'list.type !== "closed"',
"aria-label" => "New issue",
"title" => "New issue",
data: { placement: "top", container: "body" } }
- = icon("plus")
+ = icon("plus", class: "js-no-trigger-collapse")
- if can?(current_user, :admin_list, @project)
%board-delete{ "inline-template" => true,
":list" => "list",
diff --git a/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml b/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml
new file mode 100644
index 00000000000..4796f8e918b
--- /dev/null
+++ b/changelogs/unreleased/expand-backlog-closed-lists-issue-boards.yml
@@ -0,0 +1,4 @@
+---
+title: Expand/collapse backlog & closed lists in issue boards
+merge_request:
+author:
diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb
index 432f3c53c90..0f2664262e8 100644
--- a/spec/controllers/projects/boards/lists_controller_spec.rb
+++ b/spec/controllers/projects/boards/lists_controller_spec.rb
@@ -27,7 +27,7 @@ describe Projects::Boards::ListsController do
parsed_response = JSON.parse(response.body)
expect(response).to match_response_schema('lists')
- expect(parsed_response.length).to eq 2
+ expect(parsed_response.length).to eq 3
end
context 'with unauthorized user' do
diff --git a/spec/factories/lists.rb b/spec/factories/lists.rb
index f6a78811cbe..48142d3c49b 100644
--- a/spec/factories/lists.rb
+++ b/spec/factories/lists.rb
@@ -6,6 +6,12 @@ FactoryGirl.define do
sequence(:position)
end
+ factory :backlog_list, parent: :list do
+ list_type :backlog
+ label nil
+ position nil
+ end
+
factory :closed_list, parent: :list do
list_type :closed
label nil
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index 32ac265814f..2b8edac4f10 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -231,7 +231,7 @@ describe 'Issue Boards add issue modal', :feature, :js do
click_button 'Add 1 issue'
end
- page.within(first('.board')) do
+ page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.card')
end
end
@@ -247,7 +247,7 @@ describe 'Issue Boards add issue modal', :feature, :js do
click_button 'Add 1 issue'
end
- page.within(find('.board:nth-child(2)')) do
+ page.within(find('.board:nth-child(3)')) do
expect(page).to have_selector('.card')
end
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index ba27db23ced..c80453b8227 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -19,7 +19,7 @@ describe 'Issue Boards', feature: true, js: true do
before do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'shows blank state' do
@@ -36,18 +36,18 @@ describe 'Issue Boards', feature: true, js: true do
page.within(find('.board-blank-state')) do
click_button("Nevermind, I'll use my own")
end
- expect(page).to have_selector('.board', count: 1)
+ expect(page).to have_selector('.board', count: 2)
end
it 'creates default lists' do
- lists = ['To Do', 'Doing', 'Closed']
+ lists = ['Backlog', 'To Do', 'Doing', 'Closed']
page.within(find('.board-blank-state')) do
click_button('Add default lists')
end
wait_for_requests
- expect(page).to have_selector('.board', count: 3)
+ expect(page).to have_selector('.board', count: 4)
page.all('.board').each_with_index do |list, i|
expect(list.find('.board-title')).to have_content(lists[i])
@@ -85,29 +85,25 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(page).to have_selector('.board', count: 3)
- expect(find('.board:nth-child(1)')).to have_selector('.card')
+ expect(page).to have_selector('.board', count: 4)
expect(find('.board:nth-child(2)')).to have_selector('.card')
expect(find('.board:nth-child(3)')).to have_selector('.card')
- end
-
- it 'shows lists' do
- expect(page).to have_selector('.board', count: 3)
+ expect(find('.board:nth-child(4)')).to have_selector('.card')
end
it 'shows description tooltip on list title' do
- page.within('.board:nth-child(1)') do
+ page.within('.board:nth-child(2)') do
expect(find('.board-title span.has-tooltip')[:title]).to eq('Test')
end
end
it 'shows issues in lists' do
- wait_for_board_cards(1, 8)
- wait_for_board_cards(2, 2)
+ wait_for_board_cards(2, 8)
+ wait_for_board_cards(3, 2)
end
it 'shows confidential issues with icon' do
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.confidential-icon', count: 1)
end
end
@@ -118,9 +114,9 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(3)')).to have_selector('.card', count: 1)
+ expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
+ expect(find('.board:nth-child(4)')).to have_selector('.card', count: 1)
end
it 'search list' do
@@ -129,32 +125,32 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(find('.board:nth-child(1)')).to have_selector('.card', count: 1)
- expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
+ expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
+ expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
end
it 'allows user to delete board' do
- page.within(find('.board:nth-child(1)')) do
+ page.within(find('.board:nth-child(2)')) do
find('.board-delete').click
end
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'removes checkmark in new list dropdown after deleting' do
click_button 'Add list'
wait_for_requests
- page.within(find('.board:nth-child(1)')) do
+ page.within(find('.board:nth-child(2)')) do
find('.board-delete').click
end
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'infinite scrolls list' do
@@ -165,18 +161,18 @@ describe 'Issue Boards', feature: true, js: true do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('58')
expect(page).to have_selector('.card', count: 20)
expect(page).to have_content('Showing 20 of 58 issues')
- evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
wait_for_requests
expect(page).to have_selector('.card', count: 40)
expect(page).to have_content('Showing 40 of 58 issues')
- evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
wait_for_requests
expect(page).to have_selector('.card', count: 58)
@@ -186,83 +182,83 @@ describe 'Issue Boards', feature: true, js: true do
context 'closed' do
it 'shows list of closed issues' do
- wait_for_board_cards(3, 1)
+ wait_for_board_cards(4, 1)
wait_for_requests
end
it 'moves issue to closed' do
- drag(list_from_index: 0, list_to_index: 2)
+ drag(list_from_index: 1, list_to_index: 3)
- wait_for_board_cards(1, 7)
- wait_for_board_cards(2, 2)
+ wait_for_board_cards(2, 7)
wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 2)
- expect(find('.board:nth-child(1)')).not_to have_content(issue9.title)
- expect(find('.board:nth-child(3)')).to have_selector('.card', count: 2)
- expect(find('.board:nth-child(3)')).to have_content(issue9.title)
- expect(find('.board:nth-child(3)')).not_to have_content(planning.title)
+ expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).to have_selector('.card', count: 2)
+ expect(find('.board:nth-child(4)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
end
it 'removes all of the same issue to closed' do
- drag(list_from_index: 0, list_to_index: 2)
+ drag(list_from_index: 1, list_to_index: 3)
- wait_for_board_cards(1, 7)
- wait_for_board_cards(2, 2)
+ wait_for_board_cards(2, 7)
wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 2)
- expect(find('.board:nth-child(1)')).not_to have_content(issue9.title)
- expect(find('.board:nth-child(3)')).to have_content(issue9.title)
- expect(find('.board:nth-child(3)')).not_to have_content(planning.title)
+ expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
end
end
context 'lists' do
it 'changes position of list' do
- drag(list_from_index: 1, list_to_index: 0, selector: '.board-header')
+ drag(list_from_index: 2, list_to_index: 1, selector: '.board-header')
- wait_for_board_cards(1, 2)
- wait_for_board_cards(2, 8)
- wait_for_board_cards(3, 1)
+ wait_for_board_cards(2, 2)
+ wait_for_board_cards(3, 8)
+ wait_for_board_cards(4, 1)
- expect(find('.board:nth-child(1)')).to have_content(development.title)
- expect(find('.board:nth-child(1)')).to have_content(planning.title)
+ expect(find('.board:nth-child(2)')).to have_content(development.title)
+ expect(find('.board:nth-child(2)')).to have_content(planning.title)
end
it 'issue moves between lists' do
- drag(list_from_index: 0, from_index: 1, list_to_index: 1)
+ drag(list_from_index: 1, from_index: 1, list_to_index: 2)
- wait_for_board_cards(1, 7)
- wait_for_board_cards(2, 2)
- wait_for_board_cards(3, 1)
+ wait_for_board_cards(2, 7)
+ wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 1)
- expect(find('.board:nth-child(2)')).to have_content(issue6.title)
- expect(find('.board:nth-child(2)').all('.card').last).not_to have_content(development.title)
+ expect(find('.board:nth-child(3)')).to have_content(issue6.title)
+ expect(find('.board:nth-child(3)').all('.card').last).not_to have_content(development.title)
end
it 'issue moves between lists' do
- drag(list_from_index: 1, list_to_index: 0)
+ drag(list_from_index: 2, list_to_index: 1)
- wait_for_board_cards(1, 9)
- wait_for_board_cards(2, 1)
+ wait_for_board_cards(2, 9)
wait_for_board_cards(3, 1)
+ wait_for_board_cards(4, 1)
- expect(find('.board:nth-child(1)')).to have_content(issue7.title)
- expect(find('.board:nth-child(1)').all('.card').first).not_to have_content(planning.title)
+ expect(find('.board:nth-child(2)')).to have_content(issue7.title)
+ expect(find('.board:nth-child(2)').all('.card').first).not_to have_content(planning.title)
end
it 'issue moves from closed' do
- drag(list_from_index: 2, list_to_index: 1)
+ drag(list_from_index: 3, list_to_index: 2)
- expect(find('.board:nth-child(2)')).to have_content(issue8.title)
+ expect(find('.board:nth-child(3)')).to have_content(issue8.title)
- wait_for_board_cards(1, 8)
- wait_for_board_cards(2, 3)
- wait_for_board_cards(3, 0)
+ wait_for_board_cards(2, 8)
+ wait_for_board_cards(3, 3)
+ wait_for_board_cards(4, 0)
end
context 'issue card' do
it 'shows assignee' do
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.avatar', count: 1)
end
end
@@ -290,7 +286,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 5)
end
it 'creates new list for Backlog label' do
@@ -303,7 +299,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 5)
end
it 'creates new list for Closed label' do
@@ -316,7 +312,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 5)
end
it 'keeps dropdown open after adding new list' do
@@ -348,7 +344,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
wait_for_requests
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 5)
end
end
end
@@ -360,8 +356,8 @@ describe 'Issue Boards', feature: true, js: true do
submit_filter
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
it 'filters by assignee' do
@@ -371,8 +367,8 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
it 'filters by milestone' do
@@ -381,9 +377,9 @@ describe 'Issue Boards', feature: true, js: true do
submit_filter
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_board_cards(2, 0)
+ wait_for_board_cards(2, 1)
wait_for_board_cards(3, 0)
+ wait_for_board_cards(4, 0)
end
it 'filters by label' do
@@ -392,8 +388,8 @@ describe 'Issue Boards', feature: true, js: true do
submit_filter
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
it 'filters by label with space after reload' do
@@ -403,17 +399,17 @@ describe 'Issue Boards', feature: true, js: true do
# Test after reload
page.evaluate_script 'window.location.reload()'
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
wait_for_requests
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('1')
expect(page).to have_selector('.card', count: 1)
end
- page.within(find('.board:nth-child(2)')) do
+ page.within(find('.board:nth-child(3)')) do
expect(page.find('.board-header')).to have_content('0')
expect(page).to have_selector('.card', count: 0)
end
@@ -424,12 +420,12 @@ describe 'Issue Boards', feature: true, js: true do
click_filter_link(testing.title)
submit_filter
- wait_for_board_cards(1, 1)
+ wait_for_board_cards(2, 1)
find('.clear-search').click
submit_filter
- wait_for_board_cards(1, 8)
+ wait_for_board_cards(2, 8)
end
it 'infinite scrolls list with label filter' do
@@ -443,17 +439,17 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('51')
expect(page).to have_selector('.card', count: 20)
expect(page).to have_content('Showing 20 of 51 issues')
- evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
expect(page).to have_selector('.card', count: 40)
expect(page).to have_content('Showing 40 of 51 issues')
- evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
expect(page).to have_selector('.card', count: 51)
expect(page).to have_content('Showing all issues')
@@ -471,12 +467,12 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
it 'filters by clicking label button on issue' do
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.card', count: 8)
expect(find('.card', match: :first)).to have_content(bug.title)
click_button(bug.title)
@@ -489,12 +485,12 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..3))
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
it 'removes label filter by clicking label button on issue' do
- page.within(find('.board', match: :first)) do
+ page.within(find('.board:nth-child(2)')) do
page.within(find('.card', match: :first)) do
click_button(bug.title)
end
diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb
index 6c40cb2c9eb..1c289993e28 100644
--- a/spec/features/boards/issue_ordering_spec.rb
+++ b/spec/features/boards/issue_ordering_spec.rb
@@ -25,11 +25,11 @@ describe 'Issue Boards', :feature, :js do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'has un-ordered issue as last issue' do
- page.within(first('.board')) do
+ page.within(find('.board:nth-child(2)')) do
expect(all('.card').last).to have_content(issue4.title)
end
end
@@ -39,7 +39,7 @@ describe 'Issue Boards', :feature, :js do
wait_for_requests
- page.within(first('.board')) do
+ page.within(find('.board:nth-child(2)')) do
expect(first('.card')).to have_content(issue4.title)
end
end
@@ -50,7 +50,7 @@ describe 'Issue Boards', :feature, :js do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'moves from middle to top' do
@@ -113,50 +113,50 @@ describe 'Issue Boards', :feature, :js do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- expect(page).to have_selector('.board', count: 3)
+ expect(page).to have_selector('.board', count: 4)
end
it 'moves to top of another list' do
- drag(list_from_index: 0, list_to_index: 1)
+ drag(list_from_index: 1, list_to_index: 2)
wait_for_requests
- expect(first('.board')).to have_selector('.card', count: 2)
- expect(all('.board')[1]).to have_selector('.card', count: 4)
+ expect(find('.board:nth-child(2)')).to have_selector('.card', count: 2)
+ expect(all('.board')[2]).to have_selector('.card', count: 4)
- page.within(all('.board')[1]) do
+ page.within(all('.board')[2]) do
expect(first('.card')).to have_content(issue3.title)
end
end
it 'moves to bottom of another list' do
- drag(list_from_index: 0, list_to_index: 1, to_index: 2)
+ drag(list_from_index: 1, list_to_index: 2, to_index: 2)
wait_for_requests
- expect(first('.board')).to have_selector('.card', count: 2)
- expect(all('.board')[1]).to have_selector('.card', count: 4)
+ expect(find('.board:nth-child(2)')).to have_selector('.card', count: 2)
+ expect(all('.board')[2]).to have_selector('.card', count: 4)
- page.within(all('.board')[1]) do
+ page.within(all('.board')[2]) do
expect(all('.card').last).to have_content(issue3.title)
end
end
it 'moves to index of another list' do
- drag(list_from_index: 0, list_to_index: 1, to_index: 1)
+ drag(list_from_index: 1, list_to_index: 2, to_index: 1)
wait_for_requests
- expect(first('.board')).to have_selector('.card', count: 2)
- expect(all('.board')[1]).to have_selector('.card', count: 4)
+ expect(find('.board:nth-child(2)')).to have_selector('.card', count: 2)
+ expect(all('.board')[2]).to have_selector('.card', count: 4)
- page.within(all('.board')[1]) do
+ page.within(all('.board')[2]) do
expect(all('.card')[1]).to have_content(issue3.title)
end
end
end
- def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0)
+ def drag(selector: '.board-list', list_from_index: 1, from_index: 0, to_index: 0, list_to_index: 1)
drag_to(selector: selector,
scrollable: '#board-app',
list_from_index: list_from_index,
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index 0e98f994018..056224dc436 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -15,15 +15,15 @@ describe 'Issue Boards new issue', feature: true, js: true do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
- expect(page).to have_selector('.board', count: 2)
+ expect(page).to have_selector('.board', count: 3)
end
it 'displays new issue button' do
- expect(page).to have_selector('.board-issue-count-holder .btn', count: 1)
+ expect(first('.board')).to have_selector('.board-issue-count-holder .btn', count: 1)
end
it 'does not display new issue button in closed list' do
- page.within('.board:nth-child(2)') do
+ page.within('.board:nth-child(3)') do
expect(page).not_to have_selector('.board-issue-count-holder .btn')
end
end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 34f4d765117..235e4899707 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -13,7 +13,7 @@ describe 'Issue Boards', feature: true, js: true do
let!(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch], relative_position: 1) }
let(:board) { create(:board, project: project) }
let!(:list) { create(:list, board: board, label: development, position: 0) }
- let(:card) { first('.board').first('.card') }
+ let(:card) { find('.board:nth-child(2)').first('.card') }
before do
Timecop.freeze
@@ -74,7 +74,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_requests
- page.within(first('.board')) do
+ page.within(find('.board:nth-child(2)')) do
expect(page).to have_selector('.card', count: 1)
end
end
@@ -101,7 +101,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'removes the assignee' do
- card_two = first('.board').find('.card:nth-child(2)')
+ card_two = find('.board:nth-child(2)').find('.card:nth-child(2)')
click_card(card_two)
page.within('.assignee') do
@@ -154,7 +154,7 @@ describe 'Issue Boards', feature: true, js: true do
expect(page).to have_content(user.name)
end
- page.within(first('.board')) do
+ page.within(find('.board:nth-child(2)')) do
find('.card:nth-child(2)').trigger('click')
end
diff --git a/spec/fixtures/api/schemas/list.json b/spec/fixtures/api/schemas/list.json
index 11a4caf6628..622a1e40d07 100644
--- a/spec/fixtures/api/schemas/list.json
+++ b/spec/fixtures/api/schemas/list.json
@@ -10,7 +10,7 @@
"id": { "type": "integer" },
"list_type": {
"type": "string",
- "enum": ["label", "closed"]
+ "enum": ["backlog", "label", "closed"]
},
"label": {
"type": ["object", "null"],
diff --git a/spec/javascripts/boards/components/board_spec.js b/spec/javascripts/boards/components/board_spec.js
new file mode 100644
index 00000000000..c4e8966ad6c
--- /dev/null
+++ b/spec/javascripts/boards/components/board_spec.js
@@ -0,0 +1,112 @@
+import Vue from 'vue';
+import '~/boards/services/board_service';
+import '~/boards/components/board';
+import '~/boards/models/list';
+
+describe('Board component', () => {
+ let vm;
+ let el;
+
+ beforeEach((done) => {
+ loadFixtures('boards/show.html.raw');
+
+ el = document.createElement('div');
+ document.body.appendChild(el);
+
+ // eslint-disable-next-line no-undef
+ gl.boardService = new BoardService('/', '/', 1);
+
+ vm = new gl.issueBoards.Board({
+ propsData: {
+ boardId: '1',
+ disabled: false,
+ issueLinkBase: '/',
+ rootPath: '/',
+ // eslint-disable-next-line no-undef
+ list: new List({
+ id: 1,
+ position: 0,
+ title: 'test',
+ list_type: 'backlog',
+ }),
+ },
+ }).$mount(el);
+
+ Vue.nextTick(done);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ // remove the component from the DOM
+ document.querySelector('.board').remove();
+
+ localStorage.removeItem(`boards.${vm.boardId}.${vm.list.type}.expanded`);
+ });
+
+ it('board is expandable when list type is backlog', () => {
+ expect(
+ vm.$el.classList.contains('is-expandable'),
+ ).toBe(true);
+ });
+
+ it('board is expandable when list type is closed', (done) => {
+ vm.list.type = 'closed';
+
+ Vue.nextTick(() => {
+ expect(
+ vm.$el.classList.contains('is-expandable'),
+ ).toBe(true);
+
+ done();
+ });
+ });
+
+ it('board is not expandable when list type is label', (done) => {
+ vm.list.type = 'label';
+ vm.list.isExpandable = false;
+
+ Vue.nextTick(() => {
+ expect(
+ vm.$el.classList.contains('is-expandable'),
+ ).toBe(false);
+
+ done();
+ });
+ });
+
+ it('collapses when clicking header', (done) => {
+ vm.$el.querySelector('.board-header').click();
+
+ Vue.nextTick(() => {
+ expect(
+ vm.$el.classList.contains('is-collapsed'),
+ ).toBe(true);
+
+ done();
+ });
+ });
+
+ it('created sets isExpanded to true from localStorage', (done) => {
+ vm.$el.querySelector('.board-header').click();
+
+ return Vue.nextTick()
+ .then(() => {
+ expect(
+ vm.$el.classList.contains('is-collapsed'),
+ ).toBe(true);
+
+ // call created manually
+ vm.$options.created[0].call(vm);
+
+ return Vue.nextTick();
+ })
+ .then(() => {
+ expect(
+ vm.$el.classList.contains('is-collapsed'),
+ ).toBe(true);
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/fixtures/boards.rb b/spec/javascripts/fixtures/boards.rb
new file mode 100644
index 00000000000..d7c3dc0a235
--- /dev/null
+++ b/spec/javascripts/fixtures/boards.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller do
+ include JavaScriptFixturesHelpers
+
+ let(:admin) { create(:admin) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'boards-project') }
+
+ render_views
+
+ before(:all) do
+ clean_frontend_fixtures('boards/')
+ end
+
+ before(:each) do
+ sign_in(admin)
+ end
+
+ it 'boards/show.html.raw' do |example|
+ get(:index,
+ namespace_id: project.namespace,
+ project_id: project)
+
+ expect(response).to be_success
+ store_frontend_fixture(response, example.description)
+ end
+end
diff --git a/spec/services/boards/create_service_spec.rb b/spec/services/boards/create_service_spec.rb
index a8555f5b4a0..effa4633d13 100644
--- a/spec/services/boards/create_service_spec.rb
+++ b/spec/services/boards/create_service_spec.rb
@@ -14,8 +14,9 @@ describe Boards::CreateService, services: true do
it 'creates the default lists' do
board = service.execute
- expect(board.lists.size).to eq 1
- expect(board.lists.first).to be_closed
+ expect(board.lists.size).to eq 2
+ expect(board.lists.first).to be_backlog
+ expect(board.lists.last).to be_closed
end
end
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index c982031c791..a1e220c2322 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -13,6 +13,7 @@ describe Boards::Issues::ListService, services: true do
let(:p2) { create(:label, title: 'P2', project: project, priority: 2) }
let(:p3) { create(:label, title: 'P3', project: project, priority: 3) }
+ let!(:backlog) { create(:backlog_list, board: board) }
let!(:list1) { create(:list, board: board, label: development, position: 0) }
let!(:list2) { create(:list, board: board, label: testing, position: 1) }
let!(:closed) { create(:closed_list, board: board) }
@@ -53,12 +54,20 @@ describe Boards::Issues::ListService, services: true do
expect(issues).to eq [opened_issue2, reopened_issue1, opened_issue1]
end
+ it 'returns opened issues when listing issues from Backlog' do
+ params = { board_id: board.id, id: backlog.id }
+
+ issues = described_class.new(project, user, params).execute
+
+ expect(issues).to eq [opened_issue2, reopened_issue1, opened_issue1]
+ end
+
it 'returns closed issues when listing issues from Closed' do
params = { board_id: board.id, id: closed.id }
issues = described_class.new(project, user, params).execute
- expect(issues).to eq [closed_issue4, closed_issue2, closed_issue5, closed_issue3, closed_issue1]
+ expect(issues).to eq [closed_issue4, closed_issue2, closed_issue3, closed_issue1]
end
it 'returns opened issues that have label list applied when listing issues from a label list' do
diff --git a/spec/services/boards/lists/list_service_spec.rb b/spec/services/boards/lists/list_service_spec.rb
index ab9fb1bc914..68140759600 100644
--- a/spec/services/boards/lists/list_service_spec.rb
+++ b/spec/services/boards/lists/list_service_spec.rb
@@ -1,16 +1,33 @@
require 'spec_helper'
describe Boards::Lists::ListService, services: true do
+ let(:project) { create(:empty_project) }
+ let(:board) { create(:board, project: project) }
+ let(:label) { create(:label, project: project) }
+ let!(:list) { create(:list, board: board, label: label) }
+ let(:service) { described_class.new(project, double) }
+
describe '#execute' do
- it "returns board's lists" do
- project = create(:empty_project)
- board = create(:board, project: project)
- label = create(:label, project: project)
- list = create(:list, board: board, label: label)
+ context 'when the board has a backlog list' do
+ let!(:backlog_list) { create(:backlog_list, board: board) }
+
+ it 'does not create a backlog list' do
+ expect { service.execute(board) }.not_to change(board.lists, :count)
+ end
+
+ it "returns board's lists" do
+ expect(service.execute(board)).to eq [backlog_list, list, board.closed_list]
+ end
+ end
- service = described_class.new(project, double)
+ context 'when the board does not have a backlog list' do
+ it 'creates a backlog list' do
+ expect { service.execute(board) }.to change(board.lists, :count).by(1)
+ end
- expect(service.execute(board)).to eq [list, board.closed_list]
+ it "returns board's lists" do
+ expect(service.execute(board)).to eq [board.backlog_list, list, board.closed_list]
+ end
end
end
end
diff --git a/spec/support/javascript_fixtures_helpers.rb b/spec/support/javascript_fixtures_helpers.rb
index a982b159b48..aace4b3adee 100644
--- a/spec/support/javascript_fixtures_helpers.rb
+++ b/spec/support/javascript_fixtures_helpers.rb
@@ -48,7 +48,7 @@ module JavaScriptFixturesHelpers
link_tags = doc.css('link')
link_tags.remove
- scripts = doc.css("script:not([type='text/template'])")
+ scripts = doc.css("script:not([type='text/template']):not([type='text/x-template'])")
scripts.remove
fixture = doc.to_html