Commit 30233179 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '355130-clean-up-board-code' into 'master'

Clean up board code

See merge request gitlab-org/gitlab!83805
parents fa70c25b 6aead966
......@@ -240,7 +240,7 @@ export default {
class="board-card-footer gl-display-flex gl-justify-content-space-between gl-align-items-flex-end"
>
<div
class="gl-display-flex align-items-start flex-wrap-reverse board-card-number-container gl-overflow-hidden js-board-card-number-container"
class="gl-display-flex align-items-start flex-wrap-reverse board-card-number-container gl-overflow-hidden"
>
<gl-loading-icon v-if="item.isLoading" size="md" class="mt-3" />
<span
......
......@@ -289,7 +289,7 @@ export default {
<p v-if="isDeleteForm" data-testid="delete-confirmation-message">
{{ $options.i18n.deleteConfirmationMessage }}
</p>
<form v-else class="js-board-config-modal" data-testid="board-form-wrapper" @submit.prevent>
<form v-else data-testid="board-form-wrapper" @submit.prevent>
<div v-if="!readonly" class="gl-mb-5" data-testid="board-form">
<label class="gl-font-weight-bold gl-font-lg" for="board-new-name">
{{ $options.i18n.titleFieldLabel }}
......
......@@ -287,7 +287,7 @@ export default {
:data-board-type="list.listType"
:class="{ 'bg-danger-100': boardItemsSizeExceedsMax }"
draggable=".board-card"
class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2 js-board-list"
class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2"
data-testid="tree-root-wrapper"
@start="handleDragOnStart"
@end="handleDragOnEnd"
......
......@@ -262,7 +262,7 @@ export default {
'gl-py-2': list.collapsed && isSwimlanesHeader,
'gl-flex-direction-column': list.collapsed,
}"
class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3 js-board-handle"
class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3"
>
<gl-button
v-gl-tooltip.hover
......@@ -443,7 +443,7 @@ export default {
ref="settingsBtn"
v-gl-tooltip.hover
:aria-label="$options.i18n.listSettings"
class="no-drag js-board-settings-button"
class="no-drag"
:title="$options.i18n.listSettings"
icon="settings"
@click="openSidebarSettings"
......
......@@ -239,11 +239,12 @@ export default {
</script>
<template>
<div class="boards-switcher js-boards-selector gl-mr-3">
<span class="boards-selector-wrapper js-boards-selector-wrapper">
<div class="boards-switcher gl-mr-3" data-testid="boards-selector">
<span class="boards-selector-wrapper">
<gl-dropdown
data-testid="boards-dropdown"
data-qa-selector="boards_dropdown"
toggle-class="dropdown-menu-toggle js-dropdown-toggle"
toggle-class="dropdown-menu-toggle"
menu-class="flex-column dropdown-extended-height"
:loading="isBoardLoading"
:text="board.name"
......@@ -276,8 +277,8 @@ export default {
<gl-dropdown-item
v-for="recentBoard in recentBoards"
:key="`recent-${recentBoard.id}`"
class="js-dropdown-item"
:href="`${boardBaseUrl}/${recentBoard.id}`"
data-testid="dropdown-item"
>
{{ recentBoard.name }}
</gl-dropdown-item>
......@@ -292,8 +293,8 @@ export default {
<gl-dropdown-item
v-for="otherBoard in filteredBoards"
:key="otherBoard.id"
class="js-dropdown-item"
:href="`${boardBaseUrl}/${otherBoard.id}`"
data-testid="dropdown-item"
>
{{ otherBoard.name }}
</gl-dropdown-item>
......@@ -331,7 +332,7 @@ export default {
<gl-dropdown-item
v-if="showDelete"
v-gl-modal-directive="'board-config-modal'"
class="text-danger js-delete-board"
class="text-danger"
@click.prevent="showPage('delete')"
>
{{ s__('IssueBoards|Delete board') }}
......
......@@ -43,7 +43,7 @@ export default {
<gl-tooltip
:target="() => $refs.issueTimeEstimate"
placement="bottom"
class="js-issue-time-estimate"
data-testid="issue-time-estimate"
>
<span class="gl-font-weight-bold gl-display-block">{{ $options.i18n.timeEstimate }}</span>
{{ title }}
......
......@@ -29,7 +29,7 @@ export default {
<span :class="{ 'text-danger': issuesExceedMax }" data-testid="board-items-count">
{{ itemsSize }}
</span>
<span v-if="isMaxLimitSet" class="js-max-issue-size">
<span v-if="isMaxLimitSet" class="max-issue-size">
{{ maxIssueCount }}
</span>
</div>
......
......@@ -38,7 +38,6 @@ export default {
v-gl-tooltip
category="tertiary"
:icon="isFullscreen ? 'minimize' : 'maximize'"
class="js-focus-mode-btn"
data-qa-selector="focus_mode_button"
:title="$options.i18n.toggleFocusMode"
:aria-label="$options.i18n.toggleFocusMode"
......
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ConfigToggle from './components/config_toggle.vue';
export default () => {
const el = document.querySelector('.js-board-config');
if (!el) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el,
name: 'ConfigToggleRoot',
render(h) {
return h(ConfigToggle, {
props: {
canAdminList: parseBoolean(el.dataset.canAdminList),
hasScope: parseBoolean(el.dataset.hasScope),
},
});
},
});
};
......@@ -13,7 +13,6 @@ import {
} from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
import { fullBoardId } from './boards_util';
import initNewBoard from './new_board';
import { gqlClient } from './graphql';
Vue.use(VueApollo);
......@@ -112,6 +111,4 @@ export default () => {
});
mountBoardApp($boardApp);
initNewBoard();
};
import Vue from 'vue';
import IssueBoardFilteredSearch from 'ee_else_ce/boards/components/issue_board_filtered_search.vue';
import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
export default (
apolloProvider,
isSignedIn,
releasesFetchPath,
epicFeatureAvailable,
iterationFeatureAvailable,
) => {
const el = document.getElementById('js-issue-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
const initialFilterParams = {
...convertObjectPropsToCamelCase(rawFilterParams, {}),
};
if (!el) {
return null;
}
return new Vue({
el,
name: 'BoardFilteredSearchRoot',
provide: {
initialFilterParams,
isSignedIn,
releasesFetchPath,
epicFeatureAvailable,
iterationFeatureAvailable,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
render: (createElement) =>
createElement(IssueBoardFilteredSearch, {
props: { fullPath: store.state?.fullPath || '', boardType: store.state?.boardType || '' },
}),
});
};
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
import store from '~/boards/stores';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
export default (params = {}) => {
const boardsSwitcherElement = document.getElementById('js-multiple-boards-switcher');
const { dataset } = boardsSwitcherElement;
return new Vue({
el: boardsSwitcherElement,
name: 'BoardsSelectorRoot',
components: {
BoardsSelector,
},
apolloProvider,
store,
provide: {
fullPath: params.fullPath,
rootPath: params.rootPath,
allowScopedLabels: params.allowScopedLabels,
labelsManagePath: params.labelsManagePath,
allowLabelCreate: parseBoolean(dataset.canAdminBoard),
},
data() {
const boardsSelectorProps = {
...dataset,
hasMissingBoards: parseBoolean(dataset.hasMissingBoards),
canAdminBoard: parseBoolean(dataset.canAdminBoard),
multipleIssueBoardsAvailable: parseBoolean(dataset.multipleIssueBoardsAvailable),
scopedIssueBoardFeatureEnabled: parseBoolean(dataset.scopedIssueBoardFeatureEnabled),
weights: JSON.parse(dataset.weights),
};
return { boardsSelectorProps };
},
render(createElement) {
return createElement(BoardsSelector, {
props: this.boardsSelectorProps,
});
},
});
};
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getExperimentVariant } from '~/experimentation/utils';
import { CANDIDATE_VARIANT } from '~/experimentation/constants';
import NewBoardButton from './components/new_board_button.vue';
export default () => {
if (getExperimentVariant('prominent_create_board_btn') !== CANDIDATE_VARIANT) {
return;
}
const el = document.querySelector('.js-new-board');
if (!el) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el,
provide: {
multipleIssueBoardsAvailable: parseBoolean(el.dataset.multipleIssueBoardsAvailable),
canAdminBoard: parseBoolean(el.dataset.canAdminBoard),
},
render(h) {
return h(NewBoardButton);
},
});
};
import Vue from 'vue';
import ToggleFocus from './components/toggle_focus.vue';
export default () => {
const issueBoardsContentSelector = '.content-wrapper > .js-focus-mode-board';
return new Vue({
el: '#js-toggle-focus-btn',
name: 'ToggleFocusRoot',
render(h) {
return h(ToggleFocus, {
props: {
issueBoardsContentSelector,
},
});
},
});
};
......@@ -198,7 +198,7 @@
border-bottom: 1px solid var(--gray-100, $gray-100);
height: 3rem;
.js-max-issue-size::before {
.max-issue-size::before {
content: '/';
}
}
......
......@@ -43,8 +43,6 @@ class Groups::BoardsController < Groups::ApplicationController
def assign_endpoint_vars
@boards_endpoint = group_boards_path(group)
@namespace_path = group.to_param
@labels_endpoint = group_labels_path(group)
end
def authorize_read_board!
......
......@@ -44,8 +44,6 @@ class Projects::BoardsController < Projects::ApplicationController
def assign_endpoint_vars
@boards_endpoint = project_boards_path(project)
@bulk_issues_path = bulk_update_project_issues_path(project)
@namespace_path = project.namespace.full_path
@labels_endpoint = project_labels_path(project)
end
def authorize_read_board!
......
......@@ -127,20 +127,6 @@ module BoardsHelper
can?(current_user, :admin_issue, current_board_parent)
end
def board_list_data
include_descendant_groups = @group&.present?
{
toggle: "dropdown",
list_labels_path: labels_filter_path_with_defaults(only_group_labels: true, include_ancestor_groups: true),
labels: labels_filter_path_with_defaults(only_group_labels: true, include_descendant_groups: include_descendant_groups),
labels_endpoint: @labels_endpoint,
namespace_path: @namespace_path,
project_path: @project&.path,
group_path: @group&.path
}
end
def serializer
CurrentBoardSerializer.new
end
......
- parent = board.resource_parent
- milestone_filter_opts = { format: :json }
- milestone_filter_opts = milestone_filter_opts.merge(only_group_milestones: true) if board.group_board?
- weights = Gitlab.ee? ? ([Issue::WEIGHT_ANY] + Issue.weight_options) : []
#js-multiple-boards-switcher.inline.boards-switcher{ data: { milestone_path: milestones_filter_path(milestone_filter_opts),
board_base_url: board_base_url,
has_missing_boards: (!multiple_boards_available? && current_board_parent.boards.size > 1).to_s,
can_admin_board: can?(current_user, :admin_issue_board, parent).to_s,
multiple_issue_boards_available: parent.multiple_issue_boards_available?.to_s,
scoped_issue_board_feature_enabled: Gitlab.ee? && parent.feature_available?(:scoped_issue_board) ? 'true' : 'false',
weights: weights.to_json } }
......@@ -107,8 +107,9 @@ export default {
<div class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-mb-2">
<label class="m-0">{{ $options.i18n.wipLimitText }}</label>
<gl-button
class="js-edit-button gl-h-full gl-border-0 text-dark"
class="gl-h-full gl-border-0 text-dark"
variant="link"
data-testid="edit-button"
@click="showInput"
>{{ $options.i18n.editLinkText }}</gl-button
>
......@@ -128,12 +129,13 @@ export default {
@blur="offFocus"
/>
<div v-else class="gl-display-flex gl-align-items-center">
<p class="js-wip-limit bold gl-m-0 text-secondary">{{ activeListWipLimit }}</p>
<p class="bold gl-m-0 text-secondary" data-testid="wip-limit">{{ activeListWipLimit }}</p>
<template v-if="wipLimitIsSet">
<span class="m-1">-</span>
<gl-button
class="js-remove-limit gl-h-full gl-border-0 text-secondary"
class="gl-h-full gl-border-0 text-secondary"
variant="link"
data-testid="remove-limit"
@click="clearWipLimit"
>{{ $options.i18n.removeLimitText }}</gl-button
>
......
......@@ -30,11 +30,7 @@ export default {
>
<gl-icon name="weight" class="board-card-info-icon gl-mr-2" />
<span data-testid="board-card-weight" class="board-card-info-text"> {{ weight }} </span>
<gl-tooltip
:target="() => $refs.itemWeight"
placement="bottom"
container="body"
class="js-item-weight"
<gl-tooltip :target="() => $refs.itemWeight" placement="bottom" container="body"
>{{ __('Weight') }}<br /><span class="text-tertiary">{{ weight }}</span>
</gl-tooltip>
</component>
......
import Vue from 'vue';
import EpicFilteredSearch from 'ee_component/boards/components/epic_filtered_search.vue';
import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
export default (apolloProvider) => {
const el = document.getElementById('js-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
const initialFilterParams = {
...convertObjectPropsToCamelCase(rawFilterParams, {}),
};
if (!el) {
return null;
}
return new Vue({
el,
name: 'EpicBoardFilteredSearchRoot',
provide: {
initialFilterParams,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
render: (createElement) =>
createElement(EpicFilteredSearch, {
props: { fullPath: store.state?.fullPath || '', boardType: store.state?.boardType || '' },
}),
});
};
import Vue from 'vue';
import store from '~/boards/stores';
import ToggleEpicsSwimlanes from './components/toggle_epics_swimlanes.vue';
export default () => {
const el = document.getElementById('js-board-epics-swimlanes-toggle');
if (!el) {
return null;
}
return new Vue({
el,
name: 'ToggleEpicsSwimlanesRoot',
components: {
ToggleEpicsSwimlanes,
},
store,
render(createElement) {
return createElement(ToggleEpicsSwimlanes);
},
});
};
import Vue from 'vue';
import store from '~/boards/stores';
import ToggleLabels from './components/toggle_labels.vue';
export default () =>
new Vue({
el: document.getElementById('js-board-labels-toggle'),
name: 'ToggleLabelsRoot',
components: {
ToggleLabels,
},
store,
render: (createElement) => createElement('toggle-labels'),
});
......@@ -63,8 +63,6 @@ class Groups::EpicBoardsController < Groups::ApplicationController
def assign_endpoint_vars
@boards_endpoint = group_epic_boards_path(group)
@namespace_path = group.to_param
@labels_endpoint = group_labels_path(group)
end
def authorize_read_board!
......
......@@ -4,12 +4,6 @@ module EE
module BoardsHelper
extend ::Gitlab::Utils::Override
override :board_list_data
def board_list_data
super.merge(list_milestone_path: board_milestones_path(board, :json),
list_assignees_path: board_users_path(board, :json))
end
# rubocop:disable Metrics/AbcSize
override :board_data
def board_data
......@@ -27,10 +21,6 @@ module EE
labels: board.labels.to_json(only: [:id, :title, :color, :text_color] ),
board_weight: board.weight,
show_promotion: show_feature_promotion,
can_update: can_update?.to_s,
can_admin_list: can_admin_list?.to_s,
can_admin_board: can_admin_board?.to_s,
disabled: board.disabled_for?(current_user).to_s,
emails_disabled: current_board_parent.emails_disabled?.to_s,
weights: ::Issue.weight_options
}
......
......@@ -147,7 +147,7 @@ RSpec.describe 'Project issue boards', :js do
it 'displays issue and max issue size' do
page.within(find(".board:nth-child(2)")) do
expect(page.find('[data-testid="board-items-count"]')).to have_text(total_development_issues)
expect(page.find('.js-max-issue-size')).to have_text(max_issue_count)
expect(page.find('.max-issue-size')).to have_text(max_issue_count)
end
end
end
......@@ -207,11 +207,11 @@ RSpec.describe 'Project issue boards', :js do
end
it "sets max issue count to zero" do
page.find('.js-remove-limit').click
click_button _('Remove limit')
wait_for_requests
expect(page.find('.js-wip-limit')).to have_text("None")
expect(page.find('[data-testid="wip-limit"]')).to have_text("None")
end
end
......@@ -235,7 +235,7 @@ RSpec.describe 'Project issue boards', :js do
click_button('List settings')
end
expect(page.find('.js-wip-limit')).to have_text(max_issue_count)
expect(page.find('[data-testid="wip-limit"]')).to have_text(max_issue_count)
end
end
......@@ -253,7 +253,7 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
expect(page.find('.js-wip-limit')).to have_text(max_issue_count)
expect(page.find('[data-testid="wip-limit"]')).to have_text(max_issue_count)
end
context "When user sets max issue count to 0" do
......@@ -270,7 +270,7 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
expect(page.find('.js-wip-limit')).to have_text("None")
expect(page.find('[data-testid="wip-limit"]')).to have_text("None")
end
end
end
......@@ -285,7 +285,7 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
expect(page.find('.js-wip-limit')).to have_text(1)
expect(page.find('[data-testid="wip-limit"]')).to have_text(1)
end
end
end
......
......@@ -20,18 +20,16 @@ RSpec.describe 'Group Boards', :js do
wait_for_requests
find(:css, '.js-delete-board button').click
click_button s_('IssueBoards|Delete board')
find(:css, '.board-config-modal .js-modal-action-primary').click
click_boards_dropdown
page.within('.js-boards-selector') do
expect(page).not_to have_content(board_dev.name)
expect(page).to have_content(board_ux.name)
end
expect(page).not_to have_content(board_dev.name)
expect(page).to have_content(board_ux.name)
end
def click_boards_dropdown
find(:css, '.js-dropdown-toggle').click
find('[data-testid="boards-dropdown"]').click
end
end
......@@ -27,10 +27,8 @@ RSpec.describe 'Multiple Issue Boards', :js do
click_button board.name
page.within('.js-boards-selector .dropdown-menu') do
expect(page).not_to have_content('Create new board')
expect(page).not_to have_content('Delete board')
end
expect(page).not_to have_content('Create new board')
expect(page).not_to have_content('Delete board')
end
it 'does not show license warning when there is one board created' do
......
......@@ -112,7 +112,7 @@ RSpec.describe 'Scoped issue boards', :js do
visit group_boards_path(group)
wait_for_requests
expect(page).to have_css('.js-boards-selector')
expect(page).to have_selector('[data-testid="boards-selector"]')
click_on_create_new_board
click_button 'Expand'
......@@ -572,12 +572,10 @@ RSpec.describe 'Scoped issue boards', :js do
it "doesn't show the input when creating a board" do
click_on_create_new_board
page.within '.js-board-config-modal' do
# To make sure the form is shown
expect(page).to have_field('board-new-name')
# To make sure the form is shown
expect(page).to have_field('board-new-name')
expect(page).not_to have_button('Expand')
end
expect(page).not_to have_button('Expand')
end
it "doesn't show the button to edit scope" do
......@@ -681,7 +679,7 @@ RSpec.describe 'Scoped issue boards', :js do
end
def click_on_create_new_board
page.within '.js-boards-selector' do
page.within '[data-testid="boards-selector"]' do
find('.dropdown-menu-toggle').click
wait_for_requests
......
......@@ -377,7 +377,7 @@ RSpec.describe 'Issue Boards', :js do
end
context 'when opening sidebars' do
let(:settings_button) { find('.js-board-settings-button') }
let(:settings_button) { find_button _('List settings') }
it 'closes card sidebar when opening settings sidebar' do
click_card(card1)
......
......@@ -363,7 +363,7 @@ RSpec.describe 'epic boards', :js do
end
def click_on_create_new_board
page.within '.js-boards-selector' do
page.within '[data-testid="boards-selector"]' do
find('.dropdown-menu-toggle').click
wait_for_requests
......
......@@ -87,7 +87,7 @@ RSpec.describe 'epic boards', :js do
wait_for_requests
dropdown_selector = '.js-boards-selector .dropdown-menu'
dropdown_selector = '[data-testid="boards-selector"] .dropdown-menu'
page.within(dropdown_selector) do
yield
end
......
import { GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { noop } from 'lodash';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import BoardSettingsWipLimit from 'ee_component/boards/components/board_settings_wip_limit.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { mockLabelList } from 'jest/boards/mock_data';
......@@ -15,9 +15,9 @@ describe('BoardSettingsWipLimit', () => {
const listId = mockLabelList.id;
const currentWipLimit = 1; // Needs to be other than null to trigger requests
const clickEdit = () => wrapper.find('.js-edit-button').vm.$emit('click');
const findRemoveWipLimit = () => wrapper.find('.js-remove-limit');
const findWipLimit = () => wrapper.find('.js-wip-limit');
const clickEdit = () => wrapper.findByTestId('edit-button').vm.$emit('click');
const findRemoveWipLimit = () => wrapper.findByTestId('remove-limit');
const findWipLimit = () => wrapper.findByTestId('wip-limit');
const findInput = () => wrapper.findComponent(GlFormInput);
const createComponent = ({
......@@ -33,7 +33,7 @@ describe('BoardSettingsWipLimit', () => {
actions: storeActions,
});
wrapper = shallowMount(BoardSettingsWipLimit, {
wrapper = shallowMountExtended(BoardSettingsWipLimit, {
propsData: props,
store,
data() {
......
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import ToggleEpicsSwimlanes from 'ee/boards/components/toggle_epics_swimlanes.vue';
Vue.use(Vuex);
describe('ToggleEpicsSwimlanes', () => {
let store;
let wrapper;
const createComponent = () => {
wrapper = mount(ToggleEpicsSwimlanes, { store });
};
afterEach(() => {
wrapper.destroy();
});
beforeEach(() => {
store = new Vuex.Store({ state: { isShowingEpicsSwimlanes: false } });
createComponent();
});
describe('dropdownLabel', () => {
it('displays "None" when isShowingEpicsSwimlanes is false', () => {
expect(wrapper.findComponent(GlDropdown).props('text')).toEqual('None');
});
it('returns "Epics" when isShowingEpicsSwimlanes is true', () => {
store = new Vuex.Store({ state: { isShowingEpicsSwimlanes: true } });
createComponent();
expect(wrapper.findComponent(GlDropdown).props('text')).toEqual('Epic');
});
});
describe('template', () => {
it('renders .board-swimlanes-toggle-wrapper container', () => {
expect(wrapper.find('[data-testid="toggle-swimlanes"]').exists()).toBe(true);
});
it('renders "Group by" label', () => {
expect(wrapper.find('[data-testid="toggle-swimlanes-label"]').text()).toEqual('Group by');
});
it('renders dropdown with 2 options', () => {
expect(wrapper.findComponent(GlDropdown).exists()).toBe(true);
expect(wrapper.findAllComponents(GlDropdownItem).length).toEqual(2);
});
});
});
import { GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import ToggleLabels from 'ee/boards/components/toggle_labels.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
Vue.use(Vuex);
describe('ToggleLabels component', () => {
let wrapper;
let setShowLabels;
function createComponent(state = {}) {
setShowLabels = jest.fn();
return shallowMount(ToggleLabels, {
store: new Vuex.Store({
state: {
isShowingLabels: true,
...state,
},
actions: {
setShowLabels,
},
}),
stubs: {
LocalStorageSync,
},
});
}
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('onStorageUpdate parses empty value as false', async () => {
wrapper = createComponent();
const localStorageSync = wrapper.findComponent(LocalStorageSync);
localStorageSync.vm.$emit('input', '');
await nextTick();
expect(setShowLabels).toHaveBeenCalledWith(expect.any(Object), false);
});
it('sets GlToggle value from store.isShowingLabels', () => {
wrapper = createComponent({ isShowingLabels: true });
expect(wrapper.findComponent(GlToggle).props('value')).toEqual(true);
wrapper = createComponent({ isShowingLabels: false });
expect(wrapper.findComponent(GlToggle).props('value')).toEqual(false);
});
});
......@@ -8,17 +8,6 @@ RSpec.describe BoardsHelper do
let_it_be_with_refind(:project) { create(:project) }
let_it_be(:project_board) { create(:board, project: project) }
describe '#board_list_data' do
let(:results) { helper.board_list_data }
it 'contains an endpoint to get users list' do
assign(:board, project_board)
assign(:project, project)
expect(results).to include(list_assignees_path: "/-/boards/#{project_board.id}/users.json")
end
end
describe '#current_board_json' do
let(:board_json) { helper.current_board_json }
let(:label1) { create(:label, name: "feijoa") }
......
......@@ -282,7 +282,7 @@ RSpec.describe 'Project issue boards', :js do
it 'shows issue count on the list' do
page.within(find(".board:nth-child(2)")) do
expect(page.find('[data-testid="board-items-count"]')).to have_text(total_planning_issues)
expect(page).not_to have_selector('.js-max-issue-size')
expect(page).not_to have_selector('.max-issue-size')
end
end
end
......
......@@ -12,6 +12,6 @@ RSpec.describe 'Issue Boards focus mode', :js do
end
it 'shows focus mode button to anonymous users' do
expect(page).to have_selector('.js-focus-mode-btn')
expect(page).to have_button _('Toggle focus mode')
end
end
......@@ -72,7 +72,7 @@ RSpec.describe 'Multi Select Issue', :js do
wait_for_requests
page.within(all('.js-board-list')[2]) do
page.within(all('.board-list')[2]) do
expect(find('.board-card:nth-child(1)')).to have_content(issue1.title)
expect(find('.board-card:nth-child(2)')).to have_content(issue2.title)
end
......@@ -87,7 +87,7 @@ RSpec.describe 'Multi Select Issue', :js do
wait_for_requests
page.within(all('.js-board-list')[2]) do
page.within(all('.board-list')[2]) do
expect(find('.board-card:nth-child(1)')).to have_content(issue1.title)
expect(find('.board-card:nth-child(2)')).to have_content(issue2.title)
expect(find('.board-card:nth-child(3)')).to have_content(issue3.title)
......@@ -102,7 +102,7 @@ RSpec.describe 'Multi Select Issue', :js do
wait_for_requests
page.within(all('.js-board-list')[1]) do
page.within(all('.board-list')[1]) do
expect(find('.board-card:nth-child(1)')).to have_content(issue1.title)
expect(find('.board-card:nth-child(2)')).to have_content(issue2.title)
expect(find('.board-card:nth-child(3)')).to have_content(issue5.title)
......
import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import Vuex from 'vuex';
......@@ -14,6 +13,7 @@ import groupRecentBoardsQuery from '~/boards/graphql/group_recent_boards.query.g
import projectRecentBoardsQuery from '~/boards/graphql/project_recent_boards.query.graphql';
import defaultStore from '~/boards/stores';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import {
mockGroupBoardResponse,
mockProjectBoardResponse,
......@@ -60,7 +60,7 @@ describe('BoardsSelector', () => {
searchBoxInput.trigger('input');
};
const getDropdownItems = () => wrapper.findAll('.js-dropdown-item');
const getDropdownItems = () => wrapper.findAllByTestId('dropdown-item');
const getDropdownHeaders = () => wrapper.findAllComponents(GlDropdownSectionHeader);
const getLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findDropdown = () => wrapper.findComponent(GlDropdown);
......@@ -100,7 +100,7 @@ describe('BoardsSelector', () => {
[groupRecentBoardsQuery, groupRecentBoardsQueryHandlerSuccess],
]);
wrapper = mount(BoardsSelector, {
wrapper = mountExtended(BoardsSelector, {
store,
apolloProvider: fakeApollo,
propsData: {
......
......@@ -5,6 +5,8 @@ import IssueTimeEstimate from '~/boards/components/issue_time_estimate.vue';
describe('Issue Time Estimate component', () => {
let wrapper;
const findIssueTimeEstimate = () => wrapper.find('[data-testid="issue-time-estimate"]');
afterEach(() => {
wrapper.destroy();
});
......@@ -26,7 +28,7 @@ describe('Issue Time Estimate component', () => {
});
it('renders expanded time estimate in tooltip', () => {
expect(wrapper.find('.js-issue-time-estimate').text()).toContain('2 weeks 3 days 1 minute');
expect(findIssueTimeEstimate().text()).toContain('2 weeks 3 days 1 minute');
});
it('prevents tooltip xss', async () => {
......@@ -42,7 +44,7 @@ describe('Issue Time Estimate component', () => {
expect(alertSpy).not.toHaveBeenCalled();
expect(wrapper.find('time').text().trim()).toEqual('0m');
expect(wrapper.find('.js-issue-time-estimate').text()).toContain('0m');
expect(findIssueTimeEstimate().text()).toContain('0m');
});
});
......@@ -63,7 +65,7 @@ describe('Issue Time Estimate component', () => {
});
it('renders expanded time estimate in tooltip', () => {
expect(wrapper.find('.js-issue-time-estimate').text()).toContain('104 hours 1 minute');
expect(findIssueTimeEstimate().text()).toContain('104 hours 1 minute');
});
});
});
......@@ -29,7 +29,7 @@ describe('IssueCount', () => {
});
it('does not contains maxIssueCount in the template', () => {
expect(vm.find('.js-max-issue-size').exists()).toBe(false);
expect(vm.find('.max-issue-size').exists()).toBe(false);
});
});
......@@ -50,7 +50,7 @@ describe('IssueCount', () => {
});
it('contains maxIssueCount in the template', () => {
expect(vm.find('.js-max-issue-size').text()).toEqual(String(maxIssueCount));
expect(vm.find('.max-issue-size').text()).toEqual(String(maxIssueCount));
});
it('does not have text-danger class when issueSize is less than maxIssueCount', () => {
......@@ -75,7 +75,7 @@ describe('IssueCount', () => {
});
it('contains maxIssueCount in the template', () => {
expect(vm.find('.js-max-issue-size').text()).toEqual(String(maxIssueCount));
expect(vm.find('.max-issue-size').text()).toEqual(String(maxIssueCount));
});
it('has text-danger class', () => {
......
......@@ -138,7 +138,7 @@ RSpec.shared_examples 'multiple issue boards' do
wait_for_requests
dropdown_selector = '.js-boards-selector .dropdown-menu'
dropdown_selector = '[data-testid="boards-selector"] .dropdown-menu'
page.within(dropdown_selector) do
yield
end
......
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