diff options
Diffstat (limited to 'spec/frontend/feature_flags/components/feature_flags_spec.js')
-rw-r--r-- | spec/frontend/feature_flags/components/feature_flags_spec.js | 145 |
1 files changed, 48 insertions, 97 deletions
diff --git a/spec/frontend/feature_flags/components/feature_flags_spec.js b/spec/frontend/feature_flags/components/feature_flags_spec.js index b519aab0dc4..db4bdc736de 100644 --- a/spec/frontend/feature_flags/components/feature_flags_spec.js +++ b/spec/frontend/feature_flags/components/feature_flags_spec.js @@ -1,19 +1,17 @@ -import { GlAlert, GlEmptyState, GlLoadingIcon, GlSprintf } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui'; +import { mount, createLocalVue } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import Vuex from 'vuex'; +import waitForPromises from 'helpers/wait_for_promises'; import { TEST_HOST } from 'spec/test_constants'; -import Api from '~/api'; import ConfigureFeatureFlagsModal from '~/feature_flags/components/configure_feature_flags_modal.vue'; +import EmptyState from '~/feature_flags/components/empty_state.vue'; import FeatureFlagsComponent from '~/feature_flags/components/feature_flags.vue'; -import FeatureFlagsTab from '~/feature_flags/components/feature_flags_tab.vue'; import FeatureFlagsTable from '~/feature_flags/components/feature_flags_table.vue'; -import UserListsTable from '~/feature_flags/components/user_lists_table.vue'; -import { FEATURE_FLAG_SCOPE, USER_LIST_SCOPE } from '~/feature_flags/constants'; import createStore from '~/feature_flags/store/index'; import axios from '~/lib/utils/axios_utils'; import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue'; -import { getRequestData, userList } from '../mock_data'; +import { getRequestData } from '../mock_data'; const localVue = createLocalVue(); localVue.use(Vuex); @@ -28,7 +26,7 @@ describe('Feature flags', () => { featureFlagsLimit: '200', featureFlagsLimitExceeded: false, newFeatureFlagPath: 'feature-flags/new', - newUserListPath: '/user-list/new', + userListPath: '/user-list', unleashApiUrl: `${TEST_HOST}/api/unleash`, projectName: 'fakeProjectName', errorStateSvgPath: '/assets/illustrations/feature_flag.svg', @@ -44,36 +42,25 @@ describe('Feature flags', () => { let mock; let store; - const factory = (provide = mockData, fn = shallowMount) => { + const factory = (provide = mockData, fn = mount) => { store = createStore(mockState); wrapper = fn(FeatureFlagsComponent, { localVue, store, provide, stubs: { - FeatureFlagsTab, + EmptyState, }, }); }; const configureButton = () => wrapper.find('[data-testid="ff-configure-button"]'); const newButton = () => wrapper.find('[data-testid="ff-new-button"]'); - const newUserListButton = () => wrapper.find('[data-testid="ff-new-list-button"]'); - const limitAlert = () => wrapper.find(GlAlert); + const userListButton = () => wrapper.find('[data-testid="ff-user-list-button"]'); + const limitAlert = () => wrapper.findComponent(GlAlert); beforeEach(() => { mock = new MockAdapter(axios); - jest.spyOn(Api, 'fetchFeatureFlagUserLists').mockResolvedValue({ - data: [userList], - headers: { - 'x-next-page': '2', - 'x-page': '1', - 'X-Per-Page': '8', - 'X-Prev-Page': '', - 'X-TOTAL': '40', - 'X-Total-Pages': '5', - }, - }); }); afterEach(() => { @@ -87,7 +74,7 @@ describe('Feature flags', () => { beforeEach((done) => { mock - .onGet(`${TEST_HOST}/endpoint.json`, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) + .onGet(`${TEST_HOST}/endpoint.json`, { params: { page: '1' } }) .reply(200, getRequestData, {}); factory(provideData); setImmediate(done); @@ -101,9 +88,7 @@ describe('Feature flags', () => { it('shows a feature flags limit reached alert', () => { expect(limitAlert().exists()).toBe(true); - expect(limitAlert().find(GlSprintf).attributes('message')).toContain( - 'Feature flags limit reached', - ); + expect(limitAlert().text()).toContain('Feature flags limit reached'); }); describe('when the alert is dismissed', () => { @@ -129,12 +114,12 @@ describe('Feature flags', () => { canUserConfigure: false, canUserRotateToken: false, newFeatureFlagPath: null, - newUserListPath: null, + userListPath: null, }; beforeEach((done) => { mock - .onGet(`${TEST_HOST}/endpoint.json`, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) + .onGet(`${TEST_HOST}/endpoint.json`, { params: { page: '1' } }) .reply(200, getRequestData, {}); factory(provideData); setImmediate(done); @@ -148,20 +133,20 @@ describe('Feature flags', () => { expect(newButton().exists()).toBe(false); }); - it('does not render new user list button', () => { - expect(newUserListButton().exists()).toBe(false); + it('does not render view user list button', () => { + expect(userListButton().exists()).toBe(false); }); }); describe('loading state', () => { it('renders a loading icon', () => { mock - .onGet(`${TEST_HOST}/endpoint.json`, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) + .onGet(`${TEST_HOST}/endpoint.json`, { params: { page: '1' } }) .replyOnce(200, getRequestData, {}); factory(); - const loadingElement = wrapper.find(GlLoadingIcon); + const loadingElement = wrapper.findComponent(GlLoadingIcon); expect(loadingElement.exists()).toBe(true); expect(loadingElement.props('label')).toEqual('Loading feature flags'); @@ -173,7 +158,7 @@ describe('Feature flags', () => { let emptyState; beforeEach(async () => { - mock.onGet(mockState.endpoint, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }).reply( + mock.onGet(mockState.endpoint, { params: { page: '1' } }).reply( 200, { feature_flags: [], @@ -187,9 +172,10 @@ describe('Feature flags', () => { ); factory(); + await waitForPromises(); await wrapper.vm.$nextTick(); - emptyState = wrapper.find(GlEmptyState); + emptyState = wrapper.findComponent(GlEmptyState); }); it('should render the empty state', async () => { @@ -204,9 +190,9 @@ describe('Feature flags', () => { expect(newButton().exists()).toBe(true); }); - it('renders new user list button', () => { - expect(newUserListButton().exists()).toBe(true); - expect(newUserListButton().attributes('href')).toBe('/user-list/new'); + it('renders view user list button', () => { + expect(userListButton().exists()).toBe(true); + expect(userListButton().attributes('href')).toBe(mockData.userListPath); }); describe('in feature flags tab', () => { @@ -218,16 +204,14 @@ describe('Feature flags', () => { describe('with paginated feature flags', () => { beforeEach((done) => { - mock - .onGet(mockState.endpoint, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) - .replyOnce(200, getRequestData, { - 'x-next-page': '2', - 'x-page': '1', - 'X-Per-Page': '2', - 'X-Prev-Page': '', - 'X-TOTAL': '37', - 'X-Total-Pages': '5', - }); + mock.onGet(mockState.endpoint, { params: { page: '1' } }).replyOnce(200, getRequestData, { + 'x-next-page': '2', + 'x-page': '1', + 'X-Per-Page': '2', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '5', + }); factory(); jest.spyOn(store, 'dispatch'); @@ -235,9 +219,9 @@ describe('Feature flags', () => { }); it('should render a table with feature flags', () => { - const table = wrapper.find(FeatureFlagsTable); + const table = wrapper.findComponent(FeatureFlagsTable); expect(table.exists()).toBe(true); - expect(table.props(FEATURE_FLAG_SCOPE)).toEqual( + expect(table.props('featureFlags')).toEqual( expect.arrayContaining([ expect.objectContaining({ name: getRequestData.feature_flags[0].name, @@ -248,9 +232,9 @@ describe('Feature flags', () => { }); it('should toggle a flag when receiving the toggle-flag event', () => { - const table = wrapper.find(FeatureFlagsTable); + const table = wrapper.findComponent(FeatureFlagsTable); - const [flag] = table.props(FEATURE_FLAG_SCOPE); + const [flag] = table.props('featureFlags'); table.vm.$emit('toggle-flag', flag); expect(store.dispatch).toHaveBeenCalledWith('toggleFeatureFlag', flag); @@ -264,71 +248,38 @@ describe('Feature flags', () => { expect(newButton().exists()).toBe(true); }); - it('renders new user list button', () => { - expect(newUserListButton().exists()).toBe(true); - expect(newUserListButton().attributes('href')).toBe('/user-list/new'); + it('renders view user list button', () => { + expect(userListButton().exists()).toBe(true); + expect(userListButton().attributes('href')).toBe(mockData.userListPath); }); describe('pagination', () => { it('should render pagination', () => { - expect(wrapper.find(TablePagination).exists()).toBe(true); + expect(wrapper.findComponent(TablePagination).exists()).toBe(true); }); it('should make an API request when page is clicked', () => { jest.spyOn(wrapper.vm, 'updateFeatureFlagOptions'); - wrapper.find(TablePagination).vm.change(4); + wrapper.findComponent(TablePagination).vm.change(4); expect(wrapper.vm.updateFeatureFlagOptions).toHaveBeenCalledWith({ - scope: FEATURE_FLAG_SCOPE, page: '4', }); }); - - it('should make an API request when using tabs', () => { - jest.spyOn(wrapper.vm, 'updateFeatureFlagOptions'); - wrapper.find('[data-testid="user-lists-tab"]').vm.$emit('changeTab'); - - expect(wrapper.vm.updateFeatureFlagOptions).toHaveBeenCalledWith({ - scope: USER_LIST_SCOPE, - page: '1', - }); - }); - }); - }); - - describe('in user lists tab', () => { - beforeEach((done) => { - factory(); - setImmediate(done); - }); - beforeEach(() => { - wrapper.find('[data-testid="user-lists-tab"]').vm.$emit('changeTab'); - return wrapper.vm.$nextTick(); - }); - - it('should display the user list table', () => { - expect(wrapper.find(UserListsTable).exists()).toBe(true); - }); - - it('should set the user lists to display', () => { - expect(wrapper.find(UserListsTable).props('userLists')).toEqual([userList]); }); }); }); describe('unsuccessful request', () => { beforeEach((done) => { - mock - .onGet(mockState.endpoint, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) - .replyOnce(500, {}); - Api.fetchFeatureFlagUserLists.mockRejectedValueOnce(); + mock.onGet(mockState.endpoint, { params: { page: '1' } }).replyOnce(500, {}); factory(); setImmediate(done); }); it('should render error state', () => { - const emptyState = wrapper.find(GlEmptyState); + const emptyState = wrapper.findComponent(GlEmptyState); expect(emptyState.props('title')).toEqual('There was an error fetching the feature flags.'); expect(emptyState.props('description')).toEqual( 'Try again in a few moments or contact your support team.', @@ -343,16 +294,16 @@ describe('Feature flags', () => { expect(newButton().exists()).toBe(true); }); - it('renders new user list button', () => { - expect(newUserListButton().exists()).toBe(true); - expect(newUserListButton().attributes('href')).toBe('/user-list/new'); + it('renders view user list button', () => { + expect(userListButton().exists()).toBe(true); + expect(userListButton().attributes('href')).toBe(mockData.userListPath); }); }); describe('rotate instance id', () => { beforeEach((done) => { mock - .onGet(`${TEST_HOST}/endpoint.json`, { params: { scope: FEATURE_FLAG_SCOPE, page: '1' } }) + .onGet(`${TEST_HOST}/endpoint.json`, { params: { page: '1' } }) .reply(200, getRequestData, {}); factory(); setImmediate(done); @@ -360,7 +311,7 @@ describe('Feature flags', () => { it('should fire the rotate action when a `token` event is received', () => { const actionSpy = jest.spyOn(wrapper.vm, 'rotateInstanceId'); - const modal = wrapper.find(ConfigureFeatureFlagsModal); + const modal = wrapper.findComponent(ConfigureFeatureFlagsModal); modal.vm.$emit('token'); expect(actionSpy).toHaveBeenCalled(); |