202 lines
6 KiB
JavaScript
202 lines
6 KiB
JavaScript
import { GlToggle, GlBadge } from '@gitlab/ui';
|
|
import { shallowMount } from '@vue/test-utils';
|
|
import { nextTick } from 'vue';
|
|
import { trimText } from 'helpers/text_helper';
|
|
import { mockTracking } from 'helpers/tracking_helper';
|
|
import FeatureFlagsTable from '~/feature_flags/components/feature_flags_table.vue';
|
|
import {
|
|
ROLLOUT_STRATEGY_ALL_USERS,
|
|
ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
|
|
ROLLOUT_STRATEGY_USER_ID,
|
|
ROLLOUT_STRATEGY_GITLAB_USER_LIST,
|
|
} from '~/feature_flags/constants';
|
|
|
|
const getDefaultProps = () => ({
|
|
featureFlags: [
|
|
{
|
|
id: 1,
|
|
iid: 1,
|
|
active: true,
|
|
name: 'flag name',
|
|
description: 'flag description',
|
|
destroy_path: 'destroy/path',
|
|
edit_path: 'edit/path',
|
|
scopes: [],
|
|
strategies: [
|
|
{
|
|
name: ROLLOUT_STRATEGY_ALL_USERS,
|
|
parameters: {},
|
|
scopes: [{ environment_scope: '*' }],
|
|
},
|
|
{
|
|
name: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
|
|
parameters: { percentage: '50' },
|
|
scopes: [{ environment_scope: 'production' }, { environment_scope: 'staging' }],
|
|
},
|
|
{
|
|
name: ROLLOUT_STRATEGY_USER_ID,
|
|
parameters: { userIds: '1,2,3,4' },
|
|
scopes: [{ environment_scope: 'review/*' }],
|
|
},
|
|
{
|
|
name: ROLLOUT_STRATEGY_GITLAB_USER_LIST,
|
|
parameters: {},
|
|
user_list: { name: 'test list' },
|
|
scopes: [{ environment_scope: '*' }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
});
|
|
|
|
describe('Feature flag table', () => {
|
|
let wrapper;
|
|
let props;
|
|
let badges;
|
|
|
|
const createWrapper = (propsData, opts = {}) => {
|
|
wrapper = shallowMount(FeatureFlagsTable, {
|
|
propsData,
|
|
provide: {
|
|
csrfToken: 'fakeToken',
|
|
},
|
|
...opts,
|
|
});
|
|
};
|
|
|
|
beforeEach(() => {
|
|
props = getDefaultProps();
|
|
createWrapper(props, {
|
|
provide: { csrfToken: 'fakeToken' },
|
|
});
|
|
|
|
badges = wrapper.findAll('[data-testid="strategy-badge"]');
|
|
});
|
|
|
|
beforeEach(() => {
|
|
props = getDefaultProps();
|
|
});
|
|
|
|
afterEach(() => {
|
|
wrapper.destroy();
|
|
wrapper = null;
|
|
});
|
|
|
|
describe('with an active scope and a standard rollout strategy', () => {
|
|
beforeEach(() => {
|
|
createWrapper(props);
|
|
});
|
|
|
|
it('Should render a table', () => {
|
|
expect(wrapper.classes('table-holder')).toBe(true);
|
|
});
|
|
|
|
it('Should render rows', () => {
|
|
expect(wrapper.find('.gl-responsive-table-row').exists()).toBe(true);
|
|
});
|
|
|
|
it('should render an ID column', () => {
|
|
expect(wrapper.find('.js-feature-flag-id').exists()).toBe(true);
|
|
expect(trimText(wrapper.find('.js-feature-flag-id').text())).toEqual('^1');
|
|
});
|
|
|
|
it('Should render a status column', () => {
|
|
const badge = wrapper.find('[data-testid="feature-flag-status-badge"]');
|
|
|
|
expect(badge.exists()).toBe(true);
|
|
expect(trimText(badge.text())).toEqual('Active');
|
|
});
|
|
|
|
it('Should render a feature flag column', () => {
|
|
expect(wrapper.find('.js-feature-flag-title').exists()).toBe(true);
|
|
expect(trimText(wrapper.find('.feature-flag-name').text())).toEqual('flag name');
|
|
|
|
expect(trimText(wrapper.find('.feature-flag-description').text())).toEqual(
|
|
'flag description',
|
|
);
|
|
});
|
|
|
|
it('should render an environments specs badge with active class', () => {
|
|
const envColumn = wrapper.find('.js-feature-flag-environments');
|
|
|
|
expect(trimText(envColumn.findComponent(GlBadge).text())).toBe('All Users: All Environments');
|
|
});
|
|
|
|
it('should render an actions column', () => {
|
|
expect(wrapper.find('.table-action-buttons').exists()).toBe(true);
|
|
expect(wrapper.find('.js-feature-flag-delete-button').exists()).toBe(true);
|
|
expect(wrapper.find('.js-feature-flag-edit-button').exists()).toBe(true);
|
|
expect(wrapper.find('.js-feature-flag-edit-button').attributes('href')).toEqual('edit/path');
|
|
});
|
|
});
|
|
|
|
describe('when active and with an update toggle', () => {
|
|
let toggle;
|
|
let spy;
|
|
|
|
beforeEach(() => {
|
|
props.featureFlags[0].update_path = props.featureFlags[0].destroy_path;
|
|
createWrapper(props);
|
|
toggle = wrapper.findComponent(GlToggle);
|
|
spy = mockTracking('_category_', toggle.element, jest.spyOn);
|
|
});
|
|
|
|
it('should have a toggle', () => {
|
|
expect(toggle.exists()).toBe(true);
|
|
expect(toggle.props()).toMatchObject({
|
|
label: FeatureFlagsTable.i18n.toggleLabel,
|
|
value: true,
|
|
});
|
|
});
|
|
|
|
it('should trigger a toggle event', async () => {
|
|
toggle.vm.$emit('change');
|
|
const flag = { ...props.featureFlags[0], active: !props.featureFlags[0].active };
|
|
|
|
await nextTick();
|
|
expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]);
|
|
});
|
|
|
|
it('tracks a click', () => {
|
|
toggle.trigger('click');
|
|
|
|
expect(spy).toHaveBeenCalledWith('_category_', 'click_button', {
|
|
label: 'feature_flag_toggle',
|
|
});
|
|
});
|
|
});
|
|
|
|
it('shows All Environments if the environment scope is *', () => {
|
|
expect(badges.at(0).text()).toContain('All Environments');
|
|
});
|
|
|
|
it('shows the environment scope if another is set', () => {
|
|
expect(badges.at(1).text()).toContain('production');
|
|
expect(badges.at(1).text()).toContain('staging');
|
|
expect(badges.at(2).text()).toContain('review/*');
|
|
});
|
|
|
|
it('shows All Users for the default strategy', () => {
|
|
expect(badges.at(0).text()).toContain('All Users');
|
|
});
|
|
|
|
it('shows the percent for a percent rollout', () => {
|
|
expect(badges.at(1).text()).toContain('Percent of users - 50%');
|
|
});
|
|
|
|
it('shows the number of users for users with ID', () => {
|
|
expect(badges.at(2).text()).toContain('User IDs - 4 users');
|
|
});
|
|
|
|
it('shows the name of a user list for user list', () => {
|
|
expect(badges.at(3).text()).toContain('User List - test list');
|
|
});
|
|
|
|
it('renders a feature flag without an iid', () => {
|
|
delete props.featureFlags[0].iid;
|
|
createWrapper(props);
|
|
|
|
expect(wrapper.find('.js-feature-flag-id').exists()).toBe(true);
|
|
expect(trimText(wrapper.find('.js-feature-flag-id').text())).toBe('');
|
|
});
|
|
});
|