summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js')
-rw-r--r--spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js245
1 files changed, 245 insertions, 0 deletions
diff --git a/spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js b/spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js
new file mode 100644
index 00000000000..534c0baf35d
--- /dev/null
+++ b/spec/frontend/vue_merge_request_widget/components/mr_widget_rebase_spec.js
@@ -0,0 +1,245 @@
+import { mount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import WidgetRebase from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import toast from '~/vue_shared/plugins/global_toast';
+
+jest.mock('~/vue_shared/plugins/global_toast');
+
+let wrapper;
+
+function createWrapper(propsData, mergeRequestWidgetGraphql) {
+ wrapper = mount(WidgetRebase, {
+ propsData,
+ data() {
+ return {
+ state: {
+ rebaseInProgress: propsData.mr.rebaseInProgress,
+ targetBranch: propsData.mr.targetBranch,
+ userPermissions: {
+ pushToSourceBranch: propsData.mr.canPushToSourceBranch,
+ },
+ },
+ };
+ },
+ provide: { glFeatures: { mergeRequestWidgetGraphql } },
+ mocks: {
+ $apollo: {
+ queries: {
+ state: { loading: false },
+ },
+ },
+ },
+ });
+}
+
+describe('Merge request widget rebase component', () => {
+ const findRebaseMessage = () => wrapper.find('[data-testid="rebase-message"]');
+ const findRebaseMessageText = () => findRebaseMessage().text();
+ const findStandardRebaseButton = () => wrapper.find('[data-testid="standard-rebase-button"]');
+ const findRebaseWithoutCiButton = () => wrapper.find('[data-testid="rebase-without-ci-button"]');
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ [true, false].forEach((mergeRequestWidgetGraphql) => {
+ describe(`widget graphql is ${mergeRequestWidgetGraphql ? 'enabled' : 'disabled'}`, () => {
+ describe('while rebasing', () => {
+ it('should show progress message', () => {
+ createWrapper(
+ {
+ mr: { rebaseInProgress: true },
+ service: {},
+ },
+ mergeRequestWidgetGraphql,
+ );
+
+ expect(findRebaseMessageText()).toContain('Rebase in progress');
+ });
+ });
+
+ describe('with permissions', () => {
+ const rebaseMock = jest.fn().mockResolvedValue();
+ const pollMock = jest.fn().mockResolvedValue({});
+
+ it('renders the warning message', () => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
+ },
+ mergeRequestWidgetGraphql,
+ );
+
+ const text = findRebaseMessageText();
+
+ expect(text).toContain('Merge blocked');
+ expect(text.replace(/\s\s+/g, ' ')).toContain(
+ 'the source branch must be rebased onto the target branch',
+ );
+ });
+
+ it('renders an error message when rebasing has failed', async () => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
+ },
+ mergeRequestWidgetGraphql,
+ );
+
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
+ wrapper.setData({ rebasingError: 'Something went wrong!' });
+
+ await nextTick();
+ expect(findRebaseMessageText()).toContain('Something went wrong!');
+ });
+
+ describe('Rebase buttons with', () => {
+ beforeEach(() => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: true,
+ },
+ service: {
+ rebase: rebaseMock,
+ poll: pollMock,
+ },
+ },
+ mergeRequestWidgetGraphql,
+ );
+ });
+
+ it('renders both buttons', () => {
+ expect(findRebaseWithoutCiButton().exists()).toBe(true);
+ expect(findStandardRebaseButton().exists()).toBe(true);
+ });
+
+ it('starts the rebase when clicking', async () => {
+ findStandardRebaseButton().vm.$emit('click');
+
+ await nextTick();
+
+ expect(rebaseMock).toHaveBeenCalledWith({ skipCi: false });
+ });
+
+ it('starts the CI-skipping rebase when clicking on "Rebase without CI"', async () => {
+ findRebaseWithoutCiButton().vm.$emit('click');
+
+ await nextTick();
+
+ expect(rebaseMock).toHaveBeenCalledWith({ skipCi: true });
+ });
+ });
+ });
+
+ describe('without permissions', () => {
+ const exampleTargetBranch = 'fake-branch-to-test-with';
+
+ describe('UI text', () => {
+ beforeEach(() => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: false,
+ targetBranch: exampleTargetBranch,
+ },
+ service: {},
+ },
+ mergeRequestWidgetGraphql,
+ );
+ });
+
+ it('renders a message explaining user does not have permissions', () => {
+ const text = findRebaseMessageText();
+
+ expect(text).toContain(
+ 'Merge blocked: the source branch must be rebased onto the target branch.',
+ );
+ expect(text).toContain('the source branch must be rebased');
+ });
+
+ it('renders the correct target branch name', () => {
+ const elem = findRebaseMessage();
+
+ expect(elem.text()).toContain(
+ 'Merge blocked: the source branch must be rebased onto the target branch.',
+ );
+ });
+ });
+
+ it('does render the "Rebase without pipeline" button', () => {
+ createWrapper(
+ {
+ mr: {
+ rebaseInProgress: false,
+ canPushToSourceBranch: false,
+ targetBranch: exampleTargetBranch,
+ },
+ service: {},
+ },
+ mergeRequestWidgetGraphql,
+ );
+
+ expect(findRebaseWithoutCiButton().exists()).toBe(true);
+ });
+ });
+
+ describe('methods', () => {
+ it('checkRebaseStatus', async () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ createWrapper(
+ {
+ mr: {},
+ service: {
+ rebase() {
+ return Promise.resolve();
+ },
+ poll() {
+ return Promise.resolve({
+ data: {
+ rebase_in_progress: false,
+ should_be_rebased: false,
+ merge_error: null,
+ },
+ });
+ },
+ },
+ },
+ mergeRequestWidgetGraphql,
+ );
+
+ wrapper.vm.rebase();
+
+ // Wait for the rebase request
+ await nextTick();
+ // Wait for the polling request
+ await nextTick();
+ // Wait for the eventHub to be called
+ await nextTick();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetRebaseSuccess');
+ expect(toast).toHaveBeenCalledWith('Rebase completed');
+ });
+ });
+ });
+ });
+});