Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-07 12:12:12 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-07 12:12:12 +0300
commitb9bc4d88ea6b998e2cede0da904f36daa2c18007 (patch)
tree46a3d43aa85d18f1fe27cfccdad9e7cf53fda14f /spec
parent913224e81c5ee474f2d61962fed3c7e42b71c3f9 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/groups/show_spec.rb2
-rw-r--r--spec/features/projects/user_sorts_projects_spec.rb4
-rw-r--r--spec/frontend/groups/components/app_spec.js10
-rw-r--r--spec/frontend/groups/components/overview_tabs_spec.js106
-rw-r--r--spec/frontend/issuable/issuable_form_spec.js199
-rw-r--r--spec/helpers/groups_helper_spec.rb23
-rw-r--r--spec/workers/concerns/application_worker_spec.rb2
7 files changed, 265 insertions, 81 deletions
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index d814906a274..67310862516 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -331,6 +331,7 @@ RSpec.describe 'Group show page' do
end
it 'does not include structured markup in shared projects tab', :aggregate_failures, :js do
+ stub_feature_flags(group_overview_tabs_vue: false)
other_project = create(:project, :public)
other_project.project_group_links.create!(group: group)
@@ -342,6 +343,7 @@ RSpec.describe 'Group show page' do
end
it 'does not include structured markup in archived projects tab', :aggregate_failures, :js do
+ stub_feature_flags(group_overview_tabs_vue: false)
project.update!(archived: true)
visit group_archived_path(group)
diff --git a/spec/features/projects/user_sorts_projects_spec.rb b/spec/features/projects/user_sorts_projects_spec.rb
index 7c970f7ee3d..b9b28398279 100644
--- a/spec/features/projects/user_sorts_projects_spec.rb
+++ b/spec/features/projects/user_sorts_projects_spec.rb
@@ -24,6 +24,7 @@ RSpec.describe 'User sorts projects and order persists' do
end
it "is set on the group_canonical_path" do
+ stub_feature_flags(group_overview_tabs_vue: false)
visit(group_canonical_path(group))
within '[data-testid=group_sort_by_dropdown]' do
@@ -32,6 +33,7 @@ RSpec.describe 'User sorts projects and order persists' do
end
it "is set on the details_group_path" do
+ stub_feature_flags(group_overview_tabs_vue: false)
visit(details_group_path(group))
within '[data-testid=group_sort_by_dropdown]' do
@@ -64,6 +66,7 @@ RSpec.describe 'User sorts projects and order persists' do
context 'from group homepage', :js do
before do
+ stub_feature_flags(group_overview_tabs_vue: false)
sign_in(user)
visit(group_canonical_path(group))
within '[data-testid=group_sort_by_dropdown]' do
@@ -77,6 +80,7 @@ RSpec.describe 'User sorts projects and order persists' do
context 'from group details', :js do
before do
+ stub_feature_flags(group_overview_tabs_vue: false)
sign_in(user)
visit(details_group_path(group))
within '[data-testid=group_sort_by_dropdown]' do
diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js
index 2796a561953..a4a7530184d 100644
--- a/spec/frontend/groups/components/app_spec.js
+++ b/spec/frontend/groups/components/app_spec.js
@@ -40,7 +40,7 @@ describe('AppComponent', () => {
const store = new GroupsStore({ hideProjects: false });
const service = new GroupsService(mockEndpoint);
- const createShallowComponent = ({ propsData = {}, provide = {} } = {}) => {
+ const createShallowComponent = ({ propsData = {} } = {}) => {
store.state.pageInfo = mockPageInfo;
wrapper = shallowMount(appComponent, {
propsData: {
@@ -53,10 +53,6 @@ describe('AppComponent', () => {
mocks: {
$toast,
},
- provide: {
- renderEmptyState: false,
- ...provide,
- },
});
vm = wrapper.vm;
};
@@ -402,8 +398,7 @@ describe('AppComponent', () => {
({ action, groups, fromSearch, renderEmptyState, expected }) => {
it(expected ? 'renders empty state' : 'does not render empty state', async () => {
createShallowComponent({
- propsData: { action },
- provide: { renderEmptyState },
+ propsData: { action, renderEmptyState },
});
vm.updateGroups(groups, fromSearch);
@@ -420,7 +415,6 @@ describe('AppComponent', () => {
it('renders legacy empty state', async () => {
createShallowComponent({
propsData: { action: 'subgroups_and_projects' },
- provide: { renderEmptyState: false },
});
vm.updateGroups([], false);
diff --git a/spec/frontend/groups/components/overview_tabs_spec.js b/spec/frontend/groups/components/overview_tabs_spec.js
new file mode 100644
index 00000000000..c26254acf3d
--- /dev/null
+++ b/spec/frontend/groups/components/overview_tabs_spec.js
@@ -0,0 +1,106 @@
+import { GlTab } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import OverviewTabs from '~/groups/components/overview_tabs.vue';
+import GroupsApp from '~/groups/components/app.vue';
+import GroupsStore from '~/groups/store/groups_store';
+import GroupsService from '~/groups/service/groups_service';
+import {
+ ACTIVE_TAB_SUBGROUPS_AND_PROJECTS,
+ ACTIVE_TAB_SHARED,
+ ACTIVE_TAB_ARCHIVED,
+} from '~/groups/constants';
+import axios from '~/lib/utils/axios_utils';
+
+describe('OverviewTabs', () => {
+ let wrapper;
+
+ const endpoints = {
+ subgroups_and_projects: '/groups/foobar/-/children.json',
+ shared: '/groups/foobar/-/shared_projects.json',
+ archived: '/groups/foobar/-/children.json?archived=only',
+ };
+
+ const createComponent = async () => {
+ wrapper = mountExtended(OverviewTabs, {
+ provide: {
+ endpoints,
+ },
+ });
+
+ await nextTick();
+ };
+
+ const findTabPanels = () => wrapper.findAllComponents(GlTab);
+ const findTab = (name) => wrapper.findByRole('tab', { name });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ beforeEach(async () => {
+ // eslint-disable-next-line no-new
+ new AxiosMockAdapter(axios);
+
+ await createComponent();
+ });
+
+ it('renders `Subgroups and projects` tab with `GroupsApp` component', async () => {
+ const tabPanel = findTabPanels().at(0);
+
+ expect(tabPanel.vm.$attrs).toMatchObject({
+ title: OverviewTabs.i18n.subgroupsAndProjects,
+ lazy: false,
+ });
+ expect(tabPanel.findComponent(GroupsApp).props()).toMatchObject({
+ action: ACTIVE_TAB_SUBGROUPS_AND_PROJECTS,
+ store: new GroupsStore({ showSchemaMarkup: true }),
+ service: new GroupsService(endpoints[ACTIVE_TAB_SUBGROUPS_AND_PROJECTS]),
+ hideProjects: false,
+ renderEmptyState: true,
+ });
+ });
+
+ it('renders `Shared projects` tab and renders `GroupsApp` component after clicking tab', async () => {
+ const tabPanel = findTabPanels().at(1);
+
+ expect(tabPanel.vm.$attrs).toMatchObject({
+ title: OverviewTabs.i18n.sharedProjects,
+ lazy: true,
+ });
+
+ await findTab(OverviewTabs.i18n.sharedProjects).trigger('click');
+
+ expect(tabPanel.findComponent(GroupsApp).props()).toMatchObject({
+ action: ACTIVE_TAB_SHARED,
+ store: new GroupsStore(),
+ service: new GroupsService(endpoints[ACTIVE_TAB_SHARED]),
+ hideProjects: false,
+ renderEmptyState: false,
+ });
+
+ expect(tabPanel.vm.$attrs.lazy).toBe(false);
+ });
+
+ it('renders `Archived projects` tab and renders `GroupsApp` component after clicking tab', async () => {
+ const tabPanel = findTabPanels().at(2);
+
+ expect(tabPanel.vm.$attrs).toMatchObject({
+ title: OverviewTabs.i18n.archivedProjects,
+ lazy: true,
+ });
+
+ await findTab(OverviewTabs.i18n.archivedProjects).trigger('click');
+
+ expect(tabPanel.findComponent(GroupsApp).props()).toMatchObject({
+ action: ACTIVE_TAB_ARCHIVED,
+ store: new GroupsStore(),
+ service: new GroupsService(endpoints[ACTIVE_TAB_ARCHIVED]),
+ hideProjects: false,
+ renderEmptyState: false,
+ });
+
+ expect(tabPanel.vm.$attrs.lazy).toBe(false);
+ });
+});
diff --git a/spec/frontend/issuable/issuable_form_spec.js b/spec/frontend/issuable/issuable_form_spec.js
index d844f3394d5..f37d132743a 100644
--- a/spec/frontend/issuable/issuable_form_spec.js
+++ b/spec/frontend/issuable/issuable_form_spec.js
@@ -1,111 +1,168 @@
import $ from 'jquery';
+import Autosave from '~/autosave';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import IssuableForm from '~/issuable/issuable_form';
import setWindowLocation from 'helpers/set_window_location_helper';
+jest.mock('~/autosave');
+
+const createIssuable = (form) => {
+ return new IssuableForm(form);
+};
+
describe('IssuableForm', () => {
+ let $form;
let instance;
- const createIssuable = (form) => {
- instance = new IssuableForm(form);
- };
-
beforeEach(() => {
setHTMLFixture(`
<form>
<input name="[title]" />
+ <textarea name="[description]"></textarea>
</form>
`);
- createIssuable($('form'));
+ $form = $('form');
});
afterEach(() => {
resetHTMLFixture();
+ $form = null;
+ instance = null;
});
- describe('initAutosave', () => {
- it('creates autosave with the searchTerm included', () => {
- setWindowLocation('https://gitlab.test/foo?bar=true');
- const autosave = instance.initAutosave();
+ describe('autosave', () => {
+ let $title;
+ let $description;
+
+ beforeEach(() => {
+ $title = $form.find('input[name*="[title]"]');
+ $description = $form.find('textarea[name*="[description]"]');
+ });
+
+ afterEach(() => {
+ $title = null;
+ $description = null;
+ });
- expect(autosave.key.includes('bar=true')).toBe(true);
+ describe('initAutosave', () => {
+ it('calls initAutosave', () => {
+ const initAutosave = jest.spyOn(IssuableForm.prototype, 'initAutosave');
+ createIssuable($form);
+
+ expect(initAutosave).toHaveBeenCalledTimes(1);
+ });
+
+ it('creates autosave with the searchTerm included', () => {
+ setWindowLocation('https://gitlab.test/foo?bar=true');
+ createIssuable($form);
+
+ expect(Autosave).toHaveBeenCalledWith(
+ $title,
+ ['/foo', 'bar=true', 'title'],
+ 'autosave//foo/bar=true=title',
+ );
+ expect(Autosave).toHaveBeenCalledWith(
+ $description,
+ ['/foo', 'bar=true', 'description'],
+ 'autosave//foo/bar=true=description',
+ );
+ });
+
+ it("creates autosave fields without the searchTerm if it's an issue new form", () => {
+ setWindowLocation('https://gitlab.test/issues/new?bar=true');
+ $form.attr('data-new-issue-path', '/issues/new');
+ createIssuable($form);
+
+ expect(Autosave).toHaveBeenCalledWith(
+ $title,
+ ['/issues/new', '', 'title'],
+ 'autosave//issues/new/bar=true=title',
+ );
+ expect(Autosave).toHaveBeenCalledWith(
+ $description,
+ ['/issues/new', '', 'description'],
+ 'autosave//issues/new/bar=true=description',
+ );
+ });
});
- it("creates autosave fields without the searchTerm if it's an issue new form", () => {
- setHTMLFixture(`
- <form data-new-issue-path="/issues/new">
- <input name="[title]" />
- </form>
- `);
- createIssuable($('form'));
+ describe('resetAutosave', () => {
+ it('calls reset on title and description', () => {
+ instance = createIssuable($form);
+
+ instance.resetAutosave();
- setWindowLocation('https://gitlab.test/issues/new?bar=true');
+ expect(instance.autosaveTitle.reset).toHaveBeenCalledTimes(1);
+ expect(instance.autosaveDescription.reset).toHaveBeenCalledTimes(1);
+ });
- const autosave = instance.initAutosave();
+ it('resets autosave when submit', () => {
+ const resetAutosave = jest.spyOn(IssuableForm.prototype, 'resetAutosave');
+ createIssuable($form);
- expect(autosave.key.includes('bar=true')).toBe(false);
+ $form.submit();
+
+ expect(resetAutosave).toHaveBeenCalledTimes(1);
+ });
+
+ it('resets autosave on elements with the .js-reset-autosave class', () => {
+ const resetAutosave = jest.spyOn(IssuableForm.prototype, 'resetAutosave');
+ $form.append('<a class="js-reset-autosave">Cancel</a>');
+ createIssuable($form);
+
+ $form.find('.js-reset-autosave').trigger('click');
+
+ expect(resetAutosave).toHaveBeenCalledTimes(1);
+ });
});
});
- describe('resetAutosave', () => {
- it('resets autosave on elements with the .js-reset-autosave class', () => {
- setHTMLFixture(`
- <form>
- <input name="[title]" />
- <textarea name="[description]"></textarea>
- <a class="js-reset-autosave">Cancel</a>
- </form>
- `);
- const $form = $('form');
- const resetAutosave = jest.spyOn(IssuableForm.prototype, 'resetAutosave');
- createIssuable($form);
-
- $form.find('.js-reset-autosave').trigger('click');
-
- expect(resetAutosave).toHaveBeenCalled();
+ describe('wip', () => {
+ beforeEach(() => {
+ instance = createIssuable($form);
});
- });
- describe('removeWip', () => {
- it.each`
- prefix
- ${'draFT: '}
- ${' [DRaft] '}
- ${'drAft:'}
- ${'[draFT]'}
- ${'(draft) '}
- ${' (DrafT)'}
- ${'draft: [draft] (draft)'}
- `('removes "$prefix" from the beginning of the title', ({ prefix }) => {
- instance.titleField.val(`${prefix}The Issuable's Title Value`);
-
- instance.removeWip();
-
- expect(instance.titleField.val()).toBe("The Issuable's Title Value");
+ describe('removeWip', () => {
+ it.each`
+ prefix
+ ${'draFT: '}
+ ${' [DRaft] '}
+ ${'drAft:'}
+ ${'[draFT]'}
+ ${'(draft) '}
+ ${' (DrafT)'}
+ ${'draft: [draft] (draft)'}
+ `('removes "$prefix" from the beginning of the title', ({ prefix }) => {
+ instance.titleField.val(`${prefix}The Issuable's Title Value`);
+
+ instance.removeWip();
+
+ expect(instance.titleField.val()).toBe("The Issuable's Title Value");
+ });
});
- });
- describe('addWip', () => {
- it("properly adds the work in progress prefix to the Issuable's title", () => {
- instance.titleField.val("The Issuable's Title Value");
+ describe('addWip', () => {
+ it("properly adds the work in progress prefix to the Issuable's title", () => {
+ instance.titleField.val("The Issuable's Title Value");
- instance.addWip();
+ instance.addWip();
- expect(instance.titleField.val()).toBe("Draft: The Issuable's Title Value");
+ expect(instance.titleField.val()).toBe("Draft: The Issuable's Title Value");
+ });
});
- });
- describe('workInProgress', () => {
- it.each`
- title | expected
- ${'draFT: something is happening'} | ${true}
- ${'draft something is happening'} | ${false}
- ${'something is happening to drafts'} | ${false}
- ${'something is happening'} | ${false}
- `('returns $expected with "$title"', ({ title, expected }) => {
- instance.titleField.val(title);
-
- expect(instance.workInProgress()).toBe(expected);
+ describe('workInProgress', () => {
+ it.each`
+ title | expected
+ ${'draFT: something is happening'} | ${true}
+ ${'draft something is happening'} | ${false}
+ ${'something is happening to drafts'} | ${false}
+ ${'something is happening'} | ${false}
+ `('returns $expected with "$title"', ({ title, expected }) => {
+ instance.titleField.val(title);
+
+ expect(instance.workInProgress()).toBe(expected);
+ });
});
});
});
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 2c1061d2f1b..00e620832b3 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -520,6 +520,29 @@ RSpec.describe GroupsHelper do
end
end
+ describe '#group_overview_tabs_app_data' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+
+ allow(helper).to receive(:can?).with(user, :create_subgroup, group) { true }
+ allow(helper).to receive(:can?).with(user, :create_projects, group) { true }
+ end
+
+ it 'returns expected hash' do
+ expect(helper.group_overview_tabs_app_data(group)).to match(
+ {
+ subgroups_and_projects_endpoint: including("/groups/#{group.path}/-/children.json"),
+ shared_projects_endpoint: including("/groups/#{group.path}/-/shared_projects.json"),
+ archived_projects_endpoint: including("/groups/#{group.path}/-/children.json?archived=only"),
+ current_group_visibility: group.visibility
+ }.merge(helper.group_overview_tabs_app_data(group))
+ )
+ end
+ end
+
describe "#enabled_git_access_protocol_options_for_group" do
subject { helper.enabled_git_access_protocol_options_for_group }
diff --git a/spec/workers/concerns/application_worker_spec.rb b/spec/workers/concerns/application_worker_spec.rb
index 707fa0c9c78..5fde54b98f0 100644
--- a/spec/workers/concerns/application_worker_spec.rb
+++ b/spec/workers/concerns/application_worker_spec.rb
@@ -289,7 +289,6 @@ RSpec.describe ApplicationWorker do
perform_action
expect(worker.jobs.count).to eq args.count
- expect(worker.jobs).to all(include('enqueued_at'))
end
end
@@ -302,7 +301,6 @@ RSpec.describe ApplicationWorker do
perform_action
expect(worker.jobs.count).to eq args.count
- expect(worker.jobs).to all(include('enqueued_at'))
end
end