Commit fa29bc28 authored by Winnie Hellmann's avatar Winnie Hellmann Committed by Mike Greiling

Fix branch name encoding for dropdown on issue page

parent adb06988
...@@ -66,8 +66,14 @@ export default class CreateMergeRequestDropdown { ...@@ -66,8 +66,14 @@ export default class CreateMergeRequestDropdown {
} }
bindEvents() { bindEvents() {
this.createMergeRequestButton.addEventListener('click', this.onClickCreateMergeRequestButton.bind(this)); this.createMergeRequestButton.addEventListener(
this.createTargetButton.addEventListener('click', this.onClickCreateMergeRequestButton.bind(this)); 'click',
this.onClickCreateMergeRequestButton.bind(this),
);
this.createTargetButton.addEventListener(
'click',
this.onClickCreateMergeRequestButton.bind(this),
);
this.branchInput.addEventListener('keyup', this.onChangeInput.bind(this)); this.branchInput.addEventListener('keyup', this.onChangeInput.bind(this));
this.dropdownToggle.addEventListener('click', this.onClickSetFocusOnBranchNameInput.bind(this)); this.dropdownToggle.addEventListener('click', this.onClickSetFocusOnBranchNameInput.bind(this));
this.refInput.addEventListener('keyup', this.onChangeInput.bind(this)); this.refInput.addEventListener('keyup', this.onChangeInput.bind(this));
...@@ -77,7 +83,8 @@ export default class CreateMergeRequestDropdown { ...@@ -77,7 +83,8 @@ export default class CreateMergeRequestDropdown {
checkAbilityToCreateBranch() { checkAbilityToCreateBranch() {
this.setUnavailableButtonState(); this.setUnavailableButtonState();
axios.get(this.canCreatePath) axios
.get(this.canCreatePath)
.then(({ data }) => { .then(({ data }) => {
this.setUnavailableButtonState(false); this.setUnavailableButtonState(false);
...@@ -105,7 +112,8 @@ export default class CreateMergeRequestDropdown { ...@@ -105,7 +112,8 @@ export default class CreateMergeRequestDropdown {
createBranch() { createBranch() {
this.isCreatingBranch = true; this.isCreatingBranch = true;
return axios.post(this.createBranchPath) return axios
.post(this.createBranchPath)
.then(({ data }) => { .then(({ data }) => {
this.branchCreated = true; this.branchCreated = true;
window.location.href = data.url; window.location.href = data.url;
...@@ -116,7 +124,8 @@ export default class CreateMergeRequestDropdown { ...@@ -116,7 +124,8 @@ export default class CreateMergeRequestDropdown {
createMergeRequest() { createMergeRequest() {
this.isCreatingMergeRequest = true; this.isCreatingMergeRequest = true;
return axios.post(this.createMrPath) return axios
.post(this.createMrPath)
.then(({ data }) => { .then(({ data }) => {
this.mergeRequestCreated = true; this.mergeRequestCreated = true;
window.location.href = data.url; window.location.href = data.url;
...@@ -195,7 +204,8 @@ export default class CreateMergeRequestDropdown { ...@@ -195,7 +204,8 @@ export default class CreateMergeRequestDropdown {
getRef(ref, target = 'all') { getRef(ref, target = 'all') {
if (!ref) return false; if (!ref) return false;
return axios.get(this.refsPath + ref) return axios
.get(`${this.refsPath}${encodeURIComponent(ref)}`)
.then(({ data }) => { .then(({ data }) => {
const branches = data[Object.keys(data)[0]]; const branches = data[Object.keys(data)[0]];
const tags = data[Object.keys(data)[1]]; const tags = data[Object.keys(data)[1]];
...@@ -204,7 +214,8 @@ export default class CreateMergeRequestDropdown { ...@@ -204,7 +214,8 @@ export default class CreateMergeRequestDropdown {
if (target === 'branch') { if (target === 'branch') {
result = CreateMergeRequestDropdown.findByValue(branches, ref); result = CreateMergeRequestDropdown.findByValue(branches, ref);
} else { } else {
result = CreateMergeRequestDropdown.findByValue(branches, ref, true) || result =
CreateMergeRequestDropdown.findByValue(branches, ref, true) ||
CreateMergeRequestDropdown.findByValue(tags, ref, true); CreateMergeRequestDropdown.findByValue(tags, ref, true);
this.suggestedRef = result; this.suggestedRef = result;
} }
...@@ -255,11 +266,13 @@ export default class CreateMergeRequestDropdown { ...@@ -255,11 +266,13 @@ export default class CreateMergeRequestDropdown {
} }
isBusy() { isBusy() {
return this.isCreatingMergeRequest || return (
this.isCreatingMergeRequest ||
this.mergeRequestCreated || this.mergeRequestCreated ||
this.isCreatingBranch || this.isCreatingBranch ||
this.branchCreated || this.branchCreated ||
this.isGettingRef; this.isGettingRef
);
} }
onChangeInput(event) { onChangeInput(event) {
...@@ -271,7 +284,8 @@ export default class CreateMergeRequestDropdown { ...@@ -271,7 +284,8 @@ export default class CreateMergeRequestDropdown {
value = this.branchInput.value; value = this.branchInput.value;
} else if (event.target === this.refInput) { } else if (event.target === this.refInput) {
target = 'ref'; target = 'ref';
value = event.target.value.slice(0, event.target.selectionStart) + value =
event.target.value.slice(0, event.target.selectionStart) +
event.target.value.slice(event.target.selectionEnd); event.target.value.slice(event.target.selectionEnd);
} else { } else {
return false; return false;
...@@ -396,7 +410,8 @@ export default class CreateMergeRequestDropdown { ...@@ -396,7 +410,8 @@ export default class CreateMergeRequestDropdown {
showNotAvailableMessage(target) { showNotAvailableMessage(target) {
const { input, message } = this.getTargetData(target); const { input, message } = this.getTargetData(target);
const text = target === 'branch' ? __('Branch is already taken') : __('Source is not available'); const text =
target === 'branch' ? __('Branch is already taken') : __('Source is not available');
this.removeMessage(target); this.removeMessage(target);
input.classList.add('gl-field-error-outline'); input.classList.add('gl-field-error-outline');
...@@ -459,11 +474,15 @@ export default class CreateMergeRequestDropdown { ...@@ -459,11 +474,15 @@ export default class CreateMergeRequestDropdown {
// target - 'branch' or 'ref' // target - 'branch' or 'ref'
// ref - string - the new value to use as branch or ref // ref - string - the new value to use as branch or ref
updateCreatePaths(target, ref) { updateCreatePaths(target, ref) {
const pathReplacement = `$1${ref}`; const pathReplacement = `$1${encodeURIComponent(ref)}`;
this.createBranchPath = this.createBranchPath.replace(this.regexps[target].createBranchPath, this.createBranchPath = this.createBranchPath.replace(
pathReplacement); this.regexps[target].createBranchPath,
this.createMrPath = this.createMrPath.replace(this.regexps[target].createMrPath, pathReplacement,
pathReplacement); );
this.createMrPath = this.createMrPath.replace(
this.regexps[target].createMrPath,
pathReplacement,
);
} }
} }
---
title: Fix branch name encoding for dropdown on issue page
merge_request: 19634
author:
type: fixed
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
import CreateMergeRequestDropdown from '~/create_merge_request_dropdown';
import { TEST_HOST } from 'spec/test_constants';
describe('CreateMergeRequestDropdown', () => {
let axiosMock;
let dropdown;
beforeEach(() => {
axiosMock = new MockAdapter(axios);
setFixtures(`
<div id="dummy-wrapper-element">
<div class="available"></div>
<div class="unavailable">
<div class="fa"></div>
<div class="text"></div>
</div>
<div class="js-ref"></div>
<div class="js-create-merge-request"></div>
<div class="js-create-target"></div>
<div class="js-dropdown-toggle"></div>
</div>
`);
const dummyElement = document.getElementById('dummy-wrapper-element');
dropdown = new CreateMergeRequestDropdown(dummyElement);
dropdown.refsPath = `${TEST_HOST}/dummy/refs?search=`;
});
afterEach(() => {
axiosMock.restore();
});
describe('getRef', () => {
it('escapes branch names correctly', done => {
const endpoint = `${dropdown.refsPath}contains%23hash`;
spyOn(axios, 'get').and.callThrough();
axiosMock.onGet(endpoint).replyOnce({});
dropdown
.getRef('contains#hash')
.then(() => {
expect(axios.get).toHaveBeenCalledWith(endpoint);
})
.then(done)
.catch(done.fail);
});
});
describe('updateCreatePaths', () => {
it('escapes branch names correctly', () => {
dropdown.createBranchPath = `${TEST_HOST}/branches?branch_name=some-branch&issue=42`;
dropdown.createMrPath = `${TEST_HOST}/create_merge_request?branch_name=some-branch&ref=master`;
dropdown.updateCreatePaths('branch', 'contains#hash');
expect(dropdown.createBranchPath).toBe(
`${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`,
);
expect(dropdown.createMrPath).toBe(
`${TEST_HOST}/create_merge_request?branch_name=contains%23hash&ref=master`,
);
});
});
});
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