Commit 02f0298c authored by Phil Hughes's avatar Phil Hughes

Fixes award emoji not working with relative root URL

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/332010
parent 7535be32
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { normalizeHeaders } from '~/lib/utils/common_utils'; import { normalizeHeaders } from '~/lib/utils/common_utils';
import { joinPaths } from '~/lib/utils/url_utility';
import { __ } from '~/locale'; import { __ } from '~/locale';
import showToast from '~/vue_shared/plugins/global_toast'; import showToast from '~/vue_shared/plugins/global_toast';
import { import {
...@@ -16,7 +17,9 @@ export const fetchAwards = async ({ commit, dispatch, state }, page = '1') => { ...@@ -16,7 +17,9 @@ export const fetchAwards = async ({ commit, dispatch, state }, page = '1') => {
if (!window.gon?.current_user_id) return; if (!window.gon?.current_user_id) return;
try { try {
const { data, headers } = await axios.get(state.path, { params: { per_page: 100, page } }); const { data, headers } = await axios.get(joinPaths(gon.relative_url_root || '', state.path), {
params: { per_page: 100, page },
});
const normalizedHeaders = normalizeHeaders(headers); const normalizedHeaders = normalizeHeaders(headers);
const nextPage = normalizedHeaders['X-NEXT-PAGE']; const nextPage = normalizedHeaders['X-NEXT-PAGE'];
...@@ -35,13 +38,15 @@ export const toggleAward = async ({ commit, state }, name) => { ...@@ -35,13 +38,15 @@ export const toggleAward = async ({ commit, state }, name) => {
try { try {
if (award) { if (award) {
await axios.delete(`${state.path}/${award.id}`); await axios.delete(joinPaths(gon.relative_url_root || '', `${state.path}/${award.id}`));
commit(REMOVE_AWARD, award.id); commit(REMOVE_AWARD, award.id);
showToast(__('Award removed')); showToast(__('Award removed'));
} else { } else {
const { data } = await axios.post(state.path, { name }); const { data } = await axios.post(joinPaths(gon.relative_url_root || '', state.path), {
name,
});
commit(ADD_NEW_AWARD, data); commit(ADD_NEW_AWARD, data);
......
...@@ -35,27 +35,36 @@ describe('Awards app actions', () => { ...@@ -35,27 +35,36 @@ describe('Awards app actions', () => {
}); });
describe('success', () => { describe('success', () => {
beforeEach(() => { describe.each`
mock relativeRootUrl
.onGet('/awards', { params: { per_page: 100, page: '1' } }) ${null}
.reply(200, ['thumbsup'], { 'x-next-page': '2' }); ${'/gitlab'}
mock.onGet('/awards', { params: { per_page: 100, page: '2' } }).reply(200, ['thumbsdown']); `('with relative_root_url as $relativeRootUrl', ({ relativeRootUrl }) => {
}); beforeEach(() => {
window.gon = { relative_url_root: relativeRootUrl };
mock
.onGet(`${relativeRootUrl || ''}/awards`, { params: { per_page: 100, page: '1' } })
.reply(200, ['thumbsup'], { 'x-next-page': '2' });
mock
.onGet(`${relativeRootUrl || ''}/awards`, { params: { per_page: 100, page: '2' } })
.reply(200, ['thumbsdown']);
});
it('commits FETCH_AWARDS_SUCCESS', async () => { it('commits FETCH_AWARDS_SUCCESS', async () => {
window.gon = { current_user_id: 1 }; window.gon.current_user_id = 1;
await testAction( await testAction(
actions.fetchAwards, actions.fetchAwards,
'1', '1',
{ path: '/awards' }, { path: '/awards' },
[{ type: 'FETCH_AWARDS_SUCCESS', payload: ['thumbsup'] }], [{ type: 'FETCH_AWARDS_SUCCESS', payload: ['thumbsup'] }],
[{ type: 'fetchAwards', payload: '2' }], [{ type: 'fetchAwards', payload: '2' }],
); );
}); });
it('does not commit FETCH_AWARDS_SUCCESS when user signed out', async () => { it('does not commit FETCH_AWARDS_SUCCESS when user signed out', async () => {
await testAction(actions.fetchAwards, '1', { path: '/awards' }, [], []); await testAction(actions.fetchAwards, '1', { path: '/awards' }, [], []);
});
}); });
}); });
...@@ -85,81 +94,91 @@ describe('Awards app actions', () => { ...@@ -85,81 +94,91 @@ describe('Awards app actions', () => {
mock.restore(); mock.restore();
}); });
describe('adding new award', () => { describe.each`
describe('success', () => { relativeRootUrl
beforeEach(() => { ${null}
mock.onPost('/awards').reply(200, { id: 1 }); ${'/gitlab'}
}); `('with relative_root_url as $relativeRootUrl', ({ relativeRootUrl }) => {
beforeEach(() => {
it('commits ADD_NEW_AWARD', async () => { window.gon = { relative_url_root: relativeRootUrl };
testAction(actions.toggleAward, null, { path: '/awards', awards: [] }, [
{ type: 'ADD_NEW_AWARD', payload: { id: 1 } },
]);
});
});
describe('error', () => {
beforeEach(() => {
mock.onPost('/awards').reply(500);
});
it('calls Sentry.captureException', async () => {
await testAction(
actions.toggleAward,
null,
{ path: '/awards', awards: [] },
[],
[],
() => {
expect(Sentry.captureException).toHaveBeenCalled();
},
);
});
}); });
});
describe('removing a award', () => {
const mockData = { id: 1, name: 'thumbsup', user: { id: 1 } };
describe('success', () => { describe('adding new award', () => {
beforeEach(() => { describe('success', () => {
mock.onDelete('/awards/1').reply(200); beforeEach(() => {
mock.onPost(`${relativeRootUrl || ''}/awards`).reply(200, { id: 1 });
});
it('commits ADD_NEW_AWARD', async () => {
testAction(actions.toggleAward, null, { path: '/awards', awards: [] }, [
{ type: 'ADD_NEW_AWARD', payload: { id: 1 } },
]);
});
}); });
it('commits REMOVE_AWARD', async () => { describe('error', () => {
testAction( beforeEach(() => {
actions.toggleAward, mock.onPost(`${relativeRootUrl || ''}/awards`).reply(500);
'thumbsup', });
{
path: '/awards', it('calls Sentry.captureException', async () => {
currentUserId: 1, await testAction(
awards: [mockData], actions.toggleAward,
}, null,
[{ type: 'REMOVE_AWARD', payload: 1 }], { path: '/awards', awards: [] },
); [],
[],
() => {
expect(Sentry.captureException).toHaveBeenCalled();
},
);
});
}); });
}); });
describe('error', () => { describe('removing a award', () => {
beforeEach(() => { const mockData = { id: 1, name: 'thumbsup', user: { id: 1 } };
mock.onDelete('/awards/1').reply(500);
describe('success', () => {
beforeEach(() => {
mock.onDelete(`${relativeRootUrl || ''}/awards/1`).reply(200);
});
it('commits REMOVE_AWARD', async () => {
testAction(
actions.toggleAward,
'thumbsup',
{
path: '/awards',
currentUserId: 1,
awards: [mockData],
},
[{ type: 'REMOVE_AWARD', payload: 1 }],
);
});
}); });
it('calls Sentry.captureException', async () => { describe('error', () => {
await testAction( beforeEach(() => {
actions.toggleAward, mock.onDelete(`${relativeRootUrl || ''}/awards/1`).reply(500);
'thumbsup', });
{
path: '/awards', it('calls Sentry.captureException', async () => {
currentUserId: 1, await testAction(
awards: [mockData], actions.toggleAward,
}, 'thumbsup',
[], {
[], path: '/awards',
() => { currentUserId: 1,
expect(Sentry.captureException).toHaveBeenCalled(); awards: [mockData],
}, },
); [],
[],
() => {
expect(Sentry.captureException).toHaveBeenCalled();
},
);
});
}); });
}); });
}); });
......
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