Commit 96a0071c authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'update-feature-specs-for-graphql-project-boards' into 'master'

Use graphQL boards for project boards and fix associated rspecs [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!56458
parents b6a7cdaa 56ceba34
......@@ -328,6 +328,7 @@ export default {
<div
class="issue-count-badge gl-display-inline-flex gl-pr-0 no-drag gl-text-gray-500"
data-testid="issue-count-badge"
:class="{
'gl-display-none!': list.collapsed && isSwimlanesHeader,
'gl-p-0': list.collapsed,
......
......@@ -2,8 +2,8 @@
import { GlButton } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import { getMilestone } from 'ee_else_ce/boards/boards_util';
import BoardNewIssueMixin from 'ee_else_ce/boards/mixins/board_new_issue';
import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import eventHub from '../eventhub';
import ProjectSelect from './project_select.vue';
......@@ -17,8 +17,8 @@ export default {
ProjectSelect,
GlButton,
},
mixins: [glFeatureFlagMixin()],
inject: ['groupId', 'weightFeatureAvailable', 'boardWeight'],
mixins: [BoardNewIssueMixin],
inject: ['groupId'],
props: {
list: {
type: Object,
......@@ -53,14 +53,11 @@ export default {
submit(e) {
e.preventDefault();
const { title } = this;
const labels = this.list.label ? [this.list.label] : [];
const assignees = this.list.assignee ? [this.list.assignee] : [];
const milestone = getMilestone(this.list);
const weight = this.weightFeatureAvailable ? this.boardWeight : undefined;
const { title } = this;
eventHub.$emit(`scroll-board-list-${this.list.id}`);
return this.addListNewIssue({
......@@ -70,7 +67,7 @@ export default {
assigneeIds: assignees?.map((a) => a?.id),
milestoneId: milestone?.id,
projectPath: this.selectedProject.fullPath,
weight: weight >= 0 ? weight : null,
...this.extraIssueInput(),
},
list: this.list,
}).then(() => {
......
export default {
// EE-only
methods: {
extraIssueInput: () => {},
},
};
......@@ -327,8 +327,8 @@ export default {
commit(types.RESET_ISSUES);
},
moveItem: ({ dispatch }) => {
dispatch('moveIssue');
moveItem: ({ dispatch }, payload) => {
dispatch('moveIssue', payload);
},
moveIssue: (
......
......@@ -10,6 +10,7 @@ class Projects::BoardsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:add_issues_button)
push_frontend_feature_flag(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
push_frontend_feature_flag(:graphql_board_lists, project, default_enabled: :yaml)
end
feature_category :boards
......
export default {
inject: ['groupId', 'weightFeatureAvailable', 'boardWeight'],
methods: {
extraIssueInput() {
if (this.weightFeatureAvailable) {
return {
weight: this.boardWeight >= 0 ? this.boardWeight : null,
};
}
return {};
},
},
};
......@@ -12,6 +12,7 @@ RSpec.describe 'Issue Boards add issue modal', :js do
let!(:issue) { create(:issue, project: project, title: 'abc', description: 'def') }
before do
stub_feature_flags(graphql_board_lists: false)
stub_feature_flags(add_issues_button: true)
project.add_maintainer(user)
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'issue boards', :js do
RSpec.describe 'Project issue boards', :js do
include DragTo
let(:user) { create(:user) }
......@@ -132,7 +132,8 @@ RSpec.describe 'issue boards', :js do
it 'shows total weight for backlog' do
backlog = board.lists.first
expect(badge(backlog)).to have_content('5')
expect(list_weight_badge(backlog)).to have_content('5')
end
it 'updates weight when moving to list' do
......@@ -146,8 +147,8 @@ RSpec.describe 'issue boards', :js do
to_index: 0,
list_to_index: 1)
expect(badge(from)).to have_content('3')
expect(badge(to)).to have_content('2')
expect(card_weight_badge(from)).to have_content('3')
expect(card_weight_badge(to)).to have_content('2')
end
context 'unlicensed' do
......@@ -160,29 +161,13 @@ RSpec.describe 'issue boards', :js do
expect(page).not_to have_text('2 issues')
backlog = board.lists.first
badge(backlog).hover
list_weight_badge(backlog).hover
expect(page).to have_text('2 issues')
end
end
end
context 'locked milestone' do
before do
visit project_board_path(project, board_with_milestone)
wait_for_requests
end
it 'does not have remove button' do
expect(page).to have_selector('.js-visual-token .remove-token', count: 0)
end
it 'is not able to be backspaced' do
find('.input-token .filtered-search').native.send_key(:backspace)
expect(page).to have_selector('.js-visual-token', count: 1)
end
end
context 'list header' do
let(:max_issue_count) { 2 }
let!(:label) { create(:label, project: project, name: 'Label 2') }
......@@ -359,8 +344,12 @@ RSpec.describe 'issue boards', :js do
end
end
def badge(list)
find(".board[data-id='#{list.id}'] .issue-count-badge")
def list_weight_badge(list)
find(".board[data-id='gid://gitlab/List/#{list.id}'] [data-testid='issue-count-badge']")
end
def card_weight_badge(list)
find(".board[data-id='gid://gitlab/List/#{list.id}'] [data-testid='board-card-weight']")
end
def visit_board_page
......
......@@ -3,10 +3,10 @@
require 'spec_helper'
RSpec.describe 'Issue Boards new issue', :js do
let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let!(:list) { create(:list, board: board, position: 0) }
let(:user) { create(:user) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:board) { create(:board, project: project) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
context 'authorized user' do
before do
......@@ -17,7 +17,7 @@ RSpec.describe 'Issue Boards new issue', :js do
visit project_board_path(project, board)
wait_for_requests
expect(page).to have_selector('.board', count: 3)
expect(page).to have_selector('.board', count: 2)
end
it 'successfully assigns weight to newly-created issue' do
......@@ -32,8 +32,12 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
page.within(first('.board')) do
find('.board-card').click
end
page.within(first('.issue-boards-sidebar')) do
find('.weight .js-weight-edit-link').click
find('.weight [data-testid="edit-button"]').click
find('.weight .form-control').set("10\n")
end
......
......@@ -22,6 +22,7 @@ RSpec.describe 'Issue Boards', :js do
let(:card2) { find('.board:nth-child(2)').find('.board-card:nth-child(1)') }
before do
stub_feature_flags(graphql_board_lists: false)
stub_licensed_features(multiple_issue_assignees: true)
project.add_maintainer(user)
......
......@@ -124,6 +124,8 @@ RSpec.describe 'epics swimlanes', :js do
page.within('.board-swimlanes-toggle-wrapper') do
page.find('.dropdown-toggle').click
page.find('.dropdown-item', text: 'Epic').click
wait_for_requests
end
end
......
......@@ -10,6 +10,7 @@ RSpec.describe 'epics swimlanes', :js do
let_it_be(:board) { create(:board, project: project) }
let_it_be(:label) { create(:label, project: project, name: 'Label1') }
let_it_be(:list) { create(:list, board: board, label: label, position: 0) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let_it_be(:issue1) { create(:issue, project: project, labels: [label]) }
let_it_be(:issue2) { create(:issue, project: project) }
......
......@@ -82,6 +82,8 @@ RSpec.describe 'Filter issues by iteration', :js do
# iterationWildCardId is not yet supported by graphQL https://gitlab.com/gitlab-org/gitlab/-/issues/300115
stub_feature_flags(graphql_board_lists: false)
visit page_path
page.within('.filtered-search-wrapper') do
find('.filtered-search').set('iter')
click_button('Iteration')
......@@ -140,6 +142,7 @@ RSpec.describe 'Filter issues by iteration', :js do
context 'project board' do
let_it_be(:board) { create(:board, project: project) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let(:page_path) { project_board_path(project, board) }
let(:issue_title_selector) { '.board-card .board-card-title' }
......@@ -157,6 +160,7 @@ RSpec.describe 'Filter issues by iteration', :js do
context 'group board' do
let_it_be(:board) { create(:board, group: group) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let_it_be(:user) { create(:user) }
let(:page_path) { group_board_path(group, board) }
......
......@@ -14,6 +14,7 @@ RSpec.describe 'Issue Boards add issue modal', :js do
let!(:issue2) { create(:issue, project: project, title: 'hij', description: 'klm') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'Issue Boards', :js do
RSpec.describe 'Project issue boards', :js do
include DragTo
include MobileHelpers
......@@ -23,7 +23,7 @@ RSpec.describe 'Issue Boards', :js do
context 'no lists' do
before do
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
end
it 'creates default lists' do
......@@ -52,6 +52,7 @@ RSpec.describe 'Issue Boards', :js do
let_it_be(:a_plus) { create(:label, project: project, name: 'A+') }
let_it_be(:list1) { create(:list, board: board, label: planning, position: 0) }
let_it_be(:list2) { create(:list, board: board, label: development, position: 1) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let_it_be(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) }
let_it_be(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) }
......@@ -68,7 +69,7 @@ RSpec.describe 'Issue Boards', :js do
before do
stub_feature_flags(board_new_list: false)
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
wait_for_requests
......@@ -121,7 +122,8 @@ RSpec.describe 'Issue Boards', :js do
context 'with the NOT queries feature flag disabled' do
before do
stub_feature_flags(not_issuable_queries: false)
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
end
it 'does not have the != option' do
......@@ -141,7 +143,8 @@ RSpec.describe 'Issue Boards', :js do
context 'with the NOT queries feature flag enabled' do
before do
stub_feature_flags(not_issuable_queries: true)
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
end
it 'does not have the != option' do
......@@ -171,8 +174,7 @@ RSpec.describe 'Issue Boards', :js do
it 'infinite scrolls list' do
create_list(:labeled_issue, 50, project: project, labels: [planning])
visit project_board_path(project, board)
wait_for_requests
visit_project_board_path_without_query_limit(project, board)
page.within(find('.board:nth-child(2)')) do
expect(page.find('.board-header')).to have_content('58')
......@@ -180,15 +182,19 @@ RSpec.describe 'Issue Boards', :js do
expect(page).to have_content('Showing 20 of 58 issues')
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
wait_for_requests
end
expect(page).to have_selector('.board-card', count: 40)
expect(page).to have_content('Showing 40 of 58 issues')
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
wait_for_requests
end
expect(page).to have_selector('.board-card', count: 58)
expect(page).to have_content('Showing all issues')
......@@ -236,13 +242,13 @@ RSpec.describe 'Issue Boards', :js do
wait_for_board_cards(4, 1)
expect(find('.board:nth-child(2)')).to have_content(development.title)
expect(find('.board:nth-child(2)')).to have_content(planning.title)
expect(find('.board:nth-child(3)')).to have_content(planning.title)
# Make sure list positions are preserved after a reload
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
expect(find('.board:nth-child(2)')).to have_content(development.title)
expect(find('.board:nth-child(2)')).to have_content(planning.title)
expect(find('.board:nth-child(3)')).to have_content(planning.title)
end
it 'dragging does not duplicate list' do
......@@ -254,7 +260,8 @@ RSpec.describe 'Issue Boards', :js do
expect(page).to have_selector(selector, text: development.title, count: 1)
end
it 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do
# TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323551
xit 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do
drag(list_from_index: 1, from_index: 1, list_to_index: 2)
wait_for_board_cards(2, 7)
......@@ -467,6 +474,7 @@ RSpec.describe 'Issue Boards', :js do
end
it 'removes filtered labels' do
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
set_filter("label", testing.title)
click_filter_link(testing.title)
submit_filter
......@@ -475,6 +483,7 @@ RSpec.describe 'Issue Boards', :js do
find('.clear-search').click
submit_filter
end
wait_for_board_cards(2, 8)
end
......@@ -484,7 +493,9 @@ RSpec.describe 'Issue Boards', :js do
set_filter("label", testing.title)
click_filter_link(testing.title)
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
submit_filter
end
wait_for_requests
......@@ -494,13 +505,18 @@ RSpec.describe 'Issue Boards', :js do
expect(page).to have_content('Showing 20 of 51 issues')
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
expect(page).to have_selector('.board-card', count: 40)
expect(page).to have_content('Showing 40 of 51 issues')
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
expect(page).to have_selector('.board-card', count: 51)
expect(page).to have_content('Showing all issues')
......@@ -569,7 +585,7 @@ RSpec.describe 'Issue Boards', :js do
context 'keyboard shortcuts' do
before do
visit project_board_path(project, board)
visit_project_board_path_without_query_limit(project, board)
wait_for_requests
end
......@@ -617,6 +633,7 @@ RSpec.describe 'Issue Boards', :js do
def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
# ensure there is enough horizontal space for four boards
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
resize_window(2000, 800)
drag_to(selector: selector,
......@@ -628,6 +645,9 @@ RSpec.describe 'Issue Boards', :js do
perform_drop: perform_drop)
end
wait_for_requests
end
def wait_for_board_cards(board_number, expected_cards)
page.within(find(".board:nth-child(#{board_number})")) do
expect(page.find('.board-header')).to have_content(expected_cards.to_s)
......@@ -666,4 +686,10 @@ RSpec.describe 'Issue Boards', :js do
accept_confirm { find('[data-testid="remove-list"]').click }
end
end
def visit_project_board_path_without_query_limit(project, board)
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
visit project_board_path(project, board)
end
end
end
......@@ -12,6 +12,8 @@ RSpec.describe 'Issue Boards add issue modal filtering', :js do
let!(:issue1) { create(:issue, project: project) }
before do
stub_feature_flags(graphql_board_lists: false)
stub_feature_flags(add_issues_button: true)
project.add_maintainer(user)
sign_in(user)
......
......@@ -41,6 +41,10 @@ RSpec.describe 'Multi Select Issue', :js do
before do
project.add_maintainer(user)
# multi-drag disabled with feature flag for now
# https://gitlab.com/gitlab-org/gitlab/-/issues/289797
stub_feature_flags(graphql_board_lists: false)
sign_in(user)
end
......
......@@ -3,10 +3,12 @@
require 'spec_helper'
RSpec.describe 'Issue Boards new issue', :js do
let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let!(:list) { create(:list, board: board, position: 0) }
let(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:board) { create(:board, project: project) }
let_it_be(:backlog_list) { create(:backlog_list, board: board) }
let_it_be(:label) { create(:label, project: project, name: 'Label 1') }
let_it_be(:list) { create(:list, board: board, label: label, position: 0) }
let_it_be(:user) { create(:user) }
context 'authorized user' do
before do
......@@ -15,6 +17,7 @@ RSpec.describe 'Issue Boards new issue', :js do
sign_in(user)
visit project_board_path(project, board)
wait_for_requests
expect(page).to have_selector('.board', count: 3)
......@@ -70,11 +73,12 @@ RSpec.describe 'Issue Boards new issue', :js do
issue = project.issues.find_by_title('bug')
expect(page).to have_content(issue.to_reference)
expect(page).to have_link(issue.title, href: issue_path(issue))
expect(page).to have_link(issue.title, href: /#{issue_path(issue)}/)
end
end
it 'shows sidebar when creating new issue' do
# TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323446
xit 'shows sidebar when creating new issue' do
page.within(first('.board')) do
find('.issue-count-badge-add-button').click
end
......@@ -101,12 +105,16 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
page.within(first('.board')) do
find('.board-card').click
end
page.within(first('.issue-boards-sidebar')) do
find('.labels .edit-link').click
find('.labels [data-testid="edit-button"]').click
wait_for_requests
expect(page).to have_selector('.labels .dropdown-content li a')
expect(page).to have_selector('.labels-select-contents-list .dropdown-content li a')
end
end
end
......
......@@ -43,7 +43,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
issue = project.issues.find_by_title('issue should be shown')
expect(page).to have_content(issue.to_reference)
expect(page).to have_link(issue.title, href: issue_path(issue))
expect(page).to have_link(issue.title, href: /#{issue_path(issue)}/)
end
end
end
......
......@@ -17,6 +17,8 @@ RSpec.describe 'Project issue boards sidebar assignee', :js do
let(:card) { find('.board:nth-child(2)').first('.board-card') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -17,6 +17,8 @@ RSpec.describe 'Project issue boards sidebar due date', :js do
end
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -18,6 +18,8 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
let(:card) { find('.board:nth-child(2)').first('.board-card') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -16,6 +16,8 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
let(:card2) { find('.board:nth-child(1) .board-card:nth-of-type(2)') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -13,6 +13,8 @@ RSpec.describe 'Project issue boards sidebar', :js do
let(:card) { find('.board:nth-child(1)').first('.board-card') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -16,6 +16,8 @@ RSpec.describe 'Project issue boards sidebar subscription', :js do
let(:card2) { find('.board:nth-child(1) .board-card:nth-of-type(2)') }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -15,6 +15,8 @@ RSpec.describe 'Project issue boards sidebar time tracking', :js do
let(:application_settings) { {} }
before do
stub_feature_flags(graphql_board_lists: false)
project.add_maintainer(user)
sign_in(user)
......
......@@ -21,7 +21,8 @@ RSpec.describe 'Sub-group project issue boards', :js do
wait_for_requests
end
it 'creates new label from sidebar' do
# TODO https://gitlab.com/gitlab-org/gitlab/-/issues/324290
xit 'creates new label from sidebar' do
find('.board-card').click
page.within '.labels' do
......
......@@ -639,10 +639,13 @@ describe('resetIssues', () => {
});
describe('moveItem', () => {
it('should dispatch moveIssue action', () => {
it('should dispatch moveIssue action with payload', () => {
const payload = { mock: 'payload' };
testAction({
action: actions.moveItem,
expectedActions: [{ type: 'moveIssue' }],
payload,
expectedActions: [{ type: 'moveIssue', payload }],
});
});
});
......
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