Commit 1a9c3e9c authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'jivanvl-add-toast-reset-pipelines-button' into 'master'

Add toast to reset pipelines min button

See merge request gitlab-org/gitlab!41838
parents 6ff86c76 f6edec19
import Vue from 'vue'; import Vue from 'vue';
import { GlToast } from '@gitlab/ui';
import ResetButton from './reset_button.vue'; import ResetButton from './reset_button.vue';
Vue.use(GlToast);
export function pipelineMinutes() { export function pipelineMinutes() {
const el = document.getElementById('pipeline-minutes-vue'); const el = document.getElementById('pipeline-minutes-vue');
......
<script> <script>
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import statusCodes from '~/lib/utils/http_status';
export default { export default {
components: { components: {
...@@ -11,6 +14,22 @@ export default { ...@@ -11,6 +14,22 @@ export default {
default: '', default: '',
}, },
}, },
methods: {
resetPipelineMinutes() {
axios
.post(this.resetMinutesPath)
.then(resp => {
if (resp.status === statusCodes.OK) {
this.$toast.show(__('User pipeline minutes were successfully reset.'));
}
})
.catch(() =>
this.$toast.show(__('There was an error resetting user pipeline minutes.'), {
type: 'error',
}),
);
},
},
}; };
</script> </script>
<template> <template>
...@@ -25,7 +44,7 @@ export default { ...@@ -25,7 +44,7 @@ export default {
) )
}} }}
</p> </p>
<gl-button target="_self" :href="resetMinutesPath" data-method="post"> <gl-button @click="resetPipelineMinutes">
{{ s__('SharedRunnersMinutesSettings|Reset pipeline minutes') }} {{ s__('SharedRunnersMinutesSettings|Reset pipeline minutes') }}
</gl-button> </gl-button>
</div> </div>
......
---
title: Add toast to the reset pipelines minutes button
merge_request: 41838
author:
type: changed
...@@ -19,10 +19,10 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do ...@@ -19,10 +19,10 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do
time = Time.now time = Time.now
Timecop.freeze(time) do Timecop.freeze(time) do
click_link 'Reset pipeline minutes' click_button 'Reset pipeline minutes'
end end
expect(page).to have_selector('.flash-notice') expect(page).to have_selector('.gl-toast')
expect(current_path).to include(namespace.path) expect(current_path).to include(namespace.path)
expect(namespace.namespace_statistics.reload.shared_runners_seconds).to eq(0) expect(namespace.namespace_statistics.reload.shared_runners_seconds).to eq(0)
...@@ -38,10 +38,10 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do ...@@ -38,10 +38,10 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do
end end
it 'renders edit page with an error' do it 'renders edit page with an error' do
click_link 'Reset pipeline minutes' click_button 'Reset pipeline minutes'
expect(current_path).to include(namespace.path) expect(current_path).to include(namespace.path)
expect(page).to have_selector('.flash-error') expect(page).to have_selector('.gl-toast')
end end
end end
end end
...@@ -56,7 +56,7 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do ...@@ -56,7 +56,7 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do
end end
it 'reset pipeline minutes button is visible' do it 'reset pipeline minutes button is visible' do
expect(page).to have_link('Reset pipeline minutes', href: reset_runners_minutes_admin_user_path(user)) expect(page).to have_button('Reset pipeline minutes')
end end
include_examples 'resetting pipeline minutes' include_examples 'resetting pipeline minutes'
...@@ -86,7 +86,7 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do ...@@ -86,7 +86,7 @@ RSpec.describe 'Reset namespace pipeline minutes', :js do
end end
it 'reset pipeline minutes button is visible' do it 'reset pipeline minutes button is visible' do
expect(page).to have_link('Reset pipeline minutes', href: admin_group_reset_runners_minutes_path(group)) expect(page).to have_button('Reset pipeline minutes')
end end
include_examples 'resetting pipeline minutes' include_examples 'resetting pipeline minutes'
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui'; import { GlButton } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
import ResetButton from 'ee/pages/admin/users/pipeline_minutes/reset_button.vue'; import ResetButton from 'ee/pages/admin/users/pipeline_minutes/reset_button.vue';
import axios from '~/lib/utils/axios_utils';
import httpStatusCodes from '~/lib/utils/http_status';
const defaultProps = { resetMinutesPath: '/adming/reset_minutes' }; const defaultProps = { resetMinutesPath: '/adming/reset_minutes' };
const $toast = {
show: jest.fn(),
};
describe('Reset pipeline minutes button', () => { describe('Reset pipeline minutes button', () => {
let wrapper; let wrapper;
let mock;
beforeEach(() => { beforeEach(() => {
wrapper = shallowMount(ResetButton, { wrapper = shallowMount(ResetButton, {
provide: { provide: {
...defaultProps, ...defaultProps,
}, },
mocks: {
$toast,
},
}); });
mock = new MockAdapter(axios);
}); });
afterEach(() => { afterEach(() => {
...@@ -28,9 +40,56 @@ describe('Reset pipeline minutes button', () => { ...@@ -28,9 +40,56 @@ describe('Reset pipeline minutes button', () => {
expect(button.text()).toBe('Reset pipeline minutes'); expect(button.text()).toBe('Reset pipeline minutes');
}); });
it('should contain an href attribute set to the "resetMinutesPath" prop', () => { describe('when the api is available', () => {
const button = findResetButton(); beforeEach(() => {
mock
.onPost(defaultProps.resetMinutesPath)
.reply(httpStatusCodes.OK, { status: httpStatusCodes.OK });
});
afterEach(() => {
mock.restore();
});
it('should create a network request when the reset button is clicked', () => {
const axiosSpy = jest.spyOn(axios, 'post');
const button = findResetButton();
button.vm.$emit('click');
return axios.waitForAll().then(() => {
expect(axiosSpy).toHaveBeenCalled();
expect($toast.show).toHaveBeenCalledWith('User pipeline minutes were successfully reset.');
});
});
});
describe('when the api is not available', () => {
beforeEach(() => {
mock.onPost(defaultProps.resetMinutesPath).reply(httpStatusCodes.SERVICE_UNAVAILABLE, {
status: httpStatusCodes.SERVICE_UNAVAILABLE,
});
});
afterEach(() => {
mock.restore();
});
it('should show a toast error message', () => {
const axiosSpy = jest.spyOn(axios, 'post');
const button = findResetButton();
expect(button.attributes('href')).toBe(defaultProps.resetMinutesPath); button.vm.$emit('click');
return axios.waitForAll().then(() => {
expect(axiosSpy).toHaveBeenCalled();
expect($toast.show).toHaveBeenCalledWith(
'There was an error resetting user pipeline minutes.',
{ type: 'error' },
);
});
});
}); });
}); });
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