Skip to content
Snippets Groups Projects
Commit 6956b683 authored by Miguel Rincon's avatar Miguel Rincon
Browse files

Merge branch '413627-type-check-object' into 'master'

Fix errors happening when session expired

See merge request !137092



Merged-by: Miguel Rincon's avatarMiguel Rincon <mrincon@gitlab.com>
Approved-by: Lorenz van Herwaarden's avatarLorenz van Herwaarden <lvanherwaarden@gitlab.com>
Approved-by: Miguel Rincon's avatarMiguel Rincon <mrincon@gitlab.com>
Reviewed-by: Miguel Rincon's avatarMiguel Rincon <mrincon@gitlab.com>
Reviewed-by: Lorenz van Herwaarden's avatarLorenz van Herwaarden <lvanherwaarden@gitlab.com>
Co-authored-by: Savas Vedova's avatarSavas Vedova <svedova@gitlab.com>
parents bf4df4cc 885bc5db
No related branches found
No related tags found
1 merge request!137092Fix errors happening when session expired
Pipeline #1082819451 passed
......@@ -22,14 +22,14 @@ export default {
variables() {
return this.mergeRequestQueryVariables;
},
update: (data) => data.project.mergeRequest.userPermissions,
update: (data) => data.project?.mergeRequest.userPermissions || {},
},
state: {
query: conflictsStateQuery,
variables() {
return this.mergeRequestQueryVariables;
},
update: (data) => data.project.mergeRequest,
update: (data) => data.project?.mergeRequest || {},
},
},
props: {
......
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import Vue from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
import { removeBreakLine } from 'helpers/text_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import userPermissionsQuery from '~/vue_merge_request_widget/queries/permissions.query.graphql';
import conflictsStateQuery from '~/vue_merge_request_widget/queries/states/conflicts.query.graphql';
import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue';
Vue.use(VueApollo);
describe('MRWidgetConflicts', () => {
let wrapper;
const path = '/conflicts';
......@@ -20,34 +27,57 @@ describe('MRWidgetConflicts', () => {
const resolveConflictsBtnText = 'Resolve conflicts';
const mergeLocallyBtnText = 'Resolve locally';
async function createComponent(propsData = {}) {
wrapper = extendedWrapper(
mount(ConflictsComponent, {
propsData,
data() {
return {
const defaultApolloProvider = (mockData = {}) => {
const userData = {
data: {
project: {
id: 234,
mergeRequest: {
id: 234,
userPermissions: {
canMerge: propsData.mr.canMerge,
pushToSourceBranch: propsData.mr.canPushToSourceBranch,
},
state: {
shouldBeRebased: propsData.mr.shouldBeRebased,
sourceBranchProtected: propsData.mr.sourceBranchProtected,
canMerge: mockData.canMerge || false,
pushToSourceBranch: mockData.canPushToSourceBranch || false,
},
};
},
},
mocks: {
$apollo: {
queries: {
userPermissions: { loading: false },
stateData: { loading: false },
},
};
const mrData = {
data: {
project: {
id: 234,
mergeRequest: {
id: 234,
shouldBeRebased: mockData.shouldBeRebased || false,
sourceBranchProtected: mockData.sourceBranchProtected || false,
userPermissions: {
pushToSourceBranch: mockData.canPushToSourceBranch || false,
},
},
},
},
};
return createMockApollo([
[userPermissionsQuery, jest.fn().mockResolvedValue(userData)],
[conflictsStateQuery, jest.fn().mockResolvedValue(mrData)],
]);
};
async function createComponent({
propsData,
queryData,
apolloProvider = defaultApolloProvider(queryData),
} = {}) {
wrapper = extendedWrapper(
mount(ConflictsComponent, {
apolloProvider,
propsData,
}),
);
await nextTick();
await waitForPromises();
}
// There are two permissions we need to consider:
......@@ -62,11 +92,15 @@ describe('MRWidgetConflicts', () => {
describe('when allowed to merge but not allowed to push to source branch', () => {
beforeEach(async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictsDocsPath: '',
},
},
queryData: {
canMerge: true,
canPushToSourceBranch: false,
conflictResolutionPath: path,
conflictsDocsPath: '',
},
});
});
......@@ -89,11 +123,15 @@ describe('MRWidgetConflicts', () => {
describe('when not allowed to merge but allowed to push to source branch', () => {
beforeEach(async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictResolutionPath: path,
conflictsDocsPath: '',
},
},
queryData: {
canMerge: false,
canPushToSourceBranch: true,
conflictResolutionPath: path,
conflictsDocsPath: '',
},
});
});
......@@ -116,11 +154,15 @@ describe('MRWidgetConflicts', () => {
describe('when allowed to merge and push to source branch', () => {
beforeEach(async () => {
await createComponent({
mr: {
queryData: {
canMerge: true,
canPushToSourceBranch: true,
conflictResolutionPath: path,
conflictsDocsPath: '',
},
propsData: {
mr: {
conflictResolutionPath: path,
conflictsDocsPath: '',
},
},
});
});
......@@ -144,10 +186,14 @@ describe('MRWidgetConflicts', () => {
describe('when user does not have permission to push to source branch', () => {
it('should show proper message', async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictsDocsPath: '',
},
},
queryData: {
canMerge: false,
canPushToSourceBranch: false,
conflictsDocsPath: '',
},
});
......@@ -156,10 +202,14 @@ describe('MRWidgetConflicts', () => {
it('should not have action buttons', async () => {
await createComponent({
mr: {
queryData: {
canMerge: false,
canPushToSourceBranch: false,
conflictsDocsPath: '',
},
propsData: {
mr: {
conflictsDocsPath: '',
},
},
});
......@@ -169,10 +219,14 @@ describe('MRWidgetConflicts', () => {
it('should not have resolve button when no conflict resolution path', async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictResolutionPath: null,
conflictsDocsPath: '',
},
},
queryData: {
canMerge: true,
conflictResolutionPath: null,
conflictsDocsPath: '',
},
});
......@@ -183,9 +237,13 @@ describe('MRWidgetConflicts', () => {
describe('when fast-forward or semi-linear merge enabled', () => {
it('should tell you to rebase locally', async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictsDocsPath: '',
},
},
queryData: {
shouldBeRebased: true,
conflictsDocsPath: '',
},
});
......@@ -196,12 +254,16 @@ describe('MRWidgetConflicts', () => {
describe('when source branch protected', () => {
beforeEach(async () => {
await createComponent({
mr: {
propsData: {
mr: {
conflictResolutionPath: TEST_HOST,
conflictsDocsPath: '',
},
},
queryData: {
canMerge: true,
canPushToSourceBranch: true,
conflictResolutionPath: TEST_HOST,
sourceBranchProtected: true,
conflictsDocsPath: '',
canPushToSourceBranch: true,
},
});
});
......@@ -214,12 +276,16 @@ describe('MRWidgetConflicts', () => {
describe('when source branch not protected', () => {
beforeEach(async () => {
await createComponent({
mr: {
canMerge: true,
propsData: {
mr: {
conflictResolutionPath: TEST_HOST,
conflictsDocsPath: '',
},
},
queryData: {
canPushToSourceBranch: true,
conflictResolutionPath: TEST_HOST,
canMerge: true,
sourceBranchProtected: false,
conflictsDocsPath: '',
},
});
});
......@@ -229,4 +295,21 @@ describe('MRWidgetConflicts', () => {
expect(findResolveButton().attributes('href')).toEqual(TEST_HOST);
});
});
describe('error states', () => {
it('when project is null due to expired session it does not throw', async () => {
const fn = async () => {
await createComponent({
propsData: { mr: {} },
apolloProvider: createMockApollo([
[conflictsStateQuery, jest.fn().mockResolvedValue({ data: { project: null } })],
[userPermissionsQuery, jest.fn().mockResolvedValue({ data: { project: null } })],
]),
});
await waitForPromises();
};
await expect(fn()).resolves.not.toThrow();
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment