diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-27 21:08:59 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-27 21:08:59 +0300 |
commit | f3b9e205bb8dc4f0e8ebff79cf364fede886014b (patch) | |
tree | ce9819fa446271f94e32af2cca1c02d618c3d9aa /spec | |
parent | 2b1e7f7dac0fa5d7bb3bdf415cec1b3c67ed77b0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/incidents/user_views_incident_spec.rb | 80 | ||||
-rw-r--r-- | spec/features/issues/user_interacts_with_awards_spec.rb | 2 | ||||
-rw-r--r-- | spec/features/search/user_uses_header_search_field_spec.rb | 6 | ||||
-rw-r--r-- | spec/features/static_site_editor_spec.rb | 40 | ||||
-rw-r--r-- | spec/frontend/awards_handler_spec.js | 23 | ||||
-rw-r--r-- | spec/helpers/issuables_helper_spec.rb | 18 | ||||
-rw-r--r-- | spec/lib/backup/database_spec.rb | 21 | ||||
-rw-r--r-- | spec/lib/gitlab/json_spec.rb | 518 | ||||
-rw-r--r-- | spec/models/personal_snippet_spec.rb | 3 | ||||
-rw-r--r-- | spec/models/project_snippet_spec.rb | 3 |
10 files changed, 395 insertions, 319 deletions
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb new file mode 100644 index 00000000000..9615abebfde --- /dev/null +++ b/spec/features/incidents/user_views_incident_spec.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "User views incident" do + let_it_be(:project) { create(:project_empty_repo, :public) } + let_it_be(:user) { create(:user) } + let_it_be(:incident) { create(:incident, project: project, description: "# Description header\n\n**Lorem** _ipsum_ dolor sit [amet](https://example.com)", author: user) } + let_it_be(:note) { create(:note, noteable: incident, project: project, author: user) } + + before_all do + project.add_developer(user) + end + + before do + sign_in(user) + + visit(project_issues_incident_path(project, incident)) + end + + it { expect(page).to have_header_with_correct_id_and_link(1, "Description header", "description-header") } + + it_behaves_like 'page meta description', ' Description header Lorem ipsum dolor sit amet' + + it 'shows the merge request and incident actions', :aggregate_failures do + expect(page).to have_link('New incident') + expect(page).to have_button('Create merge request') + expect(page).to have_link('Close incident') + end + + context 'when the project is archived' do + before do + project.update!(archived: true) + visit(project_issues_incident_path(project, incident)) + end + + it 'hides the merge request and incident actions', :aggregate_failures do + expect(page).not_to have_link('New incident') + expect(page).not_to have_button('Create merge request') + expect(page).not_to have_link('Close incident') + end + end + + describe 'user status' do + subject { visit(project_issues_incident_path(project, incident)) } + + context 'when showing status of the author of the incident' do + it_behaves_like 'showing user status' do + let(:user_with_status) { user } + end + end + + context 'when showing status of a user who commented on an incident', :js do + it_behaves_like 'showing user status' do + let(:user_with_status) { user } + end + end + + context 'when status message has an emoji', :js do + let_it_be(:message) { 'My status with an emoji' } + let_it_be(:message_emoji) { 'basketball' } + let_it_be(:status) { create(:user_status, user: user, emoji: 'smirk', message: "#{message} :#{message_emoji}:") } + + it 'correctly renders the emoji' do + wait_for_requests + + tooltip_span = page.first(".user-status-emoji[title^='#{message}']") + tooltip_span.hover + + wait_for_requests + + tooltip = page.find('.tooltip .tooltip-inner') + + page.within(tooltip) do + expect(page).to have_emoji(message_emoji) + end + end + end + end +end diff --git a/spec/features/issues/user_interacts_with_awards_spec.rb b/spec/features/issues/user_interacts_with_awards_spec.rb index 7db72f2cd05..bb9bce9eccf 100644 --- a/spec/features/issues/user_interacts_with_awards_spec.rb +++ b/spec/features/issues/user_interacts_with_awards_spec.rb @@ -68,7 +68,7 @@ RSpec.describe 'User interacts with awards' do page.within('.awards') do expect(page).to have_selector('.js-emoji-btn') expect(page.find('.js-emoji-btn.active .js-counter')).to have_content('1') - expect(page).to have_css(".js-emoji-btn.active[data-original-title='You']") + expect(page).to have_css(".js-emoji-btn.active[title='You']") expect do page.find('.js-emoji-btn.active').click diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb index 5cbfacf4e48..c2d5b0acda6 100644 --- a/spec/features/search/user_uses_header_search_field_spec.rb +++ b/spec/features/search/user_uses_header_search_field_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'User uses header search field', :js do wait_for_all_requests end - it 'shows the category search dropdown' do + it 'shows the category search dropdown', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/250285' do expect(page).to have_selector('.dropdown-header', text: /#{scope_name}/i) end end @@ -44,7 +44,7 @@ RSpec.describe 'User uses header search field', :js do page.find('#search').click end - it 'shows category search dropdown' do + it 'shows category search dropdown', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/250285' do expect(page).to have_selector('.dropdown-header', text: /#{scope_name}/i) end @@ -104,7 +104,7 @@ RSpec.describe 'User uses header search field', :js do let(:scope_name) { 'All GitLab' } end - it 'displays search options' do + it 'displays search options', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/251076' do fill_in_search('test') expect(page).to have_selector(scoped_search_link('test')) diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb index 03085917d67..a47579582e2 100644 --- a/spec/features/static_site_editor_spec.rb +++ b/spec/features/static_site_editor_spec.rb @@ -73,4 +73,44 @@ RSpec.describe 'Static Site Editor' do expect(node['data-static-site-generator']).to eq('middleman') end end + + describe 'Static Site Editor Content Security Policy' do + subject { response_headers['Content-Security-Policy'] } + + context 'when no global CSP config exists' do + before do + expect_next_instance_of(Projects::StaticSiteEditorController) do |controller| + expect(controller).to receive(:current_content_security_policy) + .and_return(ActionDispatch::ContentSecurityPolicy.new) + end + end + + it 'does not add CSP directives' do + visit sse_path + + is_expected.to be_blank + end + end + + context 'when a global CSP config exists' do + let_it_be(:cdn_url) { 'https://some-cdn.test' } + let_it_be(:youtube_url) { 'https://www.youtube.com' } + + before do + csp = ActionDispatch::ContentSecurityPolicy.new do |p| + p.frame_src :self, cdn_url + end + + expect_next_instance_of(Projects::StaticSiteEditorController) do |controller| + expect(controller).to receive(:current_content_security_policy).and_return(csp) + end + end + + it 'appends youtube to the CSP frame-src policy' do + visit sse_path + + is_expected.to eql("frame-src 'self' #{cdn_url} #{youtube_url}") + end + end + end end diff --git a/spec/frontend/awards_handler_spec.js b/spec/frontend/awards_handler_spec.js index 7fd6a9e7b87..c6a9c911ccf 100644 --- a/spec/frontend/awards_handler_spec.js +++ b/spec/frontend/awards_handler_spec.js @@ -169,29 +169,6 @@ describe('AwardsHandler', () => { }); }); - describe('::userAuthored', () => { - it('should update tooltip to user authored title', () => { - const $votesBlock = $('.js-awards-block').eq(0); - const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent(); - $thumbsUpEmoji.attr('data-title', 'sam'); - awardsHandler.userAuthored($thumbsUpEmoji); - - expect($thumbsUpEmoji.data('originalTitle')).toBe( - 'You cannot vote on your own issue, MR and note', - ); - }); - - it('should restore tooltip back to initial vote list', () => { - const $votesBlock = $('.js-awards-block').eq(0); - const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent(); - $thumbsUpEmoji.attr('data-title', 'sam'); - awardsHandler.userAuthored($thumbsUpEmoji); - jest.advanceTimersByTime(2801); - - expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); - }); - }); - describe('::getAwardUrl', () => { it('returns the url for request', () => { expect(awardsHandler.getAwardUrl()).toBe('http://test.host/-/snippets/1/toggle_award_emoji'); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 7a243573b6d..0e3752f220e 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -345,6 +345,24 @@ RSpec.describe IssuablesHelper do end end + describe '#issuable_display_type' do + using RSpec::Parameterized::TableSyntax + + where(:issuable_type, :issuable_display_type) do + :issue | 'issue' + :incident | 'incident' + :merge_request | 'merge request' + end + + with_them do + let(:issuable) { build_stubbed(issuable_type) } + + subject { helper.issuable_display_type(issuable) } + + it { is_expected.to eq(issuable_display_type) } + end + end + describe '#sidebar_milestone_tooltip_label' do it 'escapes HTML in the milestone title' do milestone = build(:milestone, title: '<img onerror=alert(1)>') diff --git a/spec/lib/backup/database_spec.rb b/spec/lib/backup/database_spec.rb index fccd6db0018..2bce4cab679 100644 --- a/spec/lib/backup/database_spec.rb +++ b/spec/lib/backup/database_spec.rb @@ -48,5 +48,26 @@ RSpec.describe Backup::Database do expect(output).to include(visible_error) end end + + context 'with PostgreSQL settings defined in the environment' do + let(:cmd) { %W[#{Gem.ruby} -e] + ["$stderr.puts ENV.to_h.select { |k, _| k.start_with?('PG') }"] } + let(:config) { YAML.load_file(File.join(Rails.root, 'config', 'database.yml'))['test'] } + + before do + stub_const 'ENV', ENV.to_h.merge({ + 'GITLAB_BACKUP_PGHOST' => 'test.example.com', + 'PGPASSWORD' => 'donotchange' + }) + end + + it 'overrides default config values' do + subject.restore + + expect(output).to include(%("PGHOST"=>"test.example.com")) + expect(output).to include(%("PGPASSWORD"=>"donotchange")) + expect(output).to include(%("PGPORT"=>"#{config['port']}")) if config['port'] + expect(output).to include(%("PGUSER"=>"#{config['username']}")) if config['username'] + end + end end end diff --git a/spec/lib/gitlab/json_spec.rb b/spec/lib/gitlab/json_spec.rb index 0402296a3a8..59ec94f2855 100644 --- a/spec/lib/gitlab/json_spec.rb +++ b/spec/lib/gitlab/json_spec.rb @@ -7,342 +7,306 @@ RSpec.describe Gitlab::Json do stub_feature_flags(json_wrapper_legacy_mode: true) end - shared_examples "json" do - describe ".parse" do - context "legacy_mode is disabled by default" do - it "parses an object" do - expect(subject.parse('{ "foo": "bar" }')).to eq({ "foo" => "bar" }) - end - - it "parses an array" do - expect(subject.parse('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }]) - end - - it "parses a string" do - expect(subject.parse('"foo"', legacy_mode: false)).to eq("foo") - end - - it "parses a true bool" do - expect(subject.parse("true", legacy_mode: false)).to be(true) - end - - it "parses a false bool" do - expect(subject.parse("false", legacy_mode: false)).to be(false) - end + describe ".parse" do + context "legacy_mode is disabled by default" do + it "parses an object" do + expect(subject.parse('{ "foo": "bar" }')).to eq({ "foo" => "bar" }) end - context "legacy_mode is enabled" do - it "parses an object" do - expect(subject.parse('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) - end - - it "parses an array" do - expect(subject.parse('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) - end - - it "raises an error on a string" do - expect { subject.parse('"foo"', legacy_mode: true) }.to raise_error(JSON::ParserError) - end - - it "raises an error on a true bool" do - expect { subject.parse("true", legacy_mode: true) }.to raise_error(JSON::ParserError) - end - - it "raises an error on a false bool" do - expect { subject.parse("false", legacy_mode: true) }.to raise_error(JSON::ParserError) - end + it "parses an array" do + expect(subject.parse('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }]) end - context "feature flag is disabled" do - before do - stub_feature_flags(json_wrapper_legacy_mode: false) - end - - it "parses an object" do - expect(subject.parse('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) - end - - it "parses an array" do - expect(subject.parse('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) - end - - it "parses a string" do - expect(subject.parse('"foo"', legacy_mode: true)).to eq("foo") - end + it "parses a string" do + expect(subject.parse('"foo"', legacy_mode: false)).to eq("foo") + end - it "parses a true bool" do - expect(subject.parse("true", legacy_mode: true)).to be(true) - end + it "parses a true bool" do + expect(subject.parse("true", legacy_mode: false)).to be(true) + end - it "parses a false bool" do - expect(subject.parse("false", legacy_mode: true)).to be(false) - end + it "parses a false bool" do + expect(subject.parse("false", legacy_mode: false)).to be(false) end end - describe ".parse!" do - context "legacy_mode is disabled by default" do - it "parses an object" do - expect(subject.parse!('{ "foo": "bar" }')).to eq({ "foo" => "bar" }) - end + context "legacy_mode is enabled" do + it "parses an object" do + expect(subject.parse('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) + end - it "parses an array" do - expect(subject.parse!('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }]) - end + it "parses an array" do + expect(subject.parse('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) + end - it "parses a string" do - expect(subject.parse!('"foo"', legacy_mode: false)).to eq("foo") - end + it "raises an error on a string" do + expect { subject.parse('"foo"', legacy_mode: true) }.to raise_error(JSON::ParserError) + end - it "parses a true bool" do - expect(subject.parse!("true", legacy_mode: false)).to be(true) - end + it "raises an error on a true bool" do + expect { subject.parse("true", legacy_mode: true) }.to raise_error(JSON::ParserError) + end - it "parses a false bool" do - expect(subject.parse!("false", legacy_mode: false)).to be(false) - end + it "raises an error on a false bool" do + expect { subject.parse("false", legacy_mode: true) }.to raise_error(JSON::ParserError) end + end - context "legacy_mode is enabled" do - it "parses an object" do - expect(subject.parse!('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) - end + context "feature flag is disabled" do + before do + stub_feature_flags(json_wrapper_legacy_mode: false) + end - it "parses an array" do - expect(subject.parse!('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) - end + it "parses an object" do + expect(subject.parse('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) + end - it "raises an error on a string" do - expect { subject.parse!('"foo"', legacy_mode: true) }.to raise_error(JSON::ParserError) - end + it "parses an array" do + expect(subject.parse('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) + end - it "raises an error on a true bool" do - expect { subject.parse!("true", legacy_mode: true) }.to raise_error(JSON::ParserError) - end + it "parses a string" do + expect(subject.parse('"foo"', legacy_mode: true)).to eq("foo") + end - it "raises an error on a false bool" do - expect { subject.parse!("false", legacy_mode: true) }.to raise_error(JSON::ParserError) - end + it "parses a true bool" do + expect(subject.parse("true", legacy_mode: true)).to be(true) end - context "feature flag is disabled" do - before do - stub_feature_flags(json_wrapper_legacy_mode: false) - end + it "parses a false bool" do + expect(subject.parse("false", legacy_mode: true)).to be(false) + end + end + end - it "parses an object" do - expect(subject.parse!('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) - end + describe ".parse!" do + context "legacy_mode is disabled by default" do + it "parses an object" do + expect(subject.parse!('{ "foo": "bar" }')).to eq({ "foo" => "bar" }) + end - it "parses an array" do - expect(subject.parse!('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) - end + it "parses an array" do + expect(subject.parse!('[{ "foo": "bar" }]')).to eq([{ "foo" => "bar" }]) + end - it "parses a string" do - expect(subject.parse!('"foo"', legacy_mode: true)).to eq("foo") - end + it "parses a string" do + expect(subject.parse!('"foo"', legacy_mode: false)).to eq("foo") + end - it "parses a true bool" do - expect(subject.parse!("true", legacy_mode: true)).to be(true) - end + it "parses a true bool" do + expect(subject.parse!("true", legacy_mode: false)).to be(true) + end - it "parses a false bool" do - expect(subject.parse!("false", legacy_mode: true)).to be(false) - end + it "parses a false bool" do + expect(subject.parse!("false", legacy_mode: false)).to be(false) end end - describe ".dump" do - it "dumps an object" do - expect(subject.dump({ "foo" => "bar" })).to eq('{"foo":"bar"}') + context "legacy_mode is enabled" do + it "parses an object" do + expect(subject.parse!('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) end - it "dumps an array" do - expect(subject.dump([{ "foo" => "bar" }])).to eq('[{"foo":"bar"}]') + it "parses an array" do + expect(subject.parse!('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) end - it "dumps a string" do - expect(subject.dump("foo")).to eq('"foo"') + it "raises an error on a string" do + expect { subject.parse!('"foo"', legacy_mode: true) }.to raise_error(JSON::ParserError) end - it "dumps a true bool" do - expect(subject.dump(true)).to eq("true") + it "raises an error on a true bool" do + expect { subject.parse!("true", legacy_mode: true) }.to raise_error(JSON::ParserError) end - it "dumps a false bool" do - expect(subject.dump(false)).to eq("false") + it "raises an error on a false bool" do + expect { subject.parse!("false", legacy_mode: true) }.to raise_error(JSON::ParserError) end end - describe ".generate" do - let(:obj) do - { test: true, "foo.bar" => "baz", is_json: 1, some: [1, 2, 3] } + context "feature flag is disabled" do + before do + stub_feature_flags(json_wrapper_legacy_mode: false) end - it "generates JSON" do - expected_string = <<~STR.chomp - {"test":true,"foo.bar":"baz","is_json":1,"some":[1,2,3]} - STR + it "parses an object" do + expect(subject.parse!('{ "foo": "bar" }', legacy_mode: true)).to eq({ "foo" => "bar" }) + end - expect(subject.generate(obj)).to eq(expected_string) + it "parses an array" do + expect(subject.parse!('[{ "foo": "bar" }]', legacy_mode: true)).to eq([{ "foo" => "bar" }]) end - it "allows you to customise the output" do - opts = { - indent: " ", - space: " ", - space_before: " ", - object_nl: "\n", - array_nl: "\n" - } + it "parses a string" do + expect(subject.parse!('"foo"', legacy_mode: true)).to eq("foo") + end - json = subject.generate(obj, opts) - - expected_string = <<~STR.chomp - { - "test" : true, - "foo.bar" : "baz", - "is_json" : 1, - "some" : [ - 1, - 2, - 3 - ] - } - STR + it "parses a true bool" do + expect(subject.parse!("true", legacy_mode: true)).to be(true) + end - expect(json).to eq(expected_string) + it "parses a false bool" do + expect(subject.parse!("false", legacy_mode: true)).to be(false) end end + end - describe ".pretty_generate" do - let(:obj) do - { - test: true, - "foo.bar" => "baz", - is_json: 1, - some: [1, 2, 3], - more: { test: true }, - multi_line_empty_array: [], - multi_line_empty_obj: {} - } - end + describe ".dump" do + it "dumps an object" do + expect(subject.dump({ "foo" => "bar" })).to eq('{"foo":"bar"}') + end - it "generates pretty JSON" do - expected_string = <<~STR.chomp - { - "test": true, - "foo.bar": "baz", - "is_json": 1, - "some": [ - 1, - 2, - 3 - ], - "more": { - "test": true - }, - "multi_line_empty_array": [ - - ], - "multi_line_empty_obj": { - } - } - STR + it "dumps an array" do + expect(subject.dump([{ "foo" => "bar" }])).to eq('[{"foo":"bar"}]') + end - expect(subject.pretty_generate(obj)).to eq(expected_string) - end + it "dumps a string" do + expect(subject.dump("foo")).to eq('"foo"') + end - it "allows you to customise the output" do - opts = { - space_before: " " - } + it "dumps a true bool" do + expect(subject.dump(true)).to eq("true") + end - json = subject.pretty_generate(obj, opts) - - expected_string = <<~STR.chomp - { - "test" : true, - "foo.bar" : "baz", - "is_json" : 1, - "some" : [ - 1, - 2, - 3 - ], - "more" : { - "test" : true - }, - "multi_line_empty_array" : [ - - ], - "multi_line_empty_obj" : { - } - } - STR + it "dumps a false bool" do + expect(subject.dump(false)).to eq("false") + end + end - expect(json).to eq(expected_string) - end + describe ".generate" do + let(:obj) do + { test: true, "foo.bar" => "baz", is_json: 1, some: [1, 2, 3] } end - context "the feature table is missing" do - before do - allow(Feature::FlipperFeature).to receive(:table_exists?).and_return(false) - end + it "generates JSON" do + expected_string = <<~STR.chomp + {"test":true,"foo.bar":"baz","is_json":1,"some":[1,2,3]} + STR + + expect(subject.generate(obj)).to eq(expected_string) + end - it "skips legacy mode handling" do - expect(Feature).not_to receive(:enabled?).with(:json_wrapper_legacy_mode, default_enabled: true) + it "allows you to customise the output" do + opts = { + indent: " ", + space: " ", + space_before: " ", + object_nl: "\n", + array_nl: "\n" + } - subject.send(:handle_legacy_mode!, {}) - end + json = subject.generate(obj, opts) - it "skips oj feature detection" do - expect(Feature).not_to receive(:enabled?).with(:oj_json, default_enabled: true) + expected_string = <<~STR.chomp + { + "test" : true, + "foo.bar" : "baz", + "is_json" : 1, + "some" : [ + 1, + 2, + 3 + ] + } + STR - subject.send(:enable_oj?) - end + expect(json).to eq(expected_string) end + end - context "the database is missing" do - before do - allow(Feature::FlipperFeature).to receive(:table_exists?).and_raise(PG::ConnectionBad) - end + describe ".pretty_generate" do + let(:obj) do + { + test: true, + "foo.bar" => "baz", + is_json: 1, + some: [1, 2, 3], + more: { test: true }, + multi_line_empty_array: [], + multi_line_empty_obj: {} + } + end - it "still parses json" do - expect(subject.parse("{}")).to eq({}) - end + it "generates pretty JSON" do + expected_string = <<~STR.chomp + { + "test": true, + "foo.bar": "baz", + "is_json": 1, + "some": [ + 1, + 2, + 3 + ], + "more": { + "test": true + }, + "multi_line_empty_array": [ + + ], + "multi_line_empty_obj": { + } + } + STR - it "still generates json" do - expect(subject.dump({})).to eq("{}") - end + expect(subject.pretty_generate(obj)).to eq(expected_string) + end + + it "allows you to customise the output" do + opts = { + space_before: " " + } + + json = subject.pretty_generate(obj, opts) + + expected_string = <<~STR.chomp + { + "test" : true, + "foo.bar" : "baz", + "is_json" : 1, + "some" : [ + 1, + 2, + 3 + ], + "more" : { + "test" : true + }, + "multi_line_empty_array" : [ + + ], + "multi_line_empty_obj" : { + } + } + STR + + expect(json).to eq(expected_string) end end - context "oj gem" do + context "the feature table is missing" do before do - stub_feature_flags(oj_json: true) + allow(Feature::FlipperFeature).to receive(:table_exists?).and_return(false) end - it_behaves_like "json" + it "skips legacy mode handling" do + expect(Feature).not_to receive(:enabled?).with(:json_wrapper_legacy_mode, default_enabled: true) - describe "#enable_oj?" do - it "returns true" do - expect(subject.enable_oj?).to be(true) - end + subject.send(:handle_legacy_mode!, {}) end end - context "json gem" do + context "the database is missing" do before do - stub_feature_flags(oj_json: false) + allow(Feature::FlipperFeature).to receive(:table_exists?).and_raise(PG::ConnectionBad) end - it_behaves_like "json" + it "still parses json" do + expect(subject.parse("{}")).to eq({}) + end - describe "#enable_oj?" do - it "returns false" do - expect(subject.enable_oj?).to be(false) - end + it "still generates json" do + expect(subject.dump({})).to eq("{}") end end @@ -353,47 +317,25 @@ RSpec.describe Gitlab::Json do let(:env) { {} } let(:result) { "{\"test\":true}" } - context "oj is enabled" do + context "grape_gitlab_json flag is enabled" do before do - stub_feature_flags(oj_json: true) + stub_feature_flags(grape_gitlab_json: true) end - context "grape_gitlab_json flag is enabled" do - before do - stub_feature_flags(grape_gitlab_json: true) - end - - it "generates JSON" do - expect(subject).to eq(result) - end - - it "uses Gitlab::Json" do - expect(Gitlab::Json).to receive(:dump).with(obj) - - subject - end + it "generates JSON" do + expect(subject).to eq(result) end - context "grape_gitlab_json flag is disabled" do - before do - stub_feature_flags(grape_gitlab_json: false) - end - - it "generates JSON" do - expect(subject).to eq(result) - end + it "uses Gitlab::Json" do + expect(Gitlab::Json).to receive(:dump).with(obj) - it "uses Grape::Formatter::Json" do - expect(Grape::Formatter::Json).to receive(:call).with(obj, env) - - subject - end + subject end end - context "oj is disabled" do + context "grape_gitlab_json flag is disabled" do before do - stub_feature_flags(oj_json: false) + stub_feature_flags(grape_gitlab_json: false) end it "generates JSON" do diff --git a/spec/models/personal_snippet_spec.rb b/spec/models/personal_snippet_spec.rb index 234f6e4b4b5..212605445ff 100644 --- a/spec/models/personal_snippet_spec.rb +++ b/spec/models/personal_snippet_spec.rb @@ -20,9 +20,8 @@ RSpec.describe PersonalSnippet do it_behaves_like 'model with repository' do let_it_be(:container) { create(:personal_snippet, :repository) } let(:stubbed_container) { build_stubbed(:personal_snippet) } - let(:expected_full_path) { "@snippets/#{container.id}" } + let(:expected_full_path) { "snippets/#{container.id}" } let(:expected_web_url_path) { "-/snippets/#{container.id}" } - let(:expected_repo_url_path) { "snippets/#{container.id}" } end describe '#parent_user' do diff --git a/spec/models/project_snippet_spec.rb b/spec/models/project_snippet_spec.rb index 3bcbf6b9e1b..3d1c87771f3 100644 --- a/spec/models/project_snippet_spec.rb +++ b/spec/models/project_snippet_spec.rb @@ -36,8 +36,7 @@ RSpec.describe ProjectSnippet do it_behaves_like 'model with repository' do let_it_be(:container) { create(:project_snippet, :repository) } let(:stubbed_container) { build_stubbed(:project_snippet) } - let(:expected_full_path) { "#{container.project.full_path}/@snippets/#{container.id}" } + let(:expected_full_path) { "#{container.project.full_path}/snippets/#{container.id}" } let(:expected_web_url_path) { "#{container.project.full_path}/-/snippets/#{container.id}" } - let(:expected_repo_url_path) { "#{container.project.full_path}/snippets/#{container.id}" } end end |