diff options
Diffstat (limited to 'spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js')
-rw-r--r-- | spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js | 209 |
1 files changed, 172 insertions, 37 deletions
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js index d3221cc2fc7..27604868b3e 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js @@ -2,10 +2,15 @@ import { shallowMount } 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 ActionsButton from '~/vue_shared/components/actions_button.vue'; +import { + REBASE_BUTTON_KEY, + REBASE_WITHOUT_CI_BUTTON_KEY, +} from '~/vue_merge_request_widget/constants'; let wrapper; -function factory(propsData, mergeRequestWidgetGraphql) { +function createWrapper(propsData, mergeRequestWidgetGraphql, rebaseWithoutCiUi) { wrapper = shallowMount(WidgetRebase, { propsData, data() { @@ -19,7 +24,7 @@ function factory(propsData, mergeRequestWidgetGraphql) { }, }; }, - provide: { glFeatures: { mergeRequestWidgetGraphql } }, + provide: { glFeatures: { mergeRequestWidgetGraphql, rebaseWithoutCiUi } }, mocks: { $apollo: { queries: { @@ -31,8 +36,10 @@ function factory(propsData, mergeRequestWidgetGraphql) { } describe('Merge request widget rebase component', () => { - const findRebaseMessageEl = () => wrapper.find('[data-testid="rebase-message"]'); - const findRebaseMessageElText = () => findRebaseMessageEl().text(); + const findRebaseMessage = () => wrapper.find('[data-testid="rebase-message"]'); + const findRebaseMessageText = () => findRebaseMessage().text(); + const findRebaseButtonActions = () => wrapper.find(ActionsButton); + const findStandardRebaseButton = () => wrapper.find('[data-testid="standard-rebase-button"]'); afterEach(() => { wrapper.destroy(); @@ -40,10 +47,10 @@ describe('Merge request widget rebase component', () => { }); [true, false].forEach((mergeRequestWidgetGraphql) => { - describe(`widget graphql is ${mergeRequestWidgetGraphql ? 'enabled' : 'dislabed'}`, () => { - describe('While rebasing', () => { + describe(`widget graphql is ${mergeRequestWidgetGraphql ? 'enabled' : 'disabled'}`, () => { + describe('while rebasing', () => { it('should show progress message', () => { - factory( + createWrapper( { mr: { rebaseInProgress: true }, service: {}, @@ -51,24 +58,30 @@ describe('Merge request widget rebase component', () => { mergeRequestWidgetGraphql, ); - expect(findRebaseMessageElText()).toContain('Rebase in progress'); + expect(findRebaseMessageText()).toContain('Rebase in progress'); }); }); - describe('With permissions', () => { - it('it should render rebase button and warning message', () => { - factory( + 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: {}, + service: { + rebase: rebaseMock, + poll: pollMock, + }, }, mergeRequestWidgetGraphql, ); - const text = findRebaseMessageElText(); + const text = findRebaseMessageText(); expect(text).toContain('Merge blocked'); expect(text.replace(/\s\s+/g, ' ')).toContain( @@ -76,73 +89,195 @@ describe('Merge request widget rebase component', () => { ); }); - it('it should render error message when it fails', async () => { - factory( + it('renders an error message when rebasing has failed', async () => { + createWrapper( { mr: { rebaseInProgress: false, canPushToSourceBranch: true, }, - service: {}, + 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(findRebaseMessageElText()).toContain('Something went wrong!'); + expect(findRebaseMessageText()).toContain('Something went wrong!'); + }); + + describe('Rebase button with flag rebaseWithoutCiUi', () => { + beforeEach(() => { + createWrapper( + { + mr: { + rebaseInProgress: false, + canPushToSourceBranch: true, + }, + service: { + rebase: rebaseMock, + poll: pollMock, + }, + }, + mergeRequestWidgetGraphql, + { rebaseWithoutCiUi: true }, + ); + }); + + it('rebase button with actions is rendered', () => { + expect(findRebaseButtonActions().exists()).toBe(true); + expect(findStandardRebaseButton().exists()).toBe(false); + }); + + it('has rebase and rebase without CI actions', () => { + const actionNames = findRebaseButtonActions() + .props('actions') + .map((action) => action.key); + + expect(actionNames).toStrictEqual([REBASE_BUTTON_KEY, REBASE_WITHOUT_CI_BUTTON_KEY]); + }); + + it('defaults to rebase action', () => { + expect(findRebaseButtonActions().props('selectedKey')).toStrictEqual(REBASE_BUTTON_KEY); + }); + + it('starts the rebase when clicking', async () => { + // ActionButtons use the actions props instead of emitting + // a click event, therefore simulating the behavior here: + findRebaseButtonActions() + .props('actions') + .find((x) => x.key === REBASE_BUTTON_KEY) + .handle(); + + await nextTick(); + + expect(rebaseMock).toHaveBeenCalledWith({ skipCi: false }); + }); + + it('starts the CI-skipping rebase when clicking on "Rebase without CI"', async () => { + // ActionButtons use the actions props instead of emitting + // a click event, therefore simulating the behavior here: + findRebaseButtonActions() + .props('actions') + .find((x) => x.key === REBASE_WITHOUT_CI_BUTTON_KEY) + .handle(); + + await nextTick(); + + expect(rebaseMock).toHaveBeenCalledWith({ skipCi: true }); + }); + }); + + describe('Rebase button with rebaseWithoutCiUI flag disabled', () => { + beforeEach(() => { + createWrapper( + { + mr: { + rebaseInProgress: false, + canPushToSourceBranch: true, + }, + service: { + rebase: rebaseMock, + poll: pollMock, + }, + }, + mergeRequestWidgetGraphql, + ); + }); + + it('standard rebase button is rendered', () => { + expect(findStandardRebaseButton().exists()).toBe(true); + expect(findRebaseButtonActions().exists()).toBe(false); + }); + + it('calls rebase method with skip_ci false', () => { + findStandardRebaseButton().vm.$emit('click'); + + expect(rebaseMock).toHaveBeenCalledWith({ skipCi: false }); + }); }); }); - describe('Without permissions', () => { - it('should render a message explaining user does not have permissions', () => { - factory( + 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 not render the rebase actions button with rebaseWithoutCiUI flag enabled', () => { + createWrapper( { mr: { rebaseInProgress: false, canPushToSourceBranch: false, - targetBranch: 'foo', + targetBranch: exampleTargetBranch, }, service: {}, }, mergeRequestWidgetGraphql, + { rebaseWithoutCiUi: true }, ); - const text = findRebaseMessageElText(); - - expect(text).toContain( - 'Merge blocked: the source branch must be rebased onto the target branch.', - ); - expect(text).toContain('the source branch must be rebased'); + expect(findRebaseButtonActions().exists()).toBe(false); }); - it('should render the correct target branch name', () => { - const targetBranch = 'fake-branch-to-test-with'; - factory( + it('does not render the standard rebase button with rebaseWithoutCiUI flag disabled', () => { + createWrapper( { mr: { rebaseInProgress: false, canPushToSourceBranch: false, - targetBranch, + targetBranch: exampleTargetBranch, }, service: {}, }, mergeRequestWidgetGraphql, ); - const elem = findRebaseMessageEl(); - - expect(elem.text()).toContain( - `Merge blocked: the source branch must be rebased onto the target branch.`, - ); + expect(findStandardRebaseButton().exists()).toBe(false); }); }); describe('methods', () => { it('checkRebaseStatus', async () => { jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - factory( + createWrapper( { mr: {}, service: { |