Commit c03b3938 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '196843-disable-form-when-no-dictionary' into 'master'

Disable expiration policy if dict is absent from API

See merge request gitlab-org/gitlab!23511
parents c55ba092 77d30346
<script>
import { mapActions } from 'vuex';
import { mapActions, mapState } from 'vuex';
import { GlAlert } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
import { FETCH_SETTINGS_ERROR_MESSAGE } from '../constants';
import SettingsForm from './settings_form.vue';
......@@ -7,6 +10,23 @@ import SettingsForm from './settings_form.vue';
export default {
components: {
SettingsForm,
GlAlert,
},
computed: {
...mapState(['isDisabled']),
notAvailableMessage() {
return sprintf(
s__(
'ContainerRegistry|Currently, the Container Registry tag expiration feature is not available for projects created before GitLab version 12.8. For updates and more information, visit Issue %{linkStart}#196124%{linkEnd}',
),
{
linkStart:
'<a href="https://gitlab.com/gitlab-org/gitlab/issues/196124" target="_blank" rel="noopener noreferrer">',
linkEnd: '</a>',
},
false,
);
},
},
mounted() {
this.fetchSettings().catch(() =>
......@@ -34,6 +54,9 @@ export default {
}}
</li>
</ul>
<settings-form ref="settings-form" />
<settings-form v-if="!isDisabled" />
<gl-alert v-else :dismissible="false">
<p v-html="notAvailableMessage"></p>
</gl-alert>
</div>
</template>
......@@ -4,7 +4,13 @@ import * as types from './mutation_types';
export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_STATE, data);
export const updateSettings = ({ commit }, data) => commit(types.UPDATE_SETTINGS, data);
export const toggleLoading = ({ commit }) => commit(types.TOGGLE_LOADING);
export const receiveSettingsSuccess = ({ commit }, data = {}) => commit(types.SET_SETTINGS, data);
export const receiveSettingsSuccess = ({ commit }, data) => {
if (data) {
commit(types.SET_SETTINGS, data);
} else {
commit(types.SET_IS_DISABLED, true);
}
};
export const resetSettings = ({ commit }) => commit(types.RESET_SETTINGS);
export const fetchSettings = ({ dispatch, state }) => {
......
......@@ -3,3 +3,4 @@ export const UPDATE_SETTINGS = 'UPDATE_SETTINGS';
export const TOGGLE_LOADING = 'TOGGLE_LOADING';
export const SET_SETTINGS = 'SET_SETTINGS';
export const RESET_SETTINGS = 'RESET_SETTINGS';
export const SET_IS_DISABLED = 'SET_IS_DISABLED';
......@@ -16,6 +16,9 @@ export default {
state.settings = settings;
state.original = Object.freeze(settings);
},
[types.SET_IS_DISABLED](state, isDisabled) {
state.isDisabled = isDisabled;
},
[types.RESET_SETTINGS](state) {
state.settings = { ...state.original };
},
......
......@@ -7,6 +7,10 @@ export default () => ({
* Boolean to determine if the UI is loading data from the API
*/
isLoading: false,
/*
* Boolean to determine if the user is allowed to interact with the form
*/
isDisabled: false,
/*
* This contains the data shown and manipulated in the UI
* Has the following structure:
......
......@@ -5056,6 +5056,9 @@ msgstr ""
msgid "ContainerRegistry|Copy push command"
msgstr ""
msgid "ContainerRegistry|Currently, the Container Registry tag expiration feature is not available for projects created before GitLab version 12.8. For updates and more information, visit Issue %{linkStart}#196124%{linkEnd}"
msgstr ""
msgid "ContainerRegistry|Docker connection error"
msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import { GlAlert } from '@gitlab/ui';
import component from '~/registry/settings/components/registry_settings_app.vue';
import SettingsForm from '~/registry/settings/components/settings_form.vue';
import { createStore } from '~/registry/settings/store/';
import { SET_IS_DISABLED } from '~/registry/settings/store/mutation_types';
import { FETCH_SETTINGS_ERROR_MESSAGE } from '~/registry/settings/constants';
describe('Registry Settings App', () => {
let wrapper;
let store;
const findSettingsComponent = () => wrapper.find({ ref: 'settings-form' });
const findSettingsComponent = () => wrapper.find(SettingsForm);
const findAlert = () => wrapper.find(GlAlert);
const mountComponent = ({ dispatchMock } = {}) => {
const mountComponent = ({ dispatchMock = 'mockResolvedValue', isDisabled = false } = {}) => {
store = createStore();
store.commit(SET_IS_DISABLED, isDisabled);
const dispatchSpy = jest.spyOn(store, 'dispatch');
if (dispatchMock) {
dispatchSpy[dispatchMock]();
......@@ -30,12 +35,12 @@ describe('Registry Settings App', () => {
});
it('renders', () => {
mountComponent({ dispatchMock: 'mockResolvedValue' });
mountComponent();
expect(wrapper.element).toMatchSnapshot();
});
it('call the store function to load the data on mount', () => {
mountComponent({ dispatchMock: 'mockResolvedValue' });
mountComponent();
expect(store.dispatch).toHaveBeenCalledWith('fetchSettings');
});
......@@ -49,7 +54,21 @@ describe('Registry Settings App', () => {
});
it('renders the setting form', () => {
mountComponent({ dispatchMock: 'mockResolvedValue' });
mountComponent();
expect(findSettingsComponent().exists()).toBe(true);
});
describe('isDisabled', () => {
beforeEach(() => {
mountComponent({ isDisabled: true });
});
it('the form is hidden', () => {
expect(findSettingsComponent().exists()).toBe(false);
});
it('shows an alert', () => {
expect(findAlert().exists()).toBe(true);
});
});
});
......@@ -5,18 +5,38 @@ import * as types from '~/registry/settings/store/mutation_types';
describe('Actions Registry Store', () => {
describe.each`
actionName | mutationName | payload
${'setInitialState'} | ${types.SET_INITIAL_STATE} | ${'foo'}
${'updateSettings'} | ${types.UPDATE_SETTINGS} | ${'foo'}
${'receiveSettingsSuccess'} | ${types.SET_SETTINGS} | ${'foo'}
${'toggleLoading'} | ${types.TOGGLE_LOADING} | ${undefined}
${'resetSettings'} | ${types.RESET_SETTINGS} | ${undefined}
actionName | mutationName | payload
${'setInitialState'} | ${types.SET_INITIAL_STATE} | ${'foo'}
${'updateSettings'} | ${types.UPDATE_SETTINGS} | ${'foo'}
${'toggleLoading'} | ${types.TOGGLE_LOADING} | ${undefined}
${'resetSettings'} | ${types.RESET_SETTINGS} | ${undefined}
`('%s action invokes %s mutation with payload %s', ({ actionName, mutationName, payload }) => {
it('should set the initial state', done => {
testAction(actions[actionName], payload, {}, [{ type: mutationName, payload }], [], done);
});
});
describe('receiveSettingsSuccess', () => {
it('calls SET_SETTINGS when data is present', () => {
testAction(
actions.receiveSettingsSuccess,
'foo',
{},
[{ type: types.SET_SETTINGS, payload: 'foo' }],
[],
);
});
it('calls SET_IS_DISABLED when data is not present', () => {
testAction(
actions.receiveSettingsSuccess,
null,
{},
[{ type: types.SET_IS_DISABLED, payload: true }],
[],
);
});
});
describe('fetchSettings', () => {
const state = {
projectId: 'bar',
......
......@@ -32,6 +32,7 @@ describe('Mutations Registry Store', () => {
expect(mockState.settings).toEqual(expectedState.settings);
});
});
describe('SET_SETTINGS', () => {
it('should set the settings and original', () => {
const payload = { foo: 'baz' };
......@@ -41,6 +42,7 @@ describe('Mutations Registry Store', () => {
expect(mockState.original).toEqual(expectedState.settings);
});
});
describe('RESET_SETTINGS', () => {
it('should copy original over settings', () => {
mockState.settings = { foo: 'bar' };
......@@ -49,10 +51,18 @@ describe('Mutations Registry Store', () => {
expect(mockState.settings).toEqual(mockState.original);
});
});
describe('TOGGLE_LOADING', () => {
it('should toggle the loading', () => {
mutations[types.TOGGLE_LOADING](mockState);
expect(mockState.isLoading).toEqual(true);
});
});
describe('SET_IS_DISABLED', () => {
it('should set isDisabled', () => {
mutations[types.SET_IS_DISABLED](mockState, true);
expect(mockState.isDisabled).toEqual(true);
});
});
});
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