From 4c016ad02422709d3a341215952a9b1cdb4a8451 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 30 Oct 2019 00:07:52 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- ...age_with_external_authorization_service_spec.rb | 4 +- spec/features/groups_spec.rb | 18 ++- .../projects/settings/operations_settings_spec.rb | 35 ++++++ spec/frontend/fixtures/static/signin_tabs.html | 3 + .../__snapshots__/grafana_integration_spec.js.snap | 92 +++++++++++++++ .../components/grafana_integration_spec.js | 124 +++++++++++++++++++++ .../grafana_integration/store/mutations_spec.js | 28 +++++ spec/javascripts/signin_tabs_memoizer_spec.js | 46 ++++++++ spec/javascripts/test_bundle.js | 33 +----- .../cycle_analytics/project_stage_spec.rb | 10 +- .../_confirm_rollback_modal_spec.html_spec.rb | 2 +- 11 files changed, 357 insertions(+), 38 deletions(-) create mode 100644 spec/frontend/grafana_integration/components/__snapshots__/grafana_integration_spec.js.snap create mode 100644 spec/frontend/grafana_integration/components/grafana_integration_spec.js create mode 100644 spec/frontend/grafana_integration/store/mutations_spec.js (limited to 'spec') diff --git a/spec/features/groups/group_page_with_external_authorization_service_spec.rb b/spec/features/groups/group_page_with_external_authorization_service_spec.rb index c05c3f4f3d6..823c8cc8fad 100644 --- a/spec/features/groups/group_page_with_external_authorization_service_spec.rb +++ b/spec/features/groups/group_page_with_external_authorization_service_spec.rb @@ -15,7 +15,7 @@ describe 'The group page' do def expect_all_sidebar_links within('.nav-sidebar') do - expect(page).to have_link('Overview') + expect(page).to have_link('Group overview') expect(page).to have_link('Details') expect(page).to have_link('Activity') expect(page).to have_link('Issues') @@ -44,7 +44,7 @@ describe 'The group page' do visit group_path(group) within('.nav-sidebar') do - expect(page).to have_link('Overview') + expect(page).to have_link('Group overview') expect(page).to have_link('Details') expect(page).not_to have_link('Activity') expect(page).not_to have_link('Contribution Analytics') diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 4fd241dedd1..e958ebb1275 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -237,14 +237,28 @@ describe 'Group' do let!(:group) { create(:group) } let!(:nested_group) { create(:group, parent: group) } let!(:project) { create(:project, namespace: group) } - let!(:path) { group_path(group) } it 'renders projects and groups on the page' do - visit path + visit group_path(group) wait_for_requests expect(page).to have_content(nested_group.name) expect(page).to have_content(project.name) + expect(page).to have_link('Group overview') + end + + it 'renders subgroup page with the text "Subgroup overview"' do + visit group_path(nested_group) + wait_for_requests + + expect(page).to have_link('Subgroup overview') + end + + it 'renders project page with the text "Project overview"' do + visit project_path(project) + wait_for_requests + + expect(page).to have_link('Project overview') end end diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb index d96e243d96b..ca937651af8 100644 --- a/spec/features/projects/settings/operations_settings_spec.rb +++ b/spec/features/projects/settings/operations_settings_spec.rb @@ -102,5 +102,40 @@ describe 'Projects > Settings > For a forked project', :js do end end end + + context 'grafana integration settings form' do + it 'is not present when the feature flag is disabled' do + stub_feature_flags(gfm_grafana_integration: false) + + visit project_settings_operations_path(project) + + wait_for_requests + + expect(page).to have_no_css('.js-grafana-integration') + end + + it 'is present when the feature flag is enabled' do + visit project_settings_operations_path(project) + + wait_for_requests + + within '.js-grafana-integration' do + click_button('Expand') + end + + expect(page).to have_content('Grafana URL') + expect(page).to have_content('API Token') + expect(page).to have_button('Save Changes') + + fill_in('grafana-url', with: 'http://gitlab-test.grafana.net') + fill_in('grafana-token', with: 'token') + + click_button('Save Changes') + + wait_for_requests + + assert_text('Your changes have been saved') + end + end end end diff --git a/spec/frontend/fixtures/static/signin_tabs.html b/spec/frontend/fixtures/static/signin_tabs.html index 7e66ab9394b..247a6b03054 100644 --- a/spec/frontend/fixtures/static/signin_tabs.html +++ b/spec/frontend/fixtures/static/signin_tabs.html @@ -5,4 +5,7 @@
  • Standard
  • +
  • +Register +
  • diff --git a/spec/frontend/grafana_integration/components/__snapshots__/grafana_integration_spec.js.snap b/spec/frontend/grafana_integration/components/__snapshots__/grafana_integration_spec.js.snap new file mode 100644 index 00000000000..43239da344f --- /dev/null +++ b/spec/frontend/grafana_integration/components/__snapshots__/grafana_integration_spec.js.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`grafana integration component default state to match the default snapshot 1`] = ` +
    +
    +

    + + Grafana Authentication + +

    + + + Expand + + +

    + + Embed Grafana charts in GitLab issues. + +

    +
    + +
    +
    + + + + + + + +

    + + Enter the Grafana API Token. + + + + More information + + + +

    +
    + + + + Save Changes + + +
    +
    +
    +`; diff --git a/spec/frontend/grafana_integration/components/grafana_integration_spec.js b/spec/frontend/grafana_integration/components/grafana_integration_spec.js new file mode 100644 index 00000000000..594ea94dc6a --- /dev/null +++ b/spec/frontend/grafana_integration/components/grafana_integration_spec.js @@ -0,0 +1,124 @@ +import { mount, shallowMount } from '@vue/test-utils'; +import { GlButton } from '@gitlab/ui'; +import GrafanaIntegration from '~/grafana_integration/components/grafana_integration.vue'; +import { createStore } from '~/grafana_integration/store'; +import axios from '~/lib/utils/axios_utils'; +import { refreshCurrentPage } from '~/lib/utils/url_utility'; +import createFlash from '~/flash'; +import { TEST_HOST } from 'helpers/test_constants'; + +jest.mock('~/lib/utils/url_utility'); +jest.mock('~/flash'); + +describe('grafana integration component', () => { + let wrapper; + let store; + const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`; + const grafanaIntegrationUrl = `${TEST_HOST}`; + const grafanaIntegrationToken = 'someToken'; + + beforeEach(() => { + store = createStore({ + operationsSettingsEndpoint, + grafanaIntegrationUrl, + grafanaIntegrationToken, + }); + }); + + afterEach(() => { + if (wrapper.destroy) { + wrapper.destroy(); + createFlash.mockReset(); + refreshCurrentPage.mockReset(); + } + }); + + describe('default state', () => { + it('to match the default snapshot', () => { + wrapper = shallowMount(GrafanaIntegration, { store }); + + expect(wrapper.element).toMatchSnapshot(); + }); + }); + + it('renders header text', () => { + wrapper = shallowMount(GrafanaIntegration, { store }); + + expect(wrapper.find('.js-section-header').text()).toBe('Grafana Authentication'); + }); + + describe('expand/collapse button', () => { + it('renders as an expand button by default', () => { + wrapper = shallowMount(GrafanaIntegration, { store }); + + const button = wrapper.find(GlButton); + + expect(button.text()).toBe('Expand'); + }); + }); + + describe('sub-header', () => { + it('renders descriptive text', () => { + wrapper = shallowMount(GrafanaIntegration, { store }); + + expect(wrapper.find('.js-section-sub-header').text()).toContain( + 'Embed Grafana charts in GitLab issues.', + ); + }); + }); + + describe('form', () => { + beforeEach(() => { + jest.spyOn(axios, 'patch').mockImplementation(); + }); + + afterEach(() => { + axios.patch.mockReset(); + }); + + describe('submit button', () => { + const findSubmitButton = () => wrapper.find('.settings-content form').find(GlButton); + + const endpointRequest = [ + operationsSettingsEndpoint, + { + project: { + grafana_integration_attributes: { + grafana_url: grafanaIntegrationUrl, + token: grafanaIntegrationToken, + }, + }, + }, + ]; + + it('submits form on click', () => { + wrapper = mount(GrafanaIntegration, { store }); + axios.patch.mockResolvedValue(); + + findSubmitButton(wrapper).trigger('click'); + + expect(axios.patch).toHaveBeenCalledWith(...endpointRequest); + return wrapper.vm.$nextTick().then(() => expect(refreshCurrentPage).toHaveBeenCalled()); + }); + + it('creates flash banner on error', () => { + const message = 'mockErrorMessage'; + wrapper = mount(GrafanaIntegration, { store }); + axios.patch.mockRejectedValue({ response: { data: { message } } }); + + findSubmitButton().trigger('click'); + + expect(axios.patch).toHaveBeenCalledWith(...endpointRequest); + return wrapper.vm + .$nextTick() + .then(jest.runAllTicks) + .then(() => + expect(createFlash).toHaveBeenCalledWith( + `There was an error saving your changes. ${message}`, + 'alert', + ), + ); + }); + }); + }); +}); diff --git a/spec/frontend/grafana_integration/store/mutations_spec.js b/spec/frontend/grafana_integration/store/mutations_spec.js new file mode 100644 index 00000000000..d9b8c258623 --- /dev/null +++ b/spec/frontend/grafana_integration/store/mutations_spec.js @@ -0,0 +1,28 @@ +import mutations from '~/grafana_integration/store/mutations'; +import createState from '~/grafana_integration/store/state'; + +describe('grafana integration mutations', () => { + let localState; + + beforeEach(() => { + localState = createState(); + }); + + describe('SET_GRAFANA_URL', () => { + it('sets grafanaUrl', () => { + const mockUrl = 'mockUrl'; + mutations.SET_GRAFANA_URL(localState, mockUrl); + + expect(localState.grafanaUrl).toBe(mockUrl); + }); + }); + + describe('SET_GRAFANA_TOKEN', () => { + it('sets grafanaToken', () => { + const mockToken = 'mockToken'; + mutations.SET_GRAFANA_TOKEN(localState, mockToken); + + expect(localState.grafanaToken).toBe(mockToken); + }); + }); +}); diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js b/spec/javascripts/signin_tabs_memoizer_spec.js index ef5c774736b..966ae55ce14 100644 --- a/spec/javascripts/signin_tabs_memoizer_spec.js +++ b/spec/javascripts/signin_tabs_memoizer_spec.js @@ -1,5 +1,7 @@ import AccessorUtilities from '~/lib/utils/accessor'; import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer'; +import trackData from '~/pages/sessions/new/index'; +import Tracking from '~/tracking'; describe('SigninTabsMemoizer', () => { const fixtureTemplate = 'static/signin_tabs.html'; @@ -93,6 +95,50 @@ describe('SigninTabsMemoizer', () => { }); }); + describe('trackData', () => { + beforeEach(() => { + spyOn(Tracking, 'event'); + }); + + describe('with tracking data', () => { + beforeEach(() => { + gon.tracking_data = { + category: 'Growth::Acquisition::Experiment::SignUpFlow', + action: 'start', + label: 'uuid', + property: 'control_group', + }; + trackData(); + }); + + it('should track data when the "click" event of the register tab is triggered', () => { + document.querySelector('a[href="#register-pane"]').click(); + + expect(Tracking.event).toHaveBeenCalledWith( + 'Growth::Acquisition::Experiment::SignUpFlow', + 'start', + { + label: 'uuid', + property: 'control_group', + }, + ); + }); + }); + + describe('without tracking data', () => { + beforeEach(() => { + gon.tracking_data = undefined; + trackData(); + }); + + it('should not track data when the "click" event of the register tab is triggered', () => { + document.querySelector('a[href="#register-pane"]').click(); + + expect(Tracking.event).not.toHaveBeenCalled(); + }); + }); + }); + describe('saveData', () => { beforeEach(() => { memo = { diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index cb6b158f01c..859745ee9fc 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -171,38 +171,7 @@ describe('test errors', () => { // see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15 if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report - const troubleMakers = [ - './blob_edit/blob_bundle.js', - './boards/components/modal/empty_state.vue', - './boards/components/modal/footer.js', - './boards/components/modal/header.js', - './cycle_analytics/cycle_analytics_bundle.js', - './cycle_analytics/components/stage_plan_component.js', - './cycle_analytics/components/stage_staging_component.js', - './cycle_analytics/components/stage_test_component.js', - './commit/pipelines/pipelines_bundle.js', - './diff_notes/diff_notes_bundle.js', - './diff_notes/components/jump_to_discussion.js', - './diff_notes/components/resolve_count.js', - './dispatcher.js', - './environments/environments_bundle.js', - './graphs/graphs_bundle.js', - './issuable/time_tracking/time_tracking_bundle.js', - './main.js', - './merge_conflicts/merge_conflicts_bundle.js', - './merge_conflicts/components/inline_conflict_lines.js', - './merge_conflicts/components/parallel_conflict_lines.js', - './monitoring/monitoring_bundle.js', - './network/network_bundle.js', - './network/branch_graph.js', - './profile/profile_bundle.js', - './protected_branches/protected_branches_bundle.js', - './snippet/snippet_bundle.js', - './terminal/terminal_bundle.js', - './users/users_bundle.js', - './issue_show/index.js', - './pages/admin/application_settings/general/index.js', - ]; + const troubleMakers = ['./pages/admin/application_settings/general/index.js']; describe('Uncovered files', function() { const sourceFilesContexts = [require.context('~', true, /\.(js|vue)$/)]; diff --git a/spec/models/analytics/cycle_analytics/project_stage_spec.rb b/spec/models/analytics/cycle_analytics/project_stage_spec.rb index 83d6ff754c5..9d18618f638 100644 --- a/spec/models/analytics/cycle_analytics/project_stage_spec.rb +++ b/spec/models/analytics/cycle_analytics/project_stage_spec.rb @@ -16,8 +16,16 @@ describe Analytics::CycleAnalytics::ProjectStage do end end - it_behaves_like "cycle analytics stage" do + it_behaves_like 'cycle analytics stage' do let(:parent) { create(:project) } let(:parent_name) { :project } end + + context 'relative positioning' do + it_behaves_like 'a class that supports relative positioning' do + let(:project) { create(:project) } + let(:factory) { :cycle_analytics_project_stage } + let(:default_params) { { project: project } } + end + end end diff --git a/spec/views/projects/deployments/_confirm_rollback_modal_spec.html_spec.rb b/spec/views/projects/deployments/_confirm_rollback_modal_spec.html_spec.rb index 54ec4f32856..9168bc8e833 100644 --- a/spec/views/projects/deployments/_confirm_rollback_modal_spec.html_spec.rb +++ b/spec/views/projects/deployments/_confirm_rollback_modal_spec.html_spec.rb @@ -48,7 +48,7 @@ describe 'projects/deployments/_confirm_rollback_modal' do render expect(rendered).to have_selector('h4', text: "Rollback environment #{environment.name}?") - expect(rendered).to have_selector('p', text: "This action will run the job defined by staging for commit #{deployment.short_sha}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?") + expect(rendered).to have_selector('p', text: "This action will run the job defined by #{environment.name} for commit #{deployment.short_sha}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?") expect(rendered).to have_selector('a.btn-danger', text: 'Rollback') end -- cgit v1.2.3