Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-20 03:09:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-20 03:09:13 +0300
commitc0bc64e25edb4d7c3ac1d89de720f94782be5d2e (patch)
tree7cce86fcd83c9ba6fe7c3eb418f19a982d6eff3d /spec
parent1cd61065a0d86b492be5086906429ac5956e3672 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb47
-rw-r--r--spec/frontend/behaviors/copy_as_gfm_spec.js4
-rw-r--r--spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js4
-rw-r--r--spec/frontend/content_editor/extensions/code_suggestion_spec.js6
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js95
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb56
-rw-r--r--spec/models/organizations/organization_setting_spec.rb38
-rw-r--r--spec/scripts/lib/glfm/update_example_snapshots_spec.rb5
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 &quot;Markup&quot; 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"