debian-mirror-gitlab/spec/frontend/feature_flags/components/feature_flags_table_spec.js
2021-03-11 19:13:27 +05:30

270 lines
8.1 KiB
JavaScript

import { GlToggle, GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
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,
NEW_VERSION_FLAG,
LEGACY_FLAG,
DEFAULT_PERCENT_ROLLOUT,
} 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',
version: LEGACY_FLAG,
scopes: [
{
id: 1,
active: true,
environmentScope: 'scope',
canUpdate: true,
protected: false,
rolloutStrategy: ROLLOUT_STRATEGY_ALL_USERS,
rolloutPercentage: DEFAULT_PERCENT_ROLLOUT,
shouldBeDestroyed: false,
},
],
},
],
});
describe('Feature flag table', () => {
let wrapper;
let props;
const createWrapper = (propsData, opts = {}) => {
wrapper = shallowMount(FeatureFlagsTable, {
propsData,
provide: {
csrfToken: 'fakeToken',
},
...opts,
});
};
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 column', () => {
const envColumn = wrapper.find('.js-feature-flag-environments');
expect(envColumn).toBeDefined();
expect(trimText(envColumn.text())).toBe('scope');
});
it('should render an environments specs badge with active class', () => {
const envColumn = wrapper.find('.js-feature-flag-environments');
expect(trimText(envColumn.find(GlBadge).text())).toBe('scope');
});
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;
beforeEach(() => {
props.featureFlags[0].update_path = props.featureFlags[0].destroy_path;
createWrapper(props);
toggle = wrapper.find(GlToggle);
});
it('should have a toggle', () => {
expect(toggle.exists()).toBe(true);
expect(toggle.props('value')).toBe(true);
});
it('should trigger a toggle event', () => {
toggle.vm.$emit('change');
const flag = { ...props.featureFlags[0], active: !props.featureFlags[0].active };
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]);
});
});
});
describe('with an active scope and a percentage rollout strategy', () => {
beforeEach(() => {
props.featureFlags[0].scopes[0].rolloutStrategy = ROLLOUT_STRATEGY_PERCENT_ROLLOUT;
props.featureFlags[0].scopes[0].rolloutPercentage = '54';
createWrapper(props);
});
it('should render an environments specs badge with percentage', () => {
const envColumn = wrapper.find('.js-feature-flag-environments');
expect(trimText(envColumn.find(GlBadge).text())).toBe('scope: 54%');
});
});
describe('with an inactive scope', () => {
beforeEach(() => {
props.featureFlags[0].scopes[0].active = false;
createWrapper(props);
});
it('should render an environments specs badge with inactive class', () => {
const envColumn = wrapper.find('.js-feature-flag-environments');
expect(trimText(envColumn.find(GlBadge).text())).toBe('scope');
});
});
describe('with a new version flag', () => {
let toggle;
let spy;
let badges;
beforeEach(() => {
const newVersionProps = {
...props,
featureFlags: [
{
id: 1,
iid: 1,
active: true,
name: 'flag name',
description: 'flag description',
destroy_path: 'destroy/path',
edit_path: 'edit/path',
update_path: 'update/path',
version: NEW_VERSION_FLAG,
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: '*' }],
},
],
},
],
};
createWrapper(newVersionProps, {
provide: { csrfToken: 'fakeToken', glFeatures: { featureFlagsNewVersion: true } },
});
toggle = wrapper.find(GlToggle);
spy = mockTracking('_category_', toggle.element, jest.spyOn);
badges = wrapper.findAll('[data-testid="strategy-badge"]');
});
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('tracks a click', () => {
toggle.trigger('click');
expect(spy).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'feature_flag_toggle',
});
});
});
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('');
});
});