diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-08 12:09:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-08 12:09:42 +0300 |
commit | f4ea1f8998fd64bcd02280514b91f103f830d5ce (patch) | |
tree | 14ff4a76b07da90dbaa9c75398b3bd2a79ac85c6 /spec | |
parent | ae192a2f1410b5f71397a64df76238b9d3b0afbe (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
15 files changed, 305 insertions, 145 deletions
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb index 2b856811e02..4465d7e29be 100644 --- a/spec/features/merge_request/user_sees_versions_spec.rb +++ b/spec/features/merge_request/user_sees_versions_spec.rb @@ -101,6 +101,7 @@ RSpec.describe 'Merge request > User sees versions', :js do outdated_diff_note.save! refresh + wait_for_requests expect(page).to have_css(".diffs .notes[data-discussion-id='#{outdated_diff_note.discussion_id}']") end diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb index f77a42ee506..20bf1a2939c 100644 --- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb +++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb @@ -26,6 +26,8 @@ RSpec.describe 'User comments on a diff', :js do let(:user) { create(:user) } before do + stub_feature_flags(paginated_notes: false) + project.add_maintainer(user) sign_in(user) diff --git a/spec/fixtures/glfm/example_snapshots/examples_index.yml b/spec/fixtures/glfm/example_snapshots/examples_index.yml index 8ca656cbc56..08f6f88af9e 100644 --- a/spec/fixtures/glfm/example_snapshots/examples_index.yml +++ b/spec/fixtures/glfm/example_snapshots/examples_index.yml @@ -2012,9 +2012,6 @@ 06_15__inlines__textual_content__003: spec_txt_example_position: 673 source_specification: commonmark -07_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__001: +07_01__gitlab_specific_markdown__footnotes__001: spec_txt_example_position: 674 - source_specification: commonmark -08_01__second_gitlab_specific_section_with_examples__strong_but_with_html__001: - spec_txt_example_position: 675 - source_specification: commonmark + source_specification: gitlab diff --git a/spec/fixtures/glfm/example_snapshots/html.yml b/spec/fixtures/glfm/example_snapshots/html.yml index a1870f808f2..fcbc7c0572a 100644 --- a/spec/fixtures/glfm/example_snapshots/html.yml +++ b/spec/fixtures/glfm/example_snapshots/html.yml @@ -130,9 +130,7 @@ </li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>foo - </p><ul bullet="*"><li><p>bar - </p><ul bullet="*"><li><p>baz</p></li></ul></li></ul></li></ul> + <ul bullet="*"><li><p>foo</p><ul bullet="*"><li><p>bar</p><ul bullet="*"><li><p>baz</p></li></ul></li></ul></li></ul> 02_01__preliminaries__tabs__010: canonical: | <h1>Foo</h1> @@ -1849,7 +1847,7 @@ <p data-sourcepos="2:1-2:5" dir="auto"><em>baz</em></p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__030: canonical: | <script> @@ -1872,7 +1870,7 @@ <p data-sourcepos="5:1-5:4" dir="auto">okay</p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__032: canonical: | <?php @@ -1888,7 +1886,7 @@ <p data-sourcepos="6:1-6:4" dir="auto">okay</p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__033: canonical: | <!DOCTYPE html> @@ -1915,7 +1913,7 @@ <p data-sourcepos="13:1-13:4" dir="auto">okay</p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__035: canonical: |2 <!-- foo --> @@ -1927,7 +1925,7 @@ foo --></span></code></pre>\n<copy-code></copy-code>\n</div>" wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__036: canonical: |2 <div> @@ -3898,10 +3896,7 @@ </li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>foo - </p><ul bullet="*"><li><p>bar - </p><ul bullet="*"><li><p>baz - </p><ul bullet="*"><li><p>boo</p></li></ul></li></ul></li></ul></li></ul> + <ul bullet="*"><li><p>foo</p><ul bullet="*"><li><p>bar</p><ul bullet="*"><li><p>baz</p><ul bullet="*"><li><p>boo</p></li></ul></li></ul></li></ul></li></ul> 05_02__container_blocks__list_items__043: canonical: | <ul> @@ -3937,8 +3932,7 @@ </li> </ol> wysiwyg: |- - <ol parens="false"><li><p>foo - </p><ul bullet="*"><li><p>bar</p></li></ul></li></ol> + <ol parens="false"><li><p>foo</p><ul bullet="*"><li><p>bar</p></li></ul></li></ol> 05_02__container_blocks__list_items__045: canonical: | <ol start="10"> @@ -4072,8 +4066,7 @@ <li data-sourcepos="9:1-9:5">baz</li> </ul> wysiwyg: |- - Error - check implementation: - Hast node of type "input" not supported by this converter. Please, provide an specification. + <ul bullet="*"><li><p>baz</p></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__050: canonical: | <ol> @@ -4190,9 +4183,7 @@ </li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>foo - </p><ul bullet="*"><li><p>bar - </p><ul bullet="*"><li><p>baz</p><p>bim</p></li></ul></li></ul></li></ul> + <ul bullet="*"><li><p>foo</p><ul bullet="*"><li><p>bar</p><ul bullet="*"><li><p>baz</p><p>bim</p></li></ul></li></ul></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__056: canonical: | <ul> @@ -4216,7 +4207,7 @@ </ul> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__057: canonical: | <ul> @@ -4248,7 +4239,7 @@ </div> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__058: canonical: | <ul> @@ -4508,8 +4499,7 @@ <li data-sourcepos="5:1-5:3">d</li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>a - </p><ul bullet="*"><li><p>b</p><p>c</p></li></ul></li><li><p>d</p></li></ul> + <ul bullet="*"><li><p>a</p><ul bullet="*"><li><p>b</p><p>c</p></li></ul></li><li><p>d</p></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__068: canonical: | <ul> @@ -4530,8 +4520,7 @@ <li data-sourcepos="4:1-4:3">c</li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>a - </p><blockquote multiline="false"><p>b</p></blockquote></li><li><p>c</p></li></ul> + <ul bullet="*"><li><p>a</p><blockquote multiline="false"><p>b</p></blockquote></li><li><p>c</p></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__069: canonical: | <ul> @@ -4558,8 +4547,7 @@ <li data-sourcepos="6:1-6:3">d</li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>a - </p><blockquote multiline="false"><p>b</p></blockquote><pre class="content-editor-code-block undefined code highlight"><code>c</code></pre></li><li><p>d</p></li></ul> + <ul bullet="*"><li><p>a</p><blockquote multiline="false"><p>b</p></blockquote><pre class="content-editor-code-block undefined code highlight"><code>c</code></pre></li><li><p>d</p></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__070: canonical: | <ul> @@ -4589,8 +4577,7 @@ </li> </ul> wysiwyg: |- - <ul bullet="*"><li><p>a - </p><ul bullet="*"><li><p>b</p></li></ul></li></ul> + <ul bullet="*"><li><p>a</p><ul bullet="*"><li><p>b</p></li></ul></li></ul> 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__072: canonical: | <ol> @@ -7217,7 +7204,7 @@ <p data-sourcepos="1:1-2:25" dir="auto">foo </p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__014: canonical: | <p>foo <!-- not a comment -- two hyphens --></p> @@ -7241,7 +7228,7 @@ <p data-sourcepos="1:1-1:21" dir="auto">foo <?php echo $a; ?></p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__017: canonical: | <p>foo <!ELEMENT br EMPTY></p> @@ -7249,7 +7236,7 @@ <p data-sourcepos="1:1-1:23" dir="auto">foo </p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__018: canonical: | <p>foo <![CDATA[>&<]]></p> @@ -7257,7 +7244,7 @@ <p data-sourcepos="1:1-1:19" dir="auto">foo &</p> wysiwyg: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__019: canonical: | <p>foo <a href="ö"></p> @@ -7462,23 +7449,17 @@ <p data-sourcepos="1:1-1:19" dir="auto">Multiple spaces</p> wysiwyg: |- <p>Multiple spaces</p> -07_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__001: - canonical: | - <p><strong>bold</strong></p> - static: |- - <p data-sourcepos="1:1-1:8" dir="auto"><strong>bold</strong></p> - wysiwyg: |- - <p><strong>bold</strong></p> -08_01__second_gitlab_specific_section_with_examples__strong_but_with_html__001: - canonical: | - <p><strong> - bold - </strong></p> +07_01__gitlab_specific_markdown__footnotes__001: + canonical: "" static: |- - <strong> - bold - </strong> + <p data-sourcepos="1:1-1:27" dir="auto">footnote reference tag <sup class="footnote-ref"><a href="#fn-1-2118" id="fnref-1-2118" data-footnote-ref>1</a></sup></p> + <section data-footnotes class="footnotes"> + <ol> + <li id="fn-1-2118"> + <p data-sourcepos="3:7-3:19">footnote text <a href="#fnref-1-2118" data-footnote-backref aria-label="Back to content" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p> + </li> + </ol> + </section> wysiwyg: |- - <p><strong> - bold - </strong></p> + Error - check implementation: + Hast node of type "sup" not supported by this converter. Please, provide an specification. diff --git a/spec/fixtures/glfm/example_snapshots/markdown.yml b/spec/fixtures/glfm/example_snapshots/markdown.yml index f3a4de8e90d..d1fd16b10ce 100644 --- a/spec/fixtures/glfm/example_snapshots/markdown.yml +++ b/spec/fixtures/glfm/example_snapshots/markdown.yml @@ -2195,9 +2195,7 @@ Foo χρῆν 06_15__inlines__textual_content__003: | Multiple spaces -07_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__001: | - **bold** -08_01__second_gitlab_specific_section_with_examples__strong_but_with_html__001: | - <strong> - bold - </strong> +07_01__gitlab_specific_markdown__footnotes__001: | + footnote reference tag [^1] + + [^1]: footnote text diff --git a/spec/fixtures/glfm/example_snapshots/prosemirror_json.yml b/spec/fixtures/glfm/example_snapshots/prosemirror_json.yml index 1c357f26279..04196c26af0 100644 --- a/spec/fixtures/glfm/example_snapshots/prosemirror_json.yml +++ b/spec/fixtures/glfm/example_snapshots/prosemirror_json.yml @@ -233,7 +233,7 @@ "content": [ { "type": "text", - "text": "foo\n" + "text": "foo" } ] }, @@ -251,7 +251,7 @@ "content": [ { "type": "text", - "text": "bar\n" + "text": "bar" } ] }, @@ -3121,16 +3121,16 @@ Hast node of type "style" not supported by this converter. Please, provide an specification. 04_06__leaf_blocks__html_blocks__029: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__030: |- Error - check implementation: Hast node of type "script" not supported by this converter. Please, provide an specification. 04_06__leaf_blocks__html_blocks__031: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__032: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__033: |- { "type": "doc", @@ -3142,10 +3142,10 @@ } 04_06__leaf_blocks__html_blocks__034: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__035: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 04_06__leaf_blocks__html_blocks__036: |- Error - check implementation: Hast node of type "div" not supported by this converter. Please, provide an specification. @@ -6691,7 +6691,7 @@ "content": [ { "type": "text", - "text": "foo\n" + "text": "foo" } ] }, @@ -6709,7 +6709,7 @@ "content": [ { "type": "text", - "text": "bar\n" + "text": "bar" } ] }, @@ -6727,7 +6727,7 @@ "content": [ { "type": "text", - "text": "baz\n" + "text": "baz" } ] }, @@ -6856,7 +6856,7 @@ "content": [ { "type": "text", - "text": "foo\n" + "text": "foo" } ] }, @@ -7100,8 +7100,33 @@ ] } 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__049: |- - Error - check implementation: - Hast node of type "input" not supported by this converter. Please, provide an specification. + { + "type": "doc", + "content": [ + { + "type": "bulletList", + "attrs": { + "bullet": "*" + }, + "content": [ + { + "type": "listItem", + "content": [ + { + "type": "paragraph", + "content": [ + { + "type": "text", + "text": "baz" + } + ] + } + ] + } + ] + } + ] + } 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__050: |- { "type": "doc", @@ -7346,7 +7371,7 @@ "content": [ { "type": "text", - "text": "foo\n" + "text": "foo" } ] }, @@ -7364,7 +7389,7 @@ "content": [ { "type": "text", - "text": "bar\n" + "text": "bar" } ] }, @@ -7411,10 +7436,10 @@ } 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__056: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__057: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 05_02__container_blocks__list_items__motivation__task_list_items_extension__lists__058: |- { "type": "doc", @@ -8018,7 +8043,7 @@ "content": [ { "type": "text", - "text": "a\n" + "text": "a" } ] }, @@ -8091,7 +8116,7 @@ "content": [ { "type": "text", - "text": "a\n" + "text": "a" } ] }, @@ -8150,7 +8175,7 @@ "content": [ { "type": "text", - "text": "a\n" + "text": "a" } ] }, @@ -8250,7 +8275,7 @@ "content": [ { "type": "text", - "text": "a\n" + "text": "a" } ] }, @@ -16576,7 +16601,7 @@ } 06_11__inlines__raw_html__013: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__014: |- { "type": "doc", @@ -16618,13 +16643,13 @@ } 06_11__inlines__raw_html__016: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__017: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__018: |- Error - check implementation: - Hast node of type "comment" not supported by this converter. Please, provide an specification. + Cannot destructure property 'className' of 'hastNode.properties' as it is undefined. 06_11__inlines__raw_html__019: |- { "type": "doc", @@ -16988,43 +17013,6 @@ } ] } -07_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__001: |- - { - "type": "doc", - "content": [ - { - "type": "paragraph", - "content": [ - { - "type": "text", - "marks": [ - { - "type": "bold" - } - ], - "text": "bold" - } - ] - } - ] - } -08_01__second_gitlab_specific_section_with_examples__strong_but_with_html__001: |- - { - "type": "doc", - "content": [ - { - "type": "paragraph", - "content": [ - { - "type": "text", - "marks": [ - { - "type": "bold" - } - ], - "text": "\nbold\n" - } - ] - } - ] - } +07_01__gitlab_specific_markdown__footnotes__001: |- + Error - check implementation: + Hast node of type "sup" not supported by this converter. Please, provide an specification. diff --git a/spec/frontend/notes/stores/actions_spec.js b/spec/frontend/notes/stores/actions_spec.js index ecb213590ad..4ecfbc5de1f 100644 --- a/spec/frontend/notes/stores/actions_spec.js +++ b/spec/frontend/notes/stores/actions_spec.js @@ -1382,6 +1382,29 @@ describe('Actions Notes Store', () => { ], ); }); + + it('dispatches `fetchDiscussionsBatch` action if `paginatedMrDiscussions` feature flag is enabled', () => { + window.gon = { features: { paginatedMrDiscussions: true } }; + + return testAction( + actions.fetchDiscussions, + { path: 'test-path', filter: 'test-filter', persistFilter: 'test-persist-filter' }, + null, + [], + [ + { + type: 'fetchDiscussionsBatch', + payload: { + config: { + params: { notes_filter: 'test-filter', persist_filter: 'test-persist-filter' }, + }, + path: 'test-path', + perPage: 20, + }, + }, + ], + ); + }); }); describe('fetchDiscussionsBatch', () => { @@ -1401,6 +1424,7 @@ describe('Actions Notes Store', () => { null, [ { type: mutationTypes.ADD_OR_UPDATE_DISCUSSIONS, payload: { discussion } }, + { type: mutationTypes.SET_DONE_FETCHING_BATCH_DISCUSSIONS, payload: true }, { type: mutationTypes.SET_FETCHING_DISCUSSIONS, payload: false }, ], [{ type: 'updateResolvableDiscussionsCounts' }], diff --git a/spec/frontend/notes/stores/mutation_spec.js b/spec/frontend/notes/stores/mutation_spec.js index da1547ab6e7..e0a0fc43ffe 100644 --- a/spec/frontend/notes/stores/mutation_spec.js +++ b/spec/frontend/notes/stores/mutation_spec.js @@ -883,4 +883,16 @@ describe('Notes Store mutations', () => { expect(state.discussions[0].position).toEqual(position); }); }); + + describe('SET_DONE_FETCHING_BATCH_DISCUSSIONS', () => { + it('should set doneFetchingBatchDiscussions', () => { + const state = { + doneFetchingBatchDiscussions: false, + }; + + mutations.SET_DONE_FETCHING_BATCH_DISCUSSIONS(state, true); + + expect(state.doneFetchingBatchDiscussions).toEqual(true); + }); + }); }); diff --git a/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js b/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js index b574b217180..fe9b40e91c9 100644 --- a/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js +++ b/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js @@ -5,6 +5,7 @@ import CiIcon from '~/vue_shared/components/ci_icon.vue'; import axios from '~/lib/utils/axios_utils'; import PipelineStage from '~/pipelines/components/pipelines_list/pipeline_stage.vue'; import eventHub from '~/pipelines/event_hub'; +import waitForPromises from 'helpers/wait_for_promises'; import { stageReply } from '../../mock_data'; const dropdownPath = 'path.json'; @@ -58,6 +59,7 @@ describe('Pipelines stage component', () => { const findDropdownMenuTitle = () => wrapper.find('[data-testid="pipeline-stage-dropdown-menu-title"]'); const findMergeTrainWarning = () => wrapper.find('[data-testid="warning-message-merge-trains"]'); + const findLoadingState = () => wrapper.find('[data-testid="pipeline-stage-loading-state"]'); const openStageDropdown = () => { findDropdownToggle().trigger('click'); @@ -66,6 +68,29 @@ describe('Pipelines stage component', () => { }); }; + describe('loading state', () => { + beforeEach(async () => { + createComponent({ updateDropdown: true }); + + mock.onGet(dropdownPath).reply(200, stageReply); + + await openStageDropdown(); + }); + + it('displays loading state while jobs are being fetched', () => { + const expectedLoadingText = `${PipelineStage.i18n.loadingTextLineOne} ${PipelineStage.i18n.loadingTextLineTwo}`; + + expect(findLoadingState().exists()).toBe(true); + expect(findLoadingState().text()).toBe(expectedLoadingText); + }); + + it('does not display loading state after jobs have been fetched', async () => { + await waitForPromises(); + + expect(findLoadingState().exists()).toBe(false); + }); + }); + describe('default appearance', () => { beforeEach(() => { createComponent(); diff --git a/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js index ee5937ab7e7..b95ddb47b27 100644 --- a/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js +++ b/spec/frontend/work_items/components/work_item_links/work_item_links_spec.js @@ -23,32 +23,26 @@ describe('WorkItemLinks', () => { wrapper.destroy(); }); - it('is collapsed by default', () => { - expect(findToggleButton().props('icon')).toBe('angle-down'); - expect(findLinksBody().exists()).toBe(false); + it('is expanded by default', () => { + expect(findToggleButton().props('icon')).toBe('angle-up'); + expect(findLinksBody().exists()).toBe(true); }); it('expands on click toggle button', async () => { findToggleButton().vm.$emit('click'); await nextTick(); - expect(findToggleButton().props('icon')).toBe('angle-up'); - expect(findLinksBody().exists()).toBe(true); + expect(findToggleButton().props('icon')).toBe('angle-down'); + expect(findLinksBody().exists()).toBe(false); }); - it('displays empty state if there are no links', async () => { - findToggleButton().vm.$emit('click'); - await nextTick(); - + it('displays empty state if there are no links', () => { expect(findEmptyState().exists()).toBe(true); expect(findToggleAddFormButton().exists()).toBe(true); }); describe('add link form', () => { it('displays form on click add button and hides form on cancel', async () => { - findToggleButton().vm.$emit('click'); - await nextTick(); - expect(findEmptyState().exists()).toBe(true); findToggleAddFormButton().vm.$emit('click'); diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb index 9040731d8fd..16b55dd7c74 100644 --- a/spec/lib/gitlab/email/receiver_spec.rb +++ b/spec/lib/gitlab/email/receiver_spec.rb @@ -11,6 +11,7 @@ RSpec.describe Gitlab::Email::Receiver do let_it_be(:project) { create(:project) } let(:handler) { double(:handler, project: project, execute: true, metrics_event: nil, metrics_params: nil) } + let(:client_id) { 'email/jake@example.com' } it 'correctly finds the mail key' do expect(Gitlab::Email::Handler).to receive(:for).with(an_instance_of(Mail::Message), 'gitlabhq/gitlabhq+auth_token').and_return(handler) @@ -33,7 +34,7 @@ RSpec.describe Gitlab::Email::Receiver do metadata = receiver.mail_metadata expect(metadata.keys).to match_array(%i(mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients)) - expect(metadata[:meta]).to include(client_id: 'email/jake@example.com', project: project.full_path) + expect(metadata[:meta]).to include(client_id: client_id, project: project.full_path) expect(metadata[meta_key]).to eq(meta_value) end end @@ -126,6 +127,49 @@ RSpec.describe Gitlab::Email::Receiver do it_behaves_like 'failed receive' end + context "when the email's To field is blank" do + before do + stub_incoming_email_setting(enabled: true, address: "incoming+%{key}@appmail.example.com") + end + + let(:email_raw) do + <<~EMAIL + Delivered-To: incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com + From: "jake@example.com" <jake@example.com> + Bcc: "support@example.com" <support@example.com> + + Email content + EMAIL + end + + let(:meta_key) { :delivered_to } + let(:meta_value) { ["incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com"] } + + it_behaves_like 'successful receive' + end + + context "when the email's From field is blank" do + before do + stub_incoming_email_setting(enabled: true, address: "incoming+%{key}@appmail.example.com") + end + + let(:email_raw) do + <<~EMAIL + Delivered-To: incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com + To: "support@example.com" <support@example.com> + + Email content + EMAIL + end + + let(:meta_key) { :delivered_to } + let(:meta_value) { ["incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com"] } + + it_behaves_like 'successful receive' do + let(:client_id) { 'email/' } + end + end + context 'when the email was auto generated with X-Autoreply header' do let(:email_raw) { fixture_file('emails/auto_reply.eml') } let(:expected_error) { Gitlab::Email::AutoGeneratedEmailError } diff --git a/spec/requests/api/markdown_snapshot_spec.rb b/spec/requests/api/markdown_snapshot_spec.rb index fdb55a62802..37607a4e866 100644 --- a/spec/requests/api/markdown_snapshot_spec.rb +++ b/spec/requests/api/markdown_snapshot_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' # See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#markdown-snapshot-testing # for documentation on this spec. RSpec.describe API::Markdown, 'Snapshot' do + glfm_specification_dir = File.expand_path('../../../glfm_specification', __dir__) glfm_example_snapshots_dir = File.expand_path('../../fixtures/glfm/example_snapshots', __dir__) - include_context 'API::Markdown Snapshot shared context', glfm_example_snapshots_dir + include_context 'with API::Markdown Snapshot shared context', glfm_specification_dir, glfm_example_snapshots_dir end diff --git a/spec/requests/projects/merge_requests_controller_spec.rb b/spec/requests/projects/merge_requests_controller_spec.rb index 3b1ce569033..6580fc8b80f 100644 --- a/spec/requests/projects/merge_requests_controller_spec.rb +++ b/spec/requests/projects/merge_requests_controller_spec.rb @@ -3,6 +3,70 @@ require 'spec_helper' RSpec.describe Projects::MergeRequestsController do + describe 'GET #discussions' do + let_it_be(:merge_request) { create(:merge_request) } + let_it_be(:project) { merge_request.project } + let_it_be(:user) { merge_request.author } + let_it_be(:discussion) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } + let_it_be(:discussion_reply) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, in_reply_to: discussion) } + let_it_be(:state_event) { create(:resource_state_event, merge_request: merge_request) } + let_it_be(:discussion_2) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } + let_it_be(:discussion_3) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) } + + before do + login_as(user) + end + + context 'pagination' do + def get_discussions(**params) + get discussions_project_merge_request_path(project, merge_request, params: params.merge(format: :json)) + end + + it 'returns paginated notes and cursor based on per_page param' do + get_discussions(per_page: 2) + + discussions = Gitlab::Json.parse(response.body) + notes = discussions.flat_map { |d| d['notes'] } + + expect(discussions.count).to eq(2) + expect(notes).to match([ + a_hash_including('id' => discussion.id.to_s), + a_hash_including('id' => discussion_reply.id.to_s), + a_hash_including('type' => 'StateNote') + ]) + + cursor = response.header['X-Next-Page-Cursor'] + expect(cursor).to be_present + + get_discussions(per_page: 1, cursor: cursor) + + discussions = Gitlab::Json.parse(response.body) + notes = discussions.flat_map { |d| d['notes'] } + + expect(discussions.count).to eq(1) + expect(notes).to match([ + a_hash_including('id' => discussion_2.id.to_s) + ]) + end + + context 'when paginated_mr_discussions is disabled' do + before do + stub_feature_flags(paginated_mr_discussions: false) + end + + it 'returns all discussions and ignores per_page param' do + get_discussions(per_page: 2) + + discussions = Gitlab::Json.parse(response.body) + notes = discussions.flat_map { |d| d['notes'] } + + expect(discussions.count).to eq(4) + expect(notes.count).to eq(5) + end + end + end + end + context 'token authentication' do context 'when public project' do let_it_be(:public_project) { create(:project, :public) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6c9a11587d3..b39153e79fc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -53,8 +53,10 @@ end require 'rainbow/ext/string' Rainbow.enabled = false -require_relative('../ee/spec/spec_helper') if Gitlab.ee? +# Require JH first because we need override some EE methods with JH methods, +# if we load EE first, we can't find JH modules in prepend_mod method require_relative('../jh/spec/spec_helper') if Gitlab.jh? +require_relative('../ee/spec/spec_helper') if Gitlab.ee? # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. diff --git a/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb b/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb index 531a176d76b..de52b58982e 100644 --- a/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb +++ b/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb @@ -4,7 +4,9 @@ require 'spec_helper' # See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#markdown-snapshot-testing # for documentation on this spec. -RSpec.shared_context 'API::Markdown Snapshot shared context' do |glfm_example_snapshots_dir| +# rubocop:disable Layout/LineLength +RSpec.shared_context 'with API::Markdown Snapshot shared context' do |glfm_specification_dir, glfm_example_snapshots_dir| + # rubocop:enable Layout/LineLength include ApiHelpers markdown_examples, html_examples = %w[markdown.yml html.yml].map do |file_name| @@ -12,7 +14,11 @@ RSpec.shared_context 'API::Markdown Snapshot shared context' do |glfm_example_sn YAML.safe_load(yaml, symbolize_names: true, aliases: true) end - if focused_markdown_examples_string = ENV['FOCUSED_MARKDOWN_EXAMPLES'] + normalizations_yaml = File.read( + "#{glfm_specification_dir}/input/gitlab_flavored_markdown/glfm_example_normalizations.yml") + normalizations_by_example_name = YAML.safe_load(normalizations_yaml, symbolize_names: true, aliases: true) + + if (focused_markdown_examples_string = ENV['FOCUSED_MARKDOWN_EXAMPLES']) focused_markdown_examples = focused_markdown_examples_string.split(',').map(&:strip).map(&:to_sym) markdown_examples.select! { |example_name| focused_markdown_examples.include?(example_name) } end @@ -20,17 +26,38 @@ RSpec.shared_context 'API::Markdown Snapshot shared context' do |glfm_example_sn markdown_examples.each do |name, markdown| context "for #{name}" do let(:html) { html_examples.fetch(name).fetch(:static) } + let(:normalizations) { normalizations_by_example_name.dig(name, :html, :static, :snapshot) } it "verifies conversion of GLFM to HTML", :unlimited_max_formatted_output_length do api_url = api "/markdown" + # noinspection RubyResolve + normalized_html = normalize_html(html, normalizations) + post api_url, params: { text: markdown, gfm: true } expect(response).to be_successful response_body = Gitlab::Json.parse(response.body) # Some requests have the HTML in the `html` key, others in the `body` key. response_html = response_body['body'] ? response_body.fetch('body') : response_body.fetch('html') + # noinspection RubyResolve + normalized_response_html = normalize_html(response_html, normalizations) + + expect(normalized_response_html).to eq(normalized_html) + end + + def normalize_html(html, normalizations) + return html unless normalizations + + normalized_html = html.dup + normalizations.each_value do |normalization_entry| + normalization_entry.each do |normalization| + regex = normalization.fetch(:regex) + replacement = normalization.fetch(:replacement) + normalized_html.gsub!(%r{#{regex}}, replacement) + end + end - expect(response_html).to eq(html) + normalized_html end end end |