Commit a0b783de authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'migrate-upload-button-experminent-to-glmodal' into 'master'

Migrate upload file experiment

See merge request gitlab-org/gitlab!56084
parents a429b96c c907a1ab
......@@ -3,7 +3,6 @@
import Dropzone from 'dropzone';
import $ from 'jquery';
import { sprintf, __ } from '~/locale';
import { trackUploadFileFormSubmitted } from '~/projects/upload_file_experiment';
import { HIDDEN_CLASS } from '../lib/utils/constants';
import csrf from '../lib/utils/csrf';
import { visitUrl } from '../lib/utils/url_utility';
......@@ -85,8 +84,6 @@ export default class BlobFileDropzone {
e.preventDefault();
e.stopPropagation();
trackUploadFileFormSubmitted();
if (dropzone[0].dropzone.getQueuedFiles().length === 0) {
// eslint-disable-next-line no-alert
alert(__('Please select a file'));
......
......@@ -4,7 +4,6 @@ import $ from 'jquery';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils';
import { initUploadFileTrigger } from '~/projects/upload_file_experiment';
import Tracking from '~/tracking';
import BlobFileDropzone from '../blob/blob_file_dropzone';
import NewCommitForm from '../new_commit_form';
......@@ -48,7 +47,6 @@ export const initUploadForm = () => {
new NewCommitForm(uploadBlobForm);
disableButtonIfEmptyField(uploadBlobForm.find('.js-commit-message'), '.btn-upload-file');
initUploadFileTrigger();
}
};
......
......@@ -5,6 +5,7 @@ import BlobViewer from '~/blob/viewer/index';
import { initUploadForm } from '~/blob_edit/blob_bundle';
import leaveByUrl from '~/namespaces/leave_by_url';
import initVueNotificationsDropdown from '~/notifications';
import { initUploadFileTrigger } from '~/projects/upload_file_experiment';
import initReadMore from '~/read_more';
import UserCallout from '~/user_callout';
import Star from '../../../star';
......@@ -41,3 +42,5 @@ leaveByUrl('project');
initVueNotificationsDropdown();
new ShortcutsNavigation(); // eslint-disable-line no-new
initUploadFileTrigger();
<script>
import { GlButton, GlModalDirective } from '@gitlab/ui';
import UploadBlobModal from '~/repository/components/upload_blob_modal.vue';
import { trackFileUploadEvent } from '../upload_file_experiment_tracking';
const UPLOAD_BLOB_MODAL_ID = 'details-modal-upload-blob';
......@@ -16,7 +17,7 @@ export default {
targetBranch: {
default: '',
},
origionalBranch: {
originalBranch: {
default: '',
},
canPushCode: {
......@@ -29,19 +30,28 @@ export default {
default: '',
},
},
methods: {
trackOpenModal() {
trackFileUploadEvent('click_upload_modal_trigger');
},
},
uploadBlobModalId: UPLOAD_BLOB_MODAL_ID,
};
</script>
<template>
<span>
<gl-button v-gl-modal="$options.uploadBlobModalId" icon="upload">{{
__('Upload File')
}}</gl-button>
<gl-button
v-gl-modal="$options.uploadBlobModalId"
icon="upload"
data-testid="upload-file-button"
@click="trackOpenModal"
>{{ __('Upload File') }}</gl-button
>
<upload-blob-modal
:modal-id="$options.uploadBlobModalId"
:commit-message="__('Upload New File')"
:target-branch="targetBranch"
:origional-branch="origionalBranch"
:original-branch="originalBranch"
:can-push-code="canPushCode"
:path="path"
/>
......
import ExperimentTracking from '~/experimentation/experiment_tracking';
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import createRouter from '~/repository/router';
import UploadButton from './details/upload_button.vue';
function trackEvent(eventName) {
const isEmpty = Boolean(document.querySelector('.project-home-panel.empty-project'));
const property = isEmpty ? 'empty' : 'nonempty';
const label = 'blob-upload-modal';
const Tracking = new ExperimentTracking('empty_repo_upload', { label, property });
export const initUploadFileTrigger = () => {
const uploadFileTriggerEl = document.querySelector('.js-upload-file-experiment-trigger');
Tracking.event(eventName);
}
if (!uploadFileTriggerEl) return false;
export function initUploadFileTrigger() {
const uploadFileTriggerEl = document.querySelector('.js-upload-file-experiment-trigger');
const {
targetBranch,
originalBranch,
canPushCode,
path,
projectPath,
} = uploadFileTriggerEl.dataset;
if (uploadFileTriggerEl) {
uploadFileTriggerEl.addEventListener('click', () => {
trackEvent('click_upload_modal_trigger');
return new Vue({
el: uploadFileTriggerEl,
router: createRouter(projectPath, originalBranch),
provide: {
targetBranch,
originalBranch,
canPushCode: parseBoolean(canPushCode),
path,
projectPath,
},
render(h) {
return h(UploadButton);
},
});
}
}
export function trackUploadFileFormSubmitted() {
trackEvent('click_upload_modal_form_submit');
}
};
import ExperimentTracking from '~/experimentation/experiment_tracking';
export const trackFileUploadEvent = (eventName) => {
const isEmpty = Boolean(document.querySelector('.project-home-panel.empty-project'));
const property = isEmpty ? 'empty' : 'nonempty';
const label = 'blob-upload-modal';
const FileUploadTracking = new ExperimentTracking('empty_repo_upload', { label, property });
FileUploadTracking.event(eventName);
};
......@@ -15,6 +15,7 @@ import { ContentTypeMultipartFormData } from '~/lib/utils/headers';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import { trackFileUploadEvent } from '~/projects/upload_file_experiment_tracking';
import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
const PRIMARY_OPTIONS_TEXT = __('Upload file');
......@@ -62,7 +63,7 @@ export default {
type: String,
required: true,
},
origionalBranch: {
originalBranch: {
type: String,
required: true,
},
......@@ -113,7 +114,7 @@ export default {
return numberToHumanSize(this.file.size);
},
showCreateNewMrToggle() {
return this.canPushCode && this.target !== this.origionalBranch;
return this.canPushCode && this.target !== this.originalBranch;
},
formCompleted() {
return this.file && this.commit && this.target;
......@@ -158,6 +159,7 @@ export default {
},
})
.then((response) => {
trackFileUploadEvent('click_upload_modal_form_submit');
visitUrl(response.data.filePath);
})
.catch(() => {
......
......@@ -253,8 +253,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
nil,
nil,
{
'toggle' => 'modal',
'target' => '#modal-upload-blob'
'target_branch' => default_branch_or_master,
'original_branch' => default_branch_or_master,
'can_push_code' => 'true',
'path' => project_create_blob_path(project, default_branch_or_master),
'project_path' => project.path
}
)
end
......
import $ from 'jquery';
import BlobFileDropzone from '~/blob/blob_file_dropzone';
import { trackUploadFileFormSubmitted } from '~/projects/upload_file_experiment';
jest.mock('~/projects/upload_file_experiment', () => ({
trackUploadFileFormSubmitted: jest.fn(),
}));
describe('BlobFileDropzone', () => {
let dropzone;
......@@ -45,13 +40,5 @@ describe('BlobFileDropzone', () => {
expect(replaceFileButton.is(':disabled')).toEqual(true);
expect(dropzone.processQueue).toHaveBeenCalled();
});
it('calls the tracking event', () => {
jest.spyOn(window, 'alert').mockImplementation(() => {});
replaceFileButton.click();
expect(trackUploadFileFormSubmitted).toHaveBeenCalled();
});
});
});
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import UploadButton from '~/projects/details/upload_button.vue';
import { trackFileUploadEvent } from '~/projects/upload_file_experiment_tracking';
import UploadBlobModal from '~/repository/components/upload_blob_modal.vue';
jest.mock('~/projects/upload_file_experiment_tracking');
const MODAL_ID = 'details-modal-upload-blob';
describe('UploadButton', () => {
......@@ -47,6 +50,10 @@ describe('UploadButton', () => {
wrapper.find(GlButton).vm.$emit('click');
});
it('tracks the click_upload_modal_trigger event', () => {
expect(trackFileUploadEvent).toHaveBeenCalledWith('click_upload_modal_trigger');
});
it('opens the modal', () => {
expect(glModalDirective).toHaveBeenCalledWith(MODAL_ID);
});
......
import ExperimentTracking from '~/experimentation/experiment_tracking';
import * as UploadFileExperiment from '~/projects/upload_file_experiment';
import { trackFileUploadEvent } from '~/projects/upload_file_experiment_tracking';
jest.mock('~/experimentation/experiment_tracking');
const fixture = `<a class='js-upload-file-experiment-trigger' data-toggle='modal' data-target='#modal-upload-blob'></a><div id='modal-upload-blob'></div><div class='project-home-panel empty-project'></div>`;
const findModal = () => document.querySelector('[aria-modal="true"]');
const findTrigger = () => document.querySelector('.js-upload-file-experiment-trigger');
const eventName = 'click_upload_modal_form_submit';
const fixture = `<a class='js-upload-file-experiment-trigger'></a><div class='project-home-panel empty-project'></div>`;
beforeEach(() => {
document.body.innerHTML = fixture;
......@@ -15,23 +14,26 @@ afterEach(() => {
document.body.innerHTML = '';
});
describe('trackUploadFileFormSubmitted', () => {
it('initializes ExperimentTracking with the correct arguments and calls the tracking event with correct arguments', () => {
UploadFileExperiment.trackUploadFileFormSubmitted();
describe('trackFileUploadEvent', () => {
it('initializes ExperimentTracking with the correct tracking event', () => {
trackFileUploadEvent(eventName);
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(eventName);
});
it('calls ExperimentTracking with the correct arguments', () => {
trackFileUploadEvent(eventName);
expect(ExperimentTracking).toHaveBeenCalledWith('empty_repo_upload', {
label: 'blob-upload-modal',
property: 'empty',
});
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
'click_upload_modal_form_submit',
);
});
it('initializes ExperimentTracking with the correct arguments when the project is not empty', () => {
it('calls ExperimentTracking with the correct arguments when the project is not empty', () => {
document.querySelector('.empty-project').remove();
UploadFileExperiment.trackUploadFileFormSubmitted();
trackFileUploadEvent(eventName);
expect(ExperimentTracking).toHaveBeenCalledWith('empty_repo_upload', {
label: 'blob-upload-modal',
......@@ -39,14 +41,3 @@ describe('trackUploadFileFormSubmitted', () => {
});
});
});
describe('initUploadFileTrigger', () => {
it('calls modal and tracks event', () => {
UploadFileExperiment.initUploadFileTrigger();
expect(findModal()).not.toExist();
findTrigger().click();
expect(findModal()).toExist();
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith('click_upload_modal_trigger');
});
});
......@@ -6,9 +6,11 @@ import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
import { visitUrl } from '~/lib/utils/url_utility';
import { trackFileUploadEvent } from '~/projects/upload_file_experiment_tracking';
import UploadBlobModal from '~/repository/components/upload_blob_modal.vue';
import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
jest.mock('~/projects/upload_file_experiment_tracking');
jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn(),
......@@ -19,7 +21,7 @@ const initialProps = {
modalId: 'upload-blob',
commitMessage: 'Upload New File',
targetBranch: 'master',
origionalBranch: 'master',
originalBranch: 'master',
canPushCode: true,
path: 'new_upload',
};
......@@ -160,6 +162,10 @@ describe('UploadBlobModal', () => {
await waitForPromises();
});
it('tracks the click_upload_modal_trigger event when opening the modal', () => {
expect(trackFileUploadEvent).toHaveBeenCalledWith('click_upload_modal_form_submit');
});
it('redirects to the uploaded file', () => {
expect(visitUrl).toHaveBeenCalled();
});
......@@ -179,6 +185,10 @@ describe('UploadBlobModal', () => {
await waitForPromises();
});
it('does not track an event', () => {
expect(trackFileUploadEvent).not.toHaveBeenCalled();
});
it('creates a flash error', () => {
expect(createFlash).toHaveBeenCalledWith('Error uploading file. Please try again.');
});
......
......@@ -563,6 +563,51 @@ RSpec.describe ProjectPresenter do
end
end
end
describe '#upload_anchor_data' do
context 'with empty_repo_upload enabled' do
before do
stub_experiments(empty_repo_upload: :candidate)
end
context 'user can push to branch' do
before do
project.add_developer(user)
end
it 'returns upload_anchor_data' do
expect(presenter.upload_anchor_data).to have_attributes(
is_link: false,
label: a_string_including('Upload file'),
data: {
"can_push_code" => "true",
"original_branch" => "master",
"path" => "/#{project.full_path}/-/create/master",
"project_path" => project.path,
"target_branch" => "master"
}
)
end
end
context 'user cannot push to branch' do
it 'returns nil' do
expect(presenter.upload_anchor_data).to be_nil
end
end
end
context 'with empty_repo_upload disabled' do
before do
stub_experiments(empty_repo_upload: :control)
project.add_developer(user)
end
it 'returns nil' do
expect(presenter.upload_anchor_data).to be_nil
end
end
end
end
describe '#statistics_buttons' do
......
......@@ -97,18 +97,16 @@ end
RSpec.shared_examples 'uploads and commits a new text file via "upload file" button' do
it 'uploads and commits a new text file via "upload file" button', :js do
find('.js-upload-file-experiment-trigger', text: 'Upload file').click
find('[data-testid="upload-file-button"]').click
drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
page.within('#modal-upload-blob') do
page.within('#details-modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
end
click_button('Upload file')
wait_for_requests
expect(page).to have_content('New commit message')
expect(page).to have_content('Lorem ipsum dolor sit amet')
expect(page).to have_content('Sed ut perspiciatis unde omnis')
......
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