Commit 03257247 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents 18fa27d9 26658d13
...@@ -262,7 +262,7 @@ export default class Clusters { ...@@ -262,7 +262,7 @@ export default class Clusters {
this.store.updateAppProperty(appId, 'requestReason', null); this.store.updateAppProperty(appId, 'requestReason', null);
this.store.updateAppProperty(appId, 'statusReason', null); this.store.updateAppProperty(appId, 'statusReason', null);
this.service.installApplication(appId, data.params).catch(() => { return this.service.installApplication(appId, data.params).catch(() => {
this.store.updateAppProperty(appId, 'requestStatus', REQUEST_FAILURE); this.store.updateAppProperty(appId, 'requestStatus', REQUEST_FAILURE);
this.store.updateAppProperty( this.store.updateAppProperty(
appId, appId,
......
...@@ -71,29 +71,39 @@ export default class ImageFile { ...@@ -71,29 +71,39 @@ export default class ImageFile {
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
initDraggable($el, padding, callback) { initDraggable($el, padding, callback) {
var dragging = false; var dragging = false;
var $body = $('body'); const $body = $('body');
var $offsetEl = $el.parent(); const $offsetEl = $el.parent();
const dragStart = function() {
$el.off('mousedown').on('mousedown', function() {
dragging = true; dragging = true;
$body.css('user-select', 'none'); $body.css('user-select', 'none');
}); };
const dragStop = function() {
$body
.off('mouseup')
.off('mousemove')
.on('mouseup', function() {
dragging = false; dragging = false;
$body.css('user-select', ''); $body.css('user-select', '');
}) };
.on('mousemove', function(e) { const dragMove = function(e) {
var left; const moveX = e.pageX || e.touches[0].pageX;
const left = moveX - ($offsetEl.offset().left + padding);
if (!dragging) return; if (!dragging) return;
left = e.pageX - ($offsetEl.offset().left + padding);
callback(e, left); callback(e, left);
}); };
$el
.off('mousedown')
.off('touchstart')
.on('mousedown', dragStart)
.on('touchstart', dragStart);
$body
.off('mouseup')
.off('mousemove')
.off('touchend')
.off('touchmove')
.on('mouseup', dragStop)
.on('touchend', dragStop)
.on('mousemove', dragMove)
.on('touchmove', dragMove);
} }
prepareFrames(view) { prepareFrames(view) {
......
...@@ -40,12 +40,15 @@ export default { ...@@ -40,12 +40,15 @@ export default {
}, },
beforeDestroy() { beforeDestroy() {
document.body.removeEventListener('mouseup', this.stopDrag); document.body.removeEventListener('mouseup', this.stopDrag);
this.$refs.dragger.removeEventListener('mousedown', this.startDrag); document.body.removeEventListener('touchend', this.stopDrag);
document.body.removeEventListener('mousemove', this.dragMove);
document.body.removeEventListener('touchmove', this.dragMove);
}, },
methods: { methods: {
dragMove(e) { dragMove(e) {
if (!this.dragging) return; if (!this.dragging) return;
const left = e.pageX - this.$refs.dragTrack.getBoundingClientRect().left; const moveX = e.pageX || e.touches[0].pageX;
const left = moveX - this.$refs.dragTrack.getBoundingClientRect().left;
const dragTrackWidth = const dragTrackWidth =
this.$refs.dragTrack.clientWidth - this.$refs.dragger.clientWidth || 100; this.$refs.dragTrack.clientWidth - this.$refs.dragger.clientWidth || 100;
...@@ -60,11 +63,13 @@ export default { ...@@ -60,11 +63,13 @@ export default {
this.dragging = true; this.dragging = true;
document.body.style.userSelect = 'none'; document.body.style.userSelect = 'none';
document.body.addEventListener('mousemove', this.dragMove); document.body.addEventListener('mousemove', this.dragMove);
document.body.addEventListener('touchmove', this.dragMove);
}, },
stopDrag() { stopDrag() {
this.dragging = false; this.dragging = false;
document.body.style.userSelect = ''; document.body.style.userSelect = '';
document.body.removeEventListener('mousemove', this.dragMove); document.body.removeEventListener('mousemove', this.dragMove);
document.body.removeEventListener('touchmove', this.dragMove);
}, },
prepareOnionSkin() { prepareOnionSkin() {
if (this.onionOldImgInfo && this.onionNewImgInfo) { if (this.onionOldImgInfo && this.onionNewImgInfo) {
...@@ -82,6 +87,7 @@ export default { ...@@ -82,6 +87,7 @@ export default {
this.$refs.dragTrack.clientWidth - this.$refs.dragger.clientWidth || 100; this.$refs.dragTrack.clientWidth - this.$refs.dragger.clientWidth || 100;
document.body.addEventListener('mouseup', this.stopDrag); document.body.addEventListener('mouseup', this.stopDrag);
document.body.addEventListener('touchend', this.stopDrag);
} }
}, },
onionNewImgLoaded(imgInfo) { onionNewImgLoaded(imgInfo) {
...@@ -140,7 +146,14 @@ export default { ...@@ -140,7 +146,14 @@ export default {
</div> </div>
<div class="controls"> <div class="controls">
<div class="transparent"></div> <div class="transparent"></div>
<div ref="dragTrack" class="drag-track" @mousedown="startDrag" @mouseup="stopDrag"> <div
ref="dragTrack"
class="drag-track"
@mousedown="startDrag"
@mouseup="stopDrag"
@touchstart="startDrag"
@touchend="stopDrag"
>
<div ref="dragger" :style="{ left: onionDraggerPixelPos }" class="dragger"></div> <div ref="dragger" :style="{ left: onionDraggerPixelPos }" class="dragger"></div>
</div> </div>
<div class="opaque"></div> <div class="opaque"></div>
......
...@@ -46,6 +46,8 @@ export default { ...@@ -46,6 +46,8 @@ export default {
window.removeEventListener('resize', this.resizeThrottled, false); window.removeEventListener('resize', this.resizeThrottled, false);
document.body.removeEventListener('mouseup', this.stopDrag); document.body.removeEventListener('mouseup', this.stopDrag);
document.body.removeEventListener('mousemove', this.dragMove); document.body.removeEventListener('mousemove', this.dragMove);
document.body.removeEventListener('touchend', this.stopDrag);
document.body.removeEventListener('touchmove', this.dragMove);
}, },
mounted() { mounted() {
window.addEventListener('resize', this.resize, false); window.addEventListener('resize', this.resize, false);
...@@ -54,7 +56,8 @@ export default { ...@@ -54,7 +56,8 @@ export default {
dragMove(e) { dragMove(e) {
if (!this.dragging) return; if (!this.dragging) return;
let leftValue = e.pageX - this.$refs.swipeFrame.getBoundingClientRect().left; const moveX = e.pageX || e.touches[0].pageX;
let leftValue = moveX - this.$refs.swipeFrame.getBoundingClientRect().left;
const spaceLeft = 20; const spaceLeft = 20;
const { clientWidth } = this.$refs.swipeFrame; const { clientWidth } = this.$refs.swipeFrame;
if (leftValue <= 0) { if (leftValue <= 0) {
...@@ -69,10 +72,12 @@ export default { ...@@ -69,10 +72,12 @@ export default {
startDrag() { startDrag() {
this.dragging = true; this.dragging = true;
document.body.addEventListener('mousemove', this.dragMove); document.body.addEventListener('mousemove', this.dragMove);
document.body.addEventListener('touchmove', this.dragMove);
}, },
stopDrag() { stopDrag() {
this.dragging = false; this.dragging = false;
document.body.removeEventListener('mousemove', this.dragMove); document.body.removeEventListener('mousemove', this.dragMove);
document.body.removeEventListener('touchmove', this.dragMove);
}, },
prepareSwipe() { prepareSwipe() {
if (this.swipeOldImgInfo && this.swipeNewImgInfo) { if (this.swipeOldImgInfo && this.swipeNewImgInfo) {
...@@ -83,6 +88,7 @@ export default { ...@@ -83,6 +88,7 @@ export default {
Math.max(this.swipeOldImgInfo.renderedHeight, this.swipeNewImgInfo.renderedHeight) + 2; Math.max(this.swipeOldImgInfo.renderedHeight, this.swipeNewImgInfo.renderedHeight) + 2;
document.body.addEventListener('mouseup', this.stopDrag); document.body.addEventListener('mouseup', this.stopDrag);
document.body.addEventListener('touchend', this.stopDrag);
} }
}, },
swipeNewImgLoaded(imgInfo) { swipeNewImgLoaded(imgInfo) {
...@@ -143,6 +149,8 @@ export default { ...@@ -143,6 +149,8 @@ export default {
class="swipe-bar" class="swipe-bar"
@mousedown="startDrag" @mousedown="startDrag"
@mouseup="stopDrag" @mouseup="stopDrag"
@touchstart="startDrag"
@touchend="stopDrag"
> >
<span class="top-handle"></span> <span class="bottom-handle"></span> <span class="top-handle"></span> <span class="bottom-handle"></span>
</span> </span>
......
...@@ -139,6 +139,7 @@ ...@@ -139,6 +139,7 @@
@include btn-white; @include btn-white;
color: $gl-text-color; color: $gl-text-color;
white-space: nowrap;
&:focus:active { &:focus:active {
outline: 0; outline: 0;
......
---
title: Migrate clusters tests to jest
merge_request: 27013
author:
type: other
---
title: "Make touch events work on image diff swipe view and onion skin"
merge_request: 26971
author: ftab
type: added
---
title: Add to white-space nowrap to all buttons
merge_request: 27069
author:
type: fixed
...@@ -5,19 +5,41 @@ import { ...@@ -5,19 +5,41 @@ import {
APPLICATION_STATUS, APPLICATION_STATUS,
INGRESS_DOMAIN_SUFFIX, INGRESS_DOMAIN_SUFFIX,
} from '~/clusters/constants'; } from '~/clusters/constants';
import getSetTimeoutPromise from 'spec/helpers/set_timeout_promise_helper'; import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { loadHTMLFixture } from 'helpers/fixtures';
import { setTestTimeout } from 'helpers/timeout';
import $ from 'jquery';
describe('Clusters', () => { describe('Clusters', () => {
setTestTimeout(500);
let cluster; let cluster;
preloadFixtures('clusters/show_cluster.html'); let mock;
const mockGetClusterStatusRequest = () => {
const { statusPath } = document.querySelector('.js-edit-cluster-form').dataset;
mock = new MockAdapter(axios);
mock.onGet(statusPath).reply(200);
};
beforeEach(() => {
loadHTMLFixture('clusters/show_cluster.html');
});
beforeEach(() => {
mockGetClusterStatusRequest();
});
beforeEach(() => { beforeEach(() => {
loadFixtures('clusters/show_cluster.html');
cluster = new Clusters(); cluster = new Clusters();
}); });
afterEach(() => { afterEach(() => {
cluster.destroy(); cluster.destroy();
mock.restore();
}); });
describe('toggle', () => { describe('toggle', () => {
...@@ -29,16 +51,13 @@ describe('Clusters', () => { ...@@ -29,16 +51,13 @@ describe('Clusters', () => {
'.js-cluster-enable-toggle-area .js-project-feature-toggle-input', '.js-cluster-enable-toggle-area .js-project-feature-toggle-input',
); );
toggleButton.click(); $(toggleInput).one('trigger-change', () => {
getSetTimeoutPromise()
.then(() => {
expect(toggleButton.classList).not.toContain('is-checked'); expect(toggleButton.classList).not.toContain('is-checked');
expect(toggleInput.getAttribute('value')).toEqual('false'); expect(toggleInput.getAttribute('value')).toEqual('false');
}) done();
.then(done) });
.catch(done.fail);
toggleButton.click();
}); });
}); });
...@@ -197,7 +216,7 @@ describe('Clusters', () => { ...@@ -197,7 +216,7 @@ describe('Clusters', () => {
describe('installApplication', () => { describe('installApplication', () => {
it('tries to install helm', () => { it('tries to install helm', () => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce();
expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); expect(cluster.store.state.applications.helm.requestStatus).toEqual(null);
...@@ -209,7 +228,7 @@ describe('Clusters', () => { ...@@ -209,7 +228,7 @@ describe('Clusters', () => {
}); });
it('tries to install ingress', () => { it('tries to install ingress', () => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce();
expect(cluster.store.state.applications.ingress.requestStatus).toEqual(null); expect(cluster.store.state.applications.ingress.requestStatus).toEqual(null);
...@@ -221,7 +240,7 @@ describe('Clusters', () => { ...@@ -221,7 +240,7 @@ describe('Clusters', () => {
}); });
it('tries to install runner', () => { it('tries to install runner', () => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce();
expect(cluster.store.state.applications.runner.requestStatus).toEqual(null); expect(cluster.store.state.applications.runner.requestStatus).toEqual(null);
...@@ -233,7 +252,7 @@ describe('Clusters', () => { ...@@ -233,7 +252,7 @@ describe('Clusters', () => {
}); });
it('tries to install jupyter', () => { it('tries to install jupyter', () => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce();
expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(null); expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(null);
cluster.installApplication({ cluster.installApplication({
...@@ -248,35 +267,32 @@ describe('Clusters', () => { ...@@ -248,35 +267,32 @@ describe('Clusters', () => {
}); });
}); });
it('sets error request status when the request fails', done => { it('sets error request status when the request fails', () => {
spyOn(cluster.service, 'installApplication').and.returnValue( jest
Promise.reject(new Error('STUBBED ERROR')), .spyOn(cluster.service, 'installApplication')
); .mockRejectedValueOnce(new Error('STUBBED ERROR'));
expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); expect(cluster.store.state.applications.helm.requestStatus).toEqual(null);
cluster.installApplication({ id: 'helm' }); const promise = cluster.installApplication({ id: 'helm' });
expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_SUBMITTED); expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_SUBMITTED);
expect(cluster.store.state.applications.helm.requestReason).toEqual(null); expect(cluster.store.state.applications.helm.requestReason).toEqual(null);
expect(cluster.service.installApplication).toHaveBeenCalled(); expect(cluster.service.installApplication).toHaveBeenCalled();
getSetTimeoutPromise() return promise.then(() => {
.then(() => {
expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_FAILURE); expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_FAILURE);
expect(cluster.store.state.applications.helm.requestReason).toBeDefined(); expect(cluster.store.state.applications.helm.requestReason).toBeDefined();
}) });
.then(done)
.catch(done.fail);
}); });
}); });
describe('handleSuccess', () => { describe('handleSuccess', () => {
beforeEach(() => { beforeEach(() => {
spyOn(cluster.store, 'updateStateFromServer'); jest.spyOn(cluster.store, 'updateStateFromServer').mockReturnThis();
spyOn(cluster, 'toggleIngressDomainHelpText'); jest.spyOn(cluster, 'toggleIngressDomainHelpText').mockReturnThis();
spyOn(cluster, 'checkForNewInstalls'); jest.spyOn(cluster, 'checkForNewInstalls').mockReturnThis();
spyOn(cluster, 'updateContainer'); jest.spyOn(cluster, 'updateContainer').mockReturnThis();
cluster.handleSuccess({ data: {} }); cluster.handleSuccess({ data: {} });
}); });
......
...@@ -2,7 +2,7 @@ import Vue from 'vue'; ...@@ -2,7 +2,7 @@ import Vue from 'vue';
import eventHub from '~/clusters/event_hub'; import eventHub from '~/clusters/event_hub';
import { APPLICATION_STATUS, REQUEST_SUBMITTED, REQUEST_FAILURE } from '~/clusters/constants'; import { APPLICATION_STATUS, REQUEST_SUBMITTED, REQUEST_FAILURE } from '~/clusters/constants';
import applicationRow from '~/clusters/components/application_row.vue'; import applicationRow from '~/clusters/components/application_row.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import mountComponent from 'helpers/vue_mount_component_helper';
import { DEFAULT_APPLICATION_STATE } from '../services/mock_data'; import { DEFAULT_APPLICATION_STATE } from '../services/mock_data';
describe('Application Row', () => { describe('Application Row', () => {
...@@ -160,7 +160,7 @@ describe('Application Row', () => { ...@@ -160,7 +160,7 @@ describe('Application Row', () => {
}); });
it('clicking install button emits event', () => { it('clicking install button emits event', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.INSTALLABLE, status: APPLICATION_STATUS.INSTALLABLE,
...@@ -176,7 +176,7 @@ describe('Application Row', () => { ...@@ -176,7 +176,7 @@ describe('Application Row', () => {
}); });
it('clicking install button when installApplicationRequestParams are provided emits event', () => { it('clicking install button when installApplicationRequestParams are provided emits event', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.INSTALLABLE, status: APPLICATION_STATUS.INSTALLABLE,
...@@ -193,7 +193,7 @@ describe('Application Row', () => { ...@@ -193,7 +193,7 @@ describe('Application Row', () => {
}); });
it('clicking disabled install button emits nothing', () => { it('clicking disabled install button emits nothing', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.INSTALLING, status: APPLICATION_STATUS.INSTALLING,
...@@ -255,7 +255,7 @@ describe('Application Row', () => { ...@@ -255,7 +255,7 @@ describe('Application Row', () => {
}); });
it('clicking upgrade button emits event', () => { it('clicking upgrade button emits event', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.UPDATE_ERRORED, status: APPLICATION_STATUS.UPDATE_ERRORED,
...@@ -271,7 +271,7 @@ describe('Application Row', () => { ...@@ -271,7 +271,7 @@ describe('Application Row', () => {
}); });
it('clicking disabled upgrade button emits nothing', () => { it('clicking disabled upgrade button emits nothing', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.UPDATING, status: APPLICATION_STATUS.UPDATING,
......
...@@ -2,7 +2,7 @@ import Vue from 'vue'; ...@@ -2,7 +2,7 @@ import Vue from 'vue';
import applications from '~/clusters/components/applications.vue'; import applications from '~/clusters/components/applications.vue';
import { CLUSTER_TYPE } from '~/clusters/constants'; import { CLUSTER_TYPE } from '~/clusters/constants';
import eventHub from '~/clusters/event_hub'; import eventHub from '~/clusters/event_hub';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import mountComponent from 'helpers/vue_mount_component_helper';
import { APPLICATIONS_MOCK_STATE } from '../services/mock_data'; import { APPLICATIONS_MOCK_STATE } from '../services/mock_data';
describe('Applications', () => { describe('Applications', () => {
...@@ -314,7 +314,7 @@ describe('Applications', () => { ...@@ -314,7 +314,7 @@ describe('Applications', () => {
}); });
it('emits event when clicking Save changes button', () => { it('emits event when clicking Save changes button', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit');
vm = mountComponent(Applications, props); vm = mountComponent(Applications, props);
const saveButton = vm.$el.querySelector('.js-knative-save-domain-button'); const saveButton = vm.$el.querySelector('.js-knative-save-domain-button');
......
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