diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-20 03:09:13 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-20 03:09:13 +0300 |
commit | c0bc64e25edb4d7c3ac1d89de720f94782be5d2e (patch) | |
tree | 7cce86fcd83c9ba6fe7c3eb418f19a982d6eff3d /spec | |
parent | 1cd61065a0d86b492be5086906429ac5956e3672 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
8 files changed, 220 insertions, 35 deletions
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb index 8073e7e9556..0f10da6ebad 100644 --- a/spec/features/markdown/copy_as_gfm_spec.rb +++ b/spec/features/markdown/copy_as_gfm_spec.rb @@ -29,7 +29,7 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do it 'transforms HTML to GFM', :aggregate_failures do verify( 'nesting', - '> 1. [x] **[$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~](http://google.com)**' + '> 1. [x] [**$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~**](http://google.com)' ) verify( @@ -114,9 +114,9 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do GFM <<~GFM, 1. [ ] Unchecked ordered task - 1. [x] Checked ordered task - 1. [~] Inapplicable ordered task - 1. [~] Inapplicable ordered task with ~~del~~ and <s>strike</s> embedded + 2. [x] Checked ordered task + 3. [~] Inapplicable ordered task + 4. [~] Inapplicable ordered task with ~~del~~ and <s>strike</s> embedded GFM <<~GFM * [ ] Unchecked loose list task @@ -496,15 +496,14 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do <sub>sub</sub> <dl> - <dt>dt</dt> - <dt>dt</dt> - <dd>dd</dd> - <dd>dd</dd> - - <dt>dt</dt> - <dt>dt</dt> - <dd>dd</dd> - <dd>dd</dd> + <dt>dt</dt> + <dt>dt</dt> + <dd>dd</dd> + <dd>dd</dd> + <dt>dt</dt> + <dt>dt</dt> + <dd>dd</dd> + <dd>dd</dd> </dl> <kbd>kbd</kbd> @@ -518,9 +517,8 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do <abbr title="HyperText "Markup" Language">HTML</abbr> <details> - <summary>summary></summary> - - details + <summary>summary</summary> + details </details> GFM ) @@ -542,17 +540,20 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do <<~GFM Foo - ```js - Code goes here - ``` + ```` + ```js + Code goes here + ``` + ```` GFM ) verify( 'MarkdownFilter', - "Line with two spaces at the end \nto insert a linebreak", + "Line with backslash at the end\\\nto insert a linebreak", '`code`', - '`` code with ` ticks ``', + '``code with ` ticks``', + '`` `nested` code ``', '> Quote', # multiline quote <<~GFM, @@ -589,7 +590,7 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do GFM <<~GFM, 1. Ordered list item - 1. Ordered list item 2 + 2. Ordered list item 2 GFM # multiline ordered list item @@ -618,7 +619,7 @@ RSpec.describe 'Copy as GFM', :js, feature_category: :team_planning do '##### Heading', '###### Heading', '**Bold**', - '*Italics*', + '_Italics_', '~~Strikethrough (del)~~', '<s>Strikethrough</s>', '---', diff --git a/spec/frontend/behaviors/copy_as_gfm_spec.js b/spec/frontend/behaviors/copy_as_gfm_spec.js index 2032faa1c33..a35cf2f0b13 100644 --- a/spec/frontend/behaviors/copy_as_gfm_spec.js +++ b/spec/frontend/behaviors/copy_as_gfm_spec.js @@ -1,6 +1,8 @@ import waitForPromises from 'helpers/wait_for_promises'; import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm'; +jest.mock('~/emoji'); + describe('CopyAsGFM', () => { describe('CopyAsGFM.pasteGFM', () => { let target; @@ -116,7 +118,7 @@ describe('CopyAsGFM', () => { window.getSelection = jest.fn(() => selection); await simulateCopy(); - const expectedGFM = '1. List Item1\n1. List Item2'; + const expectedGFM = '1. List Item1\n2. List Item2'; expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM); }); diff --git a/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js index 6db99e796d6..3951714c64e 100644 --- a/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js +++ b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js @@ -11,6 +11,8 @@ jest.mock('~/lib/utils/common_utils', () => ({ getSelectedFragment: jest.fn().mockName('getSelectedFragment'), })); +jest.mock('~/emoji'); + describe('ShortcutsIssuable', () => { beforeAll(() => { initCopyAsGFM(); @@ -215,7 +217,7 @@ describe('ShortcutsIssuable', () => { ShortcutsIssuable.replyWithSelectedText(true); await waitForPromises(); - expect($(FORM_SELECTOR).val()).toBe('> *Selected text.*\n\n'); + expect($(FORM_SELECTOR).val()).toBe('> _Selected text._\n\n'); }); it('triggers `focus`', async () => { diff --git a/spec/frontend/content_editor/extensions/code_suggestion_spec.js b/spec/frontend/content_editor/extensions/code_suggestion_spec.js index 86656fb96c3..b513735af22 100644 --- a/spec/frontend/content_editor/extensions/code_suggestion_spec.js +++ b/spec/frontend/content_editor/extensions/code_suggestion_spec.js @@ -28,7 +28,7 @@ describe('content_editor/extensions/code_suggestion', () => { let doc; let codeSuggestion; - const codeSuggestionConfig = { + const codeSuggestionsConfig = { canSuggest: true, line: { new_line: 5 }, lines: [{ new_line: 5 }], @@ -43,7 +43,9 @@ describe('content_editor/extensions/code_suggestion', () => { tiptapEditor = createTestEditor({ extensions: [ CodeBlockHighlight, - CodeSuggestion.configure({ config: { ...codeSuggestionConfig, ...config } }), + CodeSuggestion.configure({ + codeSuggestionsConfig: { ...codeSuggestionsConfig, ...config }, + }), ], }); diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js index 4ae39f7a5a7..aeaa63a332f 100644 --- a/spec/frontend/content_editor/services/markdown_serializer_spec.js +++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js @@ -138,10 +138,10 @@ const { }, }); -const serialize = (...content) => - new MarkdownSerializer().serialize({ - doc: doc(...content), - }); +const serializeWithOptions = (options, ...content) => + new MarkdownSerializer().serialize({ doc: doc(...content) }, options); + +const serialize = (...content) => new MarkdownSerializer().serialize({ doc: doc(...content) }); describe('markdownSerializer', () => { it('correctly serializes bold', () => { @@ -389,6 +389,16 @@ describe('markdownSerializer', () => { expect(serialize(paragraph(strike('deleted content')))).toBe('~~deleted content~~'); }); + it.each` + strikeTag + ${'s'} + ${'strike'} + `('correctly serializes strikethrough with "$strikeTag" tag', ({ strikeTag }) => { + expect(serialize(paragraph(strike({ htmlTag: strikeTag }, 'deleted content')))).toBe( + `<${strikeTag}>deleted content</${strikeTag}>`, + ); + }); + it('correctly serializes blockquotes with hard breaks', () => { expect(serialize(blockquote('some text', hardBreak(), hardBreak(), 'new line'))).toBe( ` @@ -411,6 +421,32 @@ describe('markdownSerializer', () => { ); }); + it('correctly serializes a blockquote with a nested blockquote', () => { + expect( + serialize( + blockquote( + paragraph('some paragraph'), + blockquote(paragraph('nested paragraph'), codeBlock('var x = 10;')), + ), + ), + ).toBe( + ` +> some paragraph +> +> > nested paragraph +> > +> > \`\`\` +> > var x = 10; +> > \`\`\` + `.trim(), + ); + }); + + it('skips serializing an empty blockquote if skipEmptyNodes=true', () => { + expect(serializeWithOptions({ skipEmptyNodes: true }, blockquote())).toBe(''); + expect(serializeWithOptions({ skipEmptyNodes: true }, blockquote(paragraph()))).toBe(''); + }); + it('correctly serializes a multiline blockquote', () => { expect( serialize( @@ -451,6 +487,23 @@ this is not really json but just trying out whether this case works or not ); }); + it('renders a plaintext code block without a prefix', () => { + expect( + serialize( + codeBlock( + { language: 'plaintext', langParams: '' }, + 'this is not really json but just trying out whether this case works or not', + ), + ), + ).toBe( + ` +\`\`\` +this is not really json but just trying out whether this case works or not +\`\`\` + `.trim(), + ); + }); + it('correctly serializes a code block with language parameters', () => { expect( serialize( @@ -514,6 +567,10 @@ var a = 0; ); }); + it('skips serializing an empty code block if skipEmptyNodes=true', () => { + expect(serializeWithOptions({ skipEmptyNodes: true }, codeBlock())).toBe(''); + }); + it('correctly serializes emoji', () => { expect(serialize(paragraph(emoji({ name: 'dog' })))).toBe(':dog:'); }); @@ -545,6 +602,20 @@ var a = 0; ); }); + it('skips serializing an empty heading if skipEmptyNodes=true', () => { + expect( + serializeWithOptions( + { skipEmptyNodes: true }, + heading({ level: 1 }), + heading({ level: 2 }), + heading({ level: 3 }), + heading({ level: 4 }), + heading({ level: 5 }), + heading({ level: 6 }), + ), + ).toBe(''); + }); + it('correctly serializes horizontal rule', () => { expect(serialize(horizontalRule(), horizontalRule(), horizontalRule())).toBe( ` @@ -614,6 +685,22 @@ var a = 0; ).toBe('![this is an image](file.png "foo bar baz")'); }); + it('does not use the canonicalSrc if options.useCanonicalSrc=false', () => { + expect( + serializeWithOptions( + { useCanonicalSrc: false }, + paragraph( + image({ + src: '/uploads/abcde/file.png', + alt: 'this is an image', + canonicalSrc: 'file.png', + title: 'foo bar baz', + }), + ), + ), + ).toBe('![this is an image](/uploads/abcde/file.png "foo bar baz")'); + }); + it('correctly serializes bullet list', () => { expect( serialize( diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb index 7fc50438c95..17b2218e05c 100644 --- a/spec/lib/gitlab/current_settings_spec.rb +++ b/spec/lib/gitlab/current_settings_spec.rb @@ -88,6 +88,8 @@ RSpec.describe Gitlab::CurrentSettings, feature_category: :shared do end describe '#current_application_settings', :use_clean_rails_memory_store_caching do + let_it_be(:organization_settings) { create(:organization_setting, restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) } + it 'allows keys to be called directly' do described_class.update!(home_page_url: 'http://mydomain.com', signup_enabled: false) @@ -97,10 +99,58 @@ RSpec.describe Gitlab::CurrentSettings, feature_category: :shared do expect(described_class.metrics_sample_interval).to be(15) end - it 'retrieves settings using ApplicationSettingFetcher' do - expect(Gitlab::ApplicationSettingFetcher).to receive(:current_application_settings).and_call_original + context 'when key is in ApplicationSettingFetcher' do + it 'retrieves settings using ApplicationSettingFetcher' do + expect(Gitlab::ApplicationSettingFetcher).to receive(:current_application_settings).and_call_original + + described_class.home_page_url + end + end + + context 'when key is in OrganizationSetting' do + before do + allow(Gitlab::ApplicationSettingFetcher).to receive(:current_application_settings).and_return(nil) + end + + context 'and the current organization is known' do + before do + allow(Organizations::OrganizationSetting).to receive(:for_current_organization).and_return(organization_settings) + end + + it 'retrieves settings using OrganizationSetting' do + expect(described_class.restricted_visibility_levels).to eq(organization_settings.restricted_visibility_levels) + end + end + + context 'and the current organization is unknown' do + before do + allow(Organizations::OrganizationSetting).to receive(:for_current_organization).and_return(nil) + end + + it 'raises NoMethodError' do + expect { described_class.foo }.to raise_error(NoMethodError) + end + end + end + + context 'when key is in both sources' do + it 'for test purposes, ensure the values are different' do + expect( + Gitlab::ApplicationSettingFetcher.current_application_settings.restricted_visibility_levels + ).not_to eq(organization_settings.restricted_visibility_levels) + end - described_class.home_page_url + it 'prefers ApplicationSettingFetcher' do + expect(described_class.restricted_visibility_levels).to eq( + Gitlab::ApplicationSettingFetcher.current_application_settings.restricted_visibility_levels + ) + end + end + + context 'when key is in neither' do + it 'raises NoMethodError' do + expect { described_class.foo }.to raise_error(NoMethodError) + end end end diff --git a/spec/models/organizations/organization_setting_spec.rb b/spec/models/organizations/organization_setting_spec.rb index 376d0b7fe77..dd90a4d0f58 100644 --- a/spec/models/organizations/organization_setting_spec.rb +++ b/spec/models/organizations/organization_setting_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Organizations::OrganizationSetting, type: :model, feature_category: :cell do let_it_be(:organization) { create(:organization) } + let_it_be(:organization_setting) { create(:organization_setting, organization: organization) } describe 'associations' do it { is_expected.to belong_to :organization } @@ -54,4 +55,41 @@ RSpec.describe Organizations::OrganizationSetting, type: :model, feature_categor end end end + + describe '.for_current_organization' do + let(:dummy_class) { Class.new { extend Organization::CurrentOrganization } } + + subject(:settings) { described_class.for_current_organization } + + context 'when there is no current organization' do + it { is_expected.to be_nil } + end + + context 'when there is a current organization' do + before do + dummy_class.current_organization = organization + end + + after do + dummy_class.current_organization = nil + end + + it 'returns current organization' do + expect(settings).to eq(organization_setting) + end + + context 'when current organization does not have settings' do + before do + allow(organization).to receive(:settings).and_return(nil) + end + + it 'returns new settings record' do + new_settings = settings + + expect(new_settings.organization).to eq(organization) + expect(new_settings.new_record?).to eq(true) + end + end + end + end end diff --git a/spec/scripts/lib/glfm/update_example_snapshots_spec.rb b/spec/scripts/lib/glfm/update_example_snapshots_spec.rb index 4897dbea09c..78cdb81f80c 100644 --- a/spec/scripts/lib/glfm/update_example_snapshots_spec.rb +++ b/spec/scripts/lib/glfm/update_example_snapshots_spec.rb @@ -746,7 +746,10 @@ RSpec.describe Glfm::UpdateExampleSnapshots, '#process', feature_category: :team "type": "text", "marks": [ { - "type": "strike" + "type": "strike", + "attrs": { + "htmlTag": null + } } ], "text": "Hi" |