diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-25 00:09:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-25 00:09:08 +0300 |
commit | 7671216b60e2796a050358ff808b4a0c2de3d22f (patch) | |
tree | 605dfc1339a3cd7dc7353ac6d725191086a9acca /spec | |
parent | c2367afbf57ebc65d5b78a743b5d6a91f0aece9f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
17 files changed, 484 insertions, 115 deletions
diff --git a/spec/frontend/blob/pipeline_tour_success_spec.js b/spec/frontend/blob/pipeline_tour_success_spec.js new file mode 100644 index 00000000000..f6783b31a73 --- /dev/null +++ b/spec/frontend/blob/pipeline_tour_success_spec.js @@ -0,0 +1,40 @@ +import pipelineTourSuccess from '~/blob/pipeline_tour_success_modal.vue'; +import { shallowMount } from '@vue/test-utils'; +import Cookies from 'js-cookie'; +import { GlSprintf, GlModal } from '@gitlab/ui'; + +describe('PipelineTourSuccessModal', () => { + let wrapper; + let cookieSpy; + const goToPipelinesPath = 'some_pipeline_path'; + const commitCookie = 'some_cookie'; + + beforeEach(() => { + wrapper = shallowMount(pipelineTourSuccess, { + propsData: { + goToPipelinesPath, + commitCookie, + }, + }); + + cookieSpy = jest.spyOn(Cookies, 'remove'); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('has expected structure', () => { + const modal = wrapper.find(GlModal); + const sprintf = modal.find(GlSprintf); + + expect(modal.attributes('title')).toContain("That's it, well done!"); + expect(sprintf.exists()).toBe(true); + }); + + it('calls to remove cookie', () => { + wrapper.vm.disableModalFromRenderingAgain(); + + expect(cookieSpy).toHaveBeenCalledWith(commitCookie); + }); +}); diff --git a/spec/frontend/helpers/tracking_helper.js b/spec/frontend/helpers/tracking_helper.js index 68c1bd2dbca..bd3bd24028c 100644 --- a/spec/frontend/helpers/tracking_helper.js +++ b/spec/frontend/helpers/tracking_helper.js @@ -8,7 +8,7 @@ let handlers; export function mockTracking(category = '_category_', documentOverride, spyMethod) { document = documentOverride || window.document; window.snowplow = () => {}; - Tracking.bindDocument(category, document); + handlers = Tracking.bindDocument(category, document); return spyMethod ? spyMethod(Tracking, 'event') : null; } diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js index c3c52844c2c..30a8e138df2 100644 --- a/spec/frontend/tracking_spec.js +++ b/spec/frontend/tracking_spec.js @@ -226,6 +226,14 @@ describe('Tracking', () => { }; }); + it('calls the event method with no category or action defined', () => { + mixin.trackingCategory = mixin.trackingCategory(); + mixin.trackingOptions = mixin.trackingOptions(); + + mixin.track(); + expect(eventSpy).toHaveBeenCalledWith(undefined, undefined, {}); + }); + it('calls the event method', () => { mixin.trackingCategory = mixin.trackingCategory(); mixin.trackingOptions = mixin.trackingOptions(); diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js index 77293a5b187..8b0253dc01a 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js @@ -1,16 +1,24 @@ import { mount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; import suggestPipelineComponent from '~/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue'; +import stubChildren from 'helpers/stub_children'; +import PipelineTourState from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_tour.vue'; import MrWidgetIcon from '~/vue_merge_request_widget/components/mr_widget_icon.vue'; +import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper'; describe('MRWidgetHeader', () => { let wrapper; const pipelinePath = '/foo/bar/add/pipeline/path'; + const pipelineSvgPath = '/foo/bar/pipeline/svg/path'; + const humanAccess = 'maintainer'; const iconName = 'status_notfound'; beforeEach(() => { wrapper = mount(suggestPipelineComponent, { - propsData: { pipelinePath }, + propsData: { pipelinePath, pipelineSvgPath, humanAccess }, + stubs: { + ...stubChildren(PipelineTourState), + }, }); }); @@ -22,30 +30,47 @@ describe('MRWidgetHeader', () => { it('renders add pipeline file link', () => { const link = wrapper.find(GlLink); - return wrapper.vm.$nextTick().then(() => { - expect(link.exists()).toBe(true); - expect(link.attributes().href).toBe(pipelinePath); - }); + expect(link.exists()).toBe(true); + expect(link.attributes().href).toBe(pipelinePath); }); it('renders the expected text', () => { const messageText = /\s*No pipeline\s*Add the .gitlab-ci.yml file\s*to create one./; - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.text()).toMatch(messageText); - }); + expect(wrapper.text()).toMatch(messageText); }); it('renders widget icon', () => { const icon = wrapper.find(MrWidgetIcon); - return wrapper.vm.$nextTick().then(() => { - expect(icon.exists()).toBe(true); - expect(icon.props()).toEqual( - expect.objectContaining({ - name: iconName, - }), - ); + expect(icon.exists()).toBe(true); + expect(icon.props()).toEqual( + expect.objectContaining({ + name: iconName, + }), + ); + }); + + describe('tracking', () => { + let spy; + + beforeEach(() => { + spy = mockTracking('_category_', wrapper.element, jest.spyOn); + }); + + afterEach(() => { + unmockTracking(); + }); + + it('send an event when ok button is clicked', () => { + const link = wrapper.find(GlLink); + triggerEvent(link.element); + + expect(spy).toHaveBeenCalledWith('_category_', 'click_link', { + label: 'no_pipeline_noticed', + property: humanAccess, + value: '30', + }); }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_tour_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_tour_spec.js new file mode 100644 index 00000000000..e8f95e099cc --- /dev/null +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_pipeline_tour_spec.js @@ -0,0 +1,143 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlPopover } from '@gitlab/ui'; +import Cookies from 'js-cookie'; +import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper'; +import pipelineTourState from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_tour.vue'; +import { popoverProps, cookieKey } from './pipeline_tour_mock_data'; + +describe('MRWidgetPipelineTour', () => { + let wrapper; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('template', () => { + describe(`when ${cookieKey} cookie is set`, () => { + beforeEach(() => { + Cookies.set(cookieKey, true); + wrapper = shallowMount(pipelineTourState, { + propsData: popoverProps, + }); + }); + + it('does not render the popover', () => { + const popover = wrapper.find(GlPopover); + + expect(popover.exists()).toBe(false); + }); + + describe('tracking', () => { + let trackingSpy; + + beforeEach(() => { + trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); + }); + + afterEach(() => { + unmockTracking(); + }); + it('does not call tracking', () => { + expect(trackingSpy).not.toHaveBeenCalled(); + }); + }); + }); + + describe(`when ${cookieKey} cookie is not set`, () => { + const findOkBtn = () => wrapper.find({ ref: 'ok' }); + const findDismissBtn = () => wrapper.find({ ref: 'no-thanks' }); + + beforeEach(() => { + Cookies.remove(cookieKey); + wrapper = shallowMount(pipelineTourState, { + propsData: popoverProps, + }); + }); + + it('renders the popover', () => { + const popover = wrapper.find(GlPopover); + + expect(popover.exists()).toBe(true); + }); + + it('renders the show me how button', () => { + const button = findOkBtn(); + + expect(button.exists()).toBe(true); + expect(button.attributes().category).toBe('primary'); + }); + + it('renders the dismiss button', () => { + const button = findDismissBtn(); + + expect(button.exists()).toBe(true); + expect(button.attributes().category).toBe('secondary'); + }); + + it('renders the empty pipelines image', () => { + const image = wrapper.find('img'); + + expect(image.exists()).toBe(true); + expect(image.attributes().src).toBe(popoverProps.pipelineSvgPath); + }); + + describe('tracking', () => { + let trackingSpy; + + beforeEach(() => { + trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); + }); + + afterEach(() => { + unmockTracking(); + }); + + it('send event for basic view of popover', () => { + document.body.dataset.page = 'projects:merge_requests:show'; + + wrapper.vm.trackOnShow(); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, undefined, { + label: popoverProps.trackLabel, + property: popoverProps.humanAccess, + }); + }); + + it('send an event when ok button is clicked', () => { + const okBtn = findOkBtn(); + triggerEvent(okBtn.element); + + expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_button', { + label: popoverProps.trackLabel, + property: popoverProps.humanAccess, + value: '10', + }); + }); + + it('send an event when dismiss button is clicked', () => { + const dismissBtn = findDismissBtn(); + triggerEvent(dismissBtn.element); + + expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_button', { + label: popoverProps.trackLabel, + property: popoverProps.humanAccess, + value: '20', + }); + }); + }); + + describe('dismissPopover', () => { + it('updates popoverDismissed', () => { + const button = findDismissBtn(); + const popover = wrapper.find(GlPopover); + button.vm.$emit('click'); + + return wrapper.vm.$nextTick().then(() => { + expect(Cookies.get(cookieKey)).toBe('true'); + expect(popover.exists()).toBe(false); + }); + }); + }); + }); + }); +}); diff --git a/spec/frontend/vue_mr_widget/components/states/pipeline_tour_mock_data.js b/spec/frontend/vue_mr_widget/components/states/pipeline_tour_mock_data.js new file mode 100644 index 00000000000..39bc89e459c --- /dev/null +++ b/spec/frontend/vue_mr_widget/components/states/pipeline_tour_mock_data.js @@ -0,0 +1,10 @@ +export const popoverProps = { + pipelinePath: '/foo/bar/add/pipeline/path', + pipelineSvgPath: 'assets/illustrations/something.svg', + humanAccess: 'maintainer', + popoverTarget: 'suggest-popover', + popoverContainer: 'suggest-pipeline', + trackLabel: 'some_tracking_label', +}; + +export const cookieKey = 'suggest_pipeline_dismissed'; diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js new file mode 100644 index 00000000000..420281e844c --- /dev/null +++ b/spec/frontend/vue_shared/components/file_row_spec.js @@ -0,0 +1,90 @@ +import { file } from 'jest/ide/helpers'; +import FileRow from '~/vue_shared/components/file_row.vue'; +import { mount } from '@vue/test-utils'; + +describe('File row component', () => { + let wrapper; + + function createComponent(propsData) { + wrapper = mount(FileRow, { + propsData, + }); + } + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders name', () => { + const fileName = 't4'; + createComponent({ + file: file(fileName), + level: 0, + }); + + const name = wrapper.find('.file-row-name'); + + expect(name.text().trim()).toEqual(fileName); + }); + + it('emits toggleTreeOpen on click', () => { + const fileName = 't3'; + createComponent({ + file: { + ...file(fileName), + type: 'tree', + }, + level: 0, + }); + jest.spyOn(wrapper.vm, '$emit'); + + wrapper.element.click(); + + expect(wrapper.vm.$emit).toHaveBeenCalledWith('toggleTreeOpen', fileName); + }); + + it('calls scrollIntoView if made active', () => { + createComponent({ + file: { + ...file(), + type: 'blob', + active: false, + }, + level: 0, + }); + + jest.spyOn(wrapper.vm, 'scrollIntoView'); + + wrapper.setProps({ + file: Object.assign({}, wrapper.props('file'), { + active: true, + }), + }); + + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.vm.scrollIntoView).toHaveBeenCalled(); + }); + }); + + it('indents row based on level', () => { + createComponent({ + file: file('t4'), + level: 2, + }); + + expect(wrapper.find('.file-row-name').element.style.marginLeft).toBe('32px'); + }); + + it('renders header for file', () => { + createComponent({ + file: { + isHeader: true, + path: 'app/assets', + tree: [], + }, + level: 0, + }); + + expect(wrapper.element.classList).toContain('js-file-row-header'); + }); +}); diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index a9f4b03eba5..dec7d6b2df3 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -27,7 +27,7 @@ describe BlobHelper do end describe "#edit_blob_link" do - let(:namespace) { create(:namespace, name: 'gitlab' )} + let(:namespace) { create(:namespace, name: 'gitlab') } let(:project) { create(:project, :repository, namespace: namespace) } before do @@ -202,6 +202,90 @@ describe BlobHelper do end end end + + describe '#show_suggest_pipeline_creation_celebration?' do + let(:blob) { fake_blob(path: Gitlab::FileDetector::PATTERNS[:gitlab_ci]) } + let(:current_user) { create(:user) } + + before do + assign(:project, project) + assign(:blob, blob) + assign(:commit, double('Commit', sha: 'whatever')) + helper.request.cookies["suggest_gitlab_ci_yml_commit_#{project.id}"] = 'true' + allow(blob).to receive(:auxiliary_viewer).and_return(double('viewer', valid?: true)) + allow(helper).to receive(:current_user).and_return(current_user) + end + + context 'experiment enabled' do + before do + allow(helper).to receive(:experiment_enabled?).and_return(true) + end + + it 'is true' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_truthy + end + + context 'file is invalid format' do + before do + allow(blob).to receive(:auxiliary_viewer).and_return(double('viewer', valid?: false)) + end + + it 'is false' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey + end + end + + context 'path is not a ci file' do + before do + allow(blob).to receive(:path).and_return('something_bad') + end + + it 'is false' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey + end + end + + context 'does not use the default ci config' do + before do + project.ci_config_path = 'something_bad' + end + + it 'is false' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey + end + end + + context 'does not have the needed cookie' do + before do + helper.request.cookies.delete "suggest_gitlab_ci_yml_commit_#{project.id}" + end + + it 'is false' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey + end + end + end + + context 'experiment disabled' do + before do + allow(helper).to receive(:experiment_enabled?).and_return(false) + end + + it 'is false' do + expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey + end + end + end + end + + describe 'suggest_pipeline_commit_cookie_name' do + let(:project) { create(:project) } + + it 'uses project id to make up the cookie name' do + assign(:project, project) + + expect(helper.suggest_pipeline_commit_cookie_name).to eq "suggest_gitlab_ci_yml_commit_#{project.id}" + end end describe '#ide_edit_path' do diff --git a/spec/javascripts/helpers/tracking_helper.js b/spec/javascripts/helpers/tracking_helper.js index 68c1bd2dbca..bd3bd24028c 100644 --- a/spec/javascripts/helpers/tracking_helper.js +++ b/spec/javascripts/helpers/tracking_helper.js @@ -8,7 +8,7 @@ let handlers; export function mockTracking(category = '_category_', documentOverride, spyMethod) { document = documentOverride || window.document; window.snowplow = () => {}; - Tracking.bindDocument(category, document); + handlers = Tracking.bindDocument(category, document); return spyMethod ? spyMethod(Tracking, 'event') : null; } diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index 2eaba46cdce..048a5f88c99 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -28,6 +28,7 @@ export default { }, merge_status: 'can_be_merged', merge_user_id: null, + pipelines_empty_svg_path: '/path/to/svg', source_branch: 'daaaa', source_branch_link: 'daaaa', source_project_id: 19, diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js index 272f6cad5fc..796235be4c3 100644 --- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js @@ -96,5 +96,11 @@ describe('MergeRequestStore', () => { expect(store.humanAccess).toEqual('Maintainer'); }); + + it('should set pipelinesEmptySvgPath', () => { + store.setData({ ...mockData }); + + expect(store.pipelinesEmptySvgPath).toBe('/path/to/svg'); + }); }); }); diff --git a/spec/javascripts/vue_shared/components/file_row_spec.js b/spec/javascripts/vue_shared/components/file_row_spec.js deleted file mode 100644 index 11fcb9b89c1..00000000000 --- a/spec/javascripts/vue_shared/components/file_row_spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import Vue from 'vue'; -import { file } from 'spec/ide/helpers'; -import FileRow from '~/vue_shared/components/file_row.vue'; -import mountComponent from '../../helpers/vue_mount_component_helper'; - -describe('File row component', () => { - let vm; - - function createComponent(propsData) { - const FileRowComponent = Vue.extend(FileRow); - - vm = mountComponent(FileRowComponent, propsData); - } - - afterEach(() => { - vm.$destroy(); - }); - - it('renders name', () => { - createComponent({ - file: file('t4'), - level: 0, - }); - - const name = vm.$el.querySelector('.file-row-name'); - - expect(name.textContent.trim()).toEqual(vm.file.name); - }); - - it('emits toggleTreeOpen on click', () => { - createComponent({ - file: { - ...file('t3'), - type: 'tree', - }, - level: 0, - }); - spyOn(vm, '$emit').and.stub(); - - vm.$el.click(); - - expect(vm.$emit).toHaveBeenCalledWith('toggleTreeOpen', vm.file.path); - }); - - it('calls scrollIntoView if made active', done => { - createComponent({ - file: { - ...file(), - type: 'blob', - active: false, - }, - level: 0, - }); - - spyOn(vm, 'scrollIntoView').and.stub(); - - vm.file.active = true; - - vm.$nextTick(() => { - expect(vm.scrollIntoView).toHaveBeenCalled(); - - done(); - }); - }); - - it('indents row based on level', () => { - createComponent({ - file: file('t4'), - level: 2, - }); - - expect(vm.$el.querySelector('.file-row-name').style.marginLeft).toBe('32px'); - }); - - it('renders header for file', () => { - createComponent({ - file: { - isHeader: true, - path: 'app/assets', - tree: [], - }, - level: 0, - }); - - expect(vm.$el.classList).toContain('js-file-row-header'); - }); -}); diff --git a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb index b1d56b57596..9d8cd729958 100644 --- a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb @@ -19,12 +19,14 @@ describe Banzai::Filter::InlineMetricsRedactorFilter do context 'with a metrics charts placeholder' do let(:input) { %(<div class="js-render-metrics" data-dashboard-url="#{url}"></div>) } - it_behaves_like 'a supported metrics dashboard url' + it_behaves_like 'redacts the embed placeholder' + it_behaves_like 'retains the embed placeholder when applicable' context 'for a grafana dashboard' do let(:url) { urls.project_grafana_api_metrics_dashboard_url(project, embedded: true) } - it_behaves_like 'a supported metrics dashboard url' + it_behaves_like 'redacts the embed placeholder' + it_behaves_like 'retains the embed placeholder when applicable' end context 'the user has requisite permissions' do diff --git a/spec/requests/api/version_spec.rb b/spec/requests/api/version_spec.rb index e2117ca45ee..7d81170687a 100644 --- a/spec/requests/api/version_spec.rb +++ b/spec/requests/api/version_spec.rb @@ -12,17 +12,55 @@ describe API::Version do end end - context 'when authenticated' do + context 'when authenticated as user' do let(:user) { create(:user) } it 'returns the version information' do get api('/version', user) - expect(response).to have_gitlab_http_status(200) - expect(json_response['version']).to eq(Gitlab::VERSION) - expect(json_response['revision']).to eq(Gitlab.revision) + expect_version end end + + context 'when authenticated with token' do + let(:personal_access_token) { create(:personal_access_token, scopes: scopes) } + + context 'with api scope' do + let(:scopes) { %i(api) } + + it 'returns the version information' do + get api('/version', personal_access_token: personal_access_token) + + expect_version + end + end + + context 'with read_user scope' do + let(:scopes) { %i(read_user) } + + it 'returns the version information' do + get api('/version', personal_access_token: personal_access_token) + + expect_version + end + end + + context 'with neither api nor read_user scope' do + let(:scopes) { %i(read_repository) } + + it 'returns authorization error' do + get api('/version', personal_access_token: personal_access_token) + + expect(response).to have_gitlab_http_status(403) + end + end + end + + def expect_version + expect(response).to have_gitlab_http_status(200) + expect(json_response['version']).to eq(Gitlab::VERSION) + expect(json_response['revision']).to eq(Gitlab.revision) + end end context 'with graphql enabled' do diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb index f621cb650f9..597dae81cfb 100644 --- a/spec/serializers/merge_request_widget_entity_spec.rb +++ b/spec/serializers/merge_request_widget_entity_spec.rb @@ -75,8 +75,9 @@ describe MergeRequestWidgetEntity do let(:role) { :developer } it 'has add ci config path' do - expect(subject[:merge_request_add_ci_config_path]) - .to eq("/#{resource.project.full_path}/-/new/#{resource.source_branch}?commit_message=Add+.gitlab-ci.yml&file_name=.gitlab-ci.yml") + expected_path = "/#{resource.project.full_path}/-/new/#{resource.source_branch}?commit_message=Add+.gitlab-ci.yml&file_name=.gitlab-ci.yml&suggest_gitlab_ci_yml=true" + + expect(subject[:merge_request_add_ci_config_path]).to eq(expected_path) end context 'when source project is missing' do diff --git a/spec/support/shared_examples/banzai/filters/inline_metrics_redactor_shared_examples.rb b/spec/support/shared_examples/banzai/filters/inline_metrics_redactor_shared_examples.rb index d283b3a3b27..07abb86ceb5 100644 --- a/spec/support/shared_examples/banzai/filters/inline_metrics_redactor_shared_examples.rb +++ b/spec/support/shared_examples/banzai/filters/inline_metrics_redactor_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'a supported metrics dashboard url' do +RSpec.shared_examples 'redacts the embed placeholder' do context 'no user is logged in' do it 'redacts the placeholder' do expect(doc.to_s).to be_empty @@ -14,7 +14,9 @@ RSpec.shared_examples 'a supported metrics dashboard url' do expect(doc.to_s).to be_empty end end +end +RSpec.shared_examples 'retains the embed placeholder when applicable' do context 'the user has requisite permissions' do let(:user) { create(:user) } let(:doc) { filter(input, current_user: user) } @@ -22,7 +24,7 @@ RSpec.shared_examples 'a supported metrics dashboard url' do it 'leaves the placeholder' do project.add_maintainer(user) - expect(doc.to_s).to eq(input) + expect(CGI.unescapeHTML(doc.to_s)).to eq(input) end end end diff --git a/spec/uploaders/import_export_uploader_spec.rb b/spec/uploaders/import_export_uploader_spec.rb index 7e8937ff5a6..33cab911f86 100644 --- a/spec/uploaders/import_export_uploader_spec.rb +++ b/spec/uploaders/import_export_uploader_spec.rb @@ -51,4 +51,10 @@ describe ImportExportUploader do end end end + + describe '.workhorse_local_upload_path' do + it 'returns path that includes uploads dir' do + expect(described_class.workhorse_local_upload_path).to end_with('/uploads/tmp/uploads') + end + end end |