summaryrefslogtreecommitdiff
path: root/spec/frontend/feature_flags/components/form_spec.js
blob: c0f9638390a10b30d5fe819b5c7f7ef8f341c0d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import Api from '~/api';
import Form from '~/feature_flags/components/form.vue';
import Strategy from '~/feature_flags/components/strategy.vue';
import {
  ROLLOUT_STRATEGY_ALL_USERS,
  ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
} from '~/feature_flags/constants';
import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue';
import { featureFlag, userList, allUsersStrategy } from '../mock_data';

jest.mock('~/api.js');

describe('feature flag form', () => {
  let wrapper;
  const requiredProps = {
    cancelPath: 'feature_flags',
    submitText: 'Create',
  };

  const requiredInjections = {
    environmentsEndpoint: '/environments.json',
    projectId: '1',
  };

  const factory = (props = {}, provide = {}) => {
    wrapper = extendedWrapper(
      shallowMount(Form, {
        propsData: { ...requiredProps, ...props },
        provide: {
          ...requiredInjections,
          ...provide,
        },
      }),
    );
  };

  beforeEach(() => {
    Api.fetchFeatureFlagUserLists.mockResolvedValue({ data: [] });
  });

  afterEach(() => {
    wrapper.destroy();
  });

  it('should render provided submitText', () => {
    factory(requiredProps);

    expect(wrapper.find('.js-ff-submit').text()).toEqual(requiredProps.submitText);
  });

  it('should render provided cancelPath', () => {
    factory(requiredProps);

    expect(wrapper.find('.js-ff-cancel').attributes('href')).toEqual(requiredProps.cancelPath);
  });

  it('does not render the related issues widget without the featureFlagIssuesEndpoint', () => {
    factory(requiredProps);

    expect(wrapper.find(RelatedIssuesRoot).exists()).toBe(false);
  });

  it('renders the related issues widget when the featureFlagIssuesEndpoint is provided', () => {
    factory(
      {},
      {
        ...requiredInjections,
        featureFlagIssuesEndpoint: '/some/endpoint',
      },
    );

    expect(wrapper.find(RelatedIssuesRoot).exists()).toBe(true);
  });

  describe('without provided data', () => {
    beforeEach(() => {
      factory(requiredProps);
    });

    it('should render name input text', () => {
      expect(wrapper.find('#feature-flag-name').exists()).toBe(true);
    });

    it('should render description textarea', () => {
      expect(wrapper.find('#feature-flag-description').exists()).toBe(true);
    });
  });

  describe('with strategies', () => {
    beforeEach(() => {
      Api.fetchFeatureFlagUserLists.mockResolvedValue({ data: [userList] });
      factory({
        ...requiredProps,
        name: featureFlag.name,
        description: featureFlag.description,
        active: true,
        strategies: [
          {
            type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
            parameters: { percentage: '30' },
            scopes: [],
          },
          {
            type: ROLLOUT_STRATEGY_ALL_USERS,
            parameters: {},
            scopes: [{ environment_scope: 'review/*' }],
          },
        ],
      });
    });

    it('should show the strategy component', () => {
      const strategy = wrapper.find(Strategy);
      expect(strategy.exists()).toBe(true);
      expect(strategy.props('strategy')).toEqual({
        type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
        parameters: { percentage: '30' },
        scopes: [],
      });
    });

    it('should show one strategy component per strategy', () => {
      expect(wrapper.findAll(Strategy)).toHaveLength(2);
    });

    it('adds an all users strategy when clicking the Add button', () => {
      wrapper.find(GlButton).vm.$emit('click');

      return wrapper.vm.$nextTick().then(() => {
        const strategies = wrapper.findAll(Strategy);

        expect(strategies).toHaveLength(3);
        expect(strategies.at(2).props('strategy')).toEqual(allUsersStrategy);
      });
    });

    it('should remove a strategy on delete', () => {
      const strategy = {
        type: ROLLOUT_STRATEGY_PERCENT_ROLLOUT,
        parameters: { percentage: '30' },
        scopes: [],
      };
      wrapper.find(Strategy).vm.$emit('delete');
      return wrapper.vm.$nextTick().then(() => {
        expect(wrapper.findAll(Strategy)).toHaveLength(1);
        expect(wrapper.find(Strategy).props('strategy')).not.toEqual(strategy);
      });
    });
  });
});