diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-10 00:09:12 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-10 00:09:12 +0300 |
commit | d183d2d76bcc25f983c0836805c712af096bcc2f (patch) | |
tree | 982987f91e1cf268dbad55e51c4ea57292abbbd6 /spec | |
parent | 453634293e24164ffaa5cd708e47a1cebc07bcd3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
8 files changed, 182 insertions, 63 deletions
diff --git a/spec/frontend/airflow/dags/components/incubation_alert_spec.js b/spec/frontend/airflow/dags/components/incubation_alert_spec.js deleted file mode 100644 index 29188de8025..00000000000 --- a/spec/frontend/airflow/dags/components/incubation_alert_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import { mount } from '@vue/test-utils'; -import { GlAlert, GlButton, GlLink } from '@gitlab/ui'; -import IncubationAlert from '~/airflow/dags/components/incubation_alert.vue'; - -describe('IncubationAlert', () => { - let wrapper; - - const findAlert = () => wrapper.findComponent(GlAlert); - - const findButton = () => wrapper.findComponent(GlButton); - - const findHref = () => wrapper.findComponent(GlLink); - - beforeEach(() => { - wrapper = mount(IncubationAlert); - }); - - it('displays link to issue', () => { - expect(findButton().attributes().href).toBe( - 'https://gitlab.com/gitlab-org/incubation-engineering/airflow/meta/-/issues/2', - ); - }); - - it('displays link to handbook', () => { - expect(findHref().attributes().href).toBe( - 'https://about.gitlab.com/handbook/engineering/incubation/airflow/', - ); - }); - - it('is removed if dismissed', async () => { - await wrapper.find('[aria-label="Dismiss"]').trigger('click'); - - expect(findAlert().exists()).toBe(false); - }); -}); diff --git a/spec/frontend/import_entities/import_groups/components/import_table_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_spec.js index 8d06c196d70..480f1bad8d4 100644 --- a/spec/frontend/import_entities/import_groups/components/import_table_spec.js +++ b/spec/frontend/import_entities/import_groups/components/import_table_spec.js @@ -7,7 +7,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { createAlert } from '~/flash'; -import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status'; +import { HTTP_STATUS_OK, HTTP_STATUS_TOO_MANY_REQUESTS } from '~/lib/utils/http_status'; import axios from '~/lib/utils/axios_utils'; import { STATUSES } from '~/import_entities/constants'; import { i18n, ROOT_NAMESPACE } from '~/import_entities/import_groups/constants'; @@ -270,8 +270,6 @@ describe('import table', () => { }, }); - axiosMock.onPost('/import/bulk_imports.json').reply(HTTP_STATUS_BAD_REQUEST); - await waitForPromises(); await findImportButtons()[0].trigger('click'); await waitForPromises(); @@ -283,6 +281,28 @@ describe('import table', () => { ); }); + it('displays inline error if importing group reports rate limit', async () => { + createComponent({ + bulkImportSourceGroups: () => ({ + nodes: [FAKE_GROUP], + pageInfo: FAKE_PAGE_INFO, + versionValidation: FAKE_VERSION_VALIDATION, + }), + importGroups: () => { + const error = new Error(); + error.response = { status: HTTP_STATUS_TOO_MANY_REQUESTS }; + throw error; + }, + }); + + await waitForPromises(); + await findImportButtons()[0].trigger('click'); + await waitForPromises(); + + expect(createAlert).not.toHaveBeenCalled(); + expect(wrapper.find('tbody tr').text()).toContain(i18n.ERROR_TOO_MANY_REQUESTS); + }); + describe('pagination', () => { const bulkImportSourceGroupsQueryMock = jest.fn().mockResolvedValue({ nodes: [FAKE_GROUP], diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index c51e098556c..0a05c558d45 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -3717,4 +3717,28 @@ RSpec.describe Group, feature_category: :subgroups do end end end + + describe '#readme_project' do + it 'returns groups project containing metadata' do + readme_project = create(:project, path: Group::README_PROJECT_PATH, namespace: group) + create(:project, namespace: group) + + expect(group.readme_project).to eq(readme_project) + end + end + + describe '#group_readme' do + it 'returns readme from group readme project' do + create(:project, :repository, path: Group::README_PROJECT_PATH, namespace: group) + + expect(group.group_readme.name).to eq('README.md') + expect(group.group_readme.data).to include('testme') + end + + it 'returns nil if no readme project is present' do + create(:project, :repository, namespace: group) + + expect(group.group_readme).to be(nil) + end + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 466c5574146..2e2355ba710 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -314,6 +314,34 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev expect(subject).to be_valid end end + + describe '#validate_target_project' do + let(:merge_request) do + build(:merge_request, source_project: project, target_project: project, importing: importing) + end + + let(:project) { build_stubbed(:project) } + let(:importing) { false } + + context 'when projects #merge_requests_enabled? is true' do + it { expect(merge_request.valid?(false)).to eq true } + end + + context 'when projects #merge_requests_enabled? is false' do + let(:project) { build_stubbed(:project, merge_requests_enabled: false) } + + it 'is invalid' do + expect(merge_request.valid?(false)).to eq false + expect(merge_request.errors.full_messages).to contain_exactly('Target project has disabled merge requests') + end + + context 'when #import? is true' do + let(:importing) { true } + + it { expect(merge_request.valid?(false)).to eq true } + end + end + end end describe 'callbacks' do diff --git a/spec/requests/api/graphql/subscriptions/notes/created_spec.rb b/spec/requests/api/graphql/subscriptions/notes/created_spec.rb index 7161b17d0a8..f955c14ef3b 100644 --- a/spec/requests/api/graphql/subscriptions/notes/created_spec.rb +++ b/spec/requests/api/graphql/subscriptions/notes/created_spec.rb @@ -115,4 +115,63 @@ RSpec.describe 'Subscriptions::Notes::Created', feature_category: :team_planning end end end + + context 'when resource events are triggering note subscription' do + let_it_be(:label1) { create(:label, project: project, title: 'foo') } + let_it_be(:label2) { create(:label, project: project, title: 'bar') } + + subject(:response) do + subscription_response do + # this creates note defined with let lazily and triggers the subscription event + resource_event + end + end + + context 'when user is unauthorized' do + let(:resource_event) { create(:resource_label_event, issue: task, label: label1) } + + it "does not receive discussion data" do + expect(response).to be_nil + end + end + + context 'when user is authorized' do + let(:current_user) { guest } + let(:resource_event) { create(:resource_label_event, issue: task, label: label1) } + + it "receives created synthetic note as a discussion" do + response + + event = ResourceLabelEvent.find(resource_event.id) + discussion_id = event.discussion_id + discussion_gid = ::Gitlab::GlobalId.as_global_id(discussion_id, model_name: 'Discussion').to_s + note_gid = ::Gitlab::GlobalId.as_global_id(discussion_id, model_name: 'LabelNote').to_s + + expect(response_note['id']).to eq(note_gid) + expect(discussion['id']).to eq(discussion_gid) + expect(discussion_notes.size).to eq(1) + expect(discussion_notes.pluck('id')).to match_array([note_gid]) + end + + context 'when several label events are created' do + let(:resource_event) do + ResourceEvents::ChangeLabelsService.new(task, current_user).execute(added_labels: [label1, label2]) + end + + it "receives created synthetic note as a discussion" do + response + + event = ResourceLabelEvent.where(label_id: [label1, label2]).first + discussion_id = event.discussion_id + discussion_gid = ::Gitlab::GlobalId.as_global_id(discussion_id, model_name: 'Discussion').to_s + note_gid = ::Gitlab::GlobalId.as_global_id(discussion_id, model_name: 'LabelNote').to_s + + expect(response_note['id']).to eq(note_gid) + expect(discussion['id']).to eq(discussion_gid) + expect(discussion_notes.size).to eq(1) + expect(discussion_notes.pluck('id')).to match_array([note_gid]) + end + end + end + end end diff --git a/spec/services/resource_events/change_labels_service_spec.rb b/spec/services/resource_events/change_labels_service_spec.rb index 9b0ca54a394..d94b49de9d7 100644 --- a/spec/services/resource_events/change_labels_service_spec.rb +++ b/spec/services/resource_events/change_labels_service_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' -RSpec.describe ResourceEvents::ChangeLabelsService do +# feature category is shared among plan(issues, epics), monitor(incidents), create(merge request) stages +RSpec.describe ResourceEvents::ChangeLabelsService, feature_category: :shared do let_it_be(:project) { create(:project) } let_it_be(:author) { create(:user) } let_it_be(:issue) { create(:issue, project: project) } @@ -86,12 +87,30 @@ RSpec.describe ResourceEvents::ChangeLabelsService do let(:added) { [labels[0]] } let(:removed) { [labels[1]] } + it_behaves_like 'creating timeline events' + it 'creates all label events in a single query' do expect(ApplicationRecord).to receive(:legacy_bulk_insert).once.and_call_original expect { change_labels }.to change { resource.resource_label_events.count }.from(0).to(2) end - it_behaves_like 'creating timeline events' + context 'when resource is a work item' do + it 'triggers note created subscription' do + expect(GraphqlTriggers).to receive(:work_item_note_created) + + change_labels + end + end + + context 'when resource is an MR' do + let(:resource) { create(:merge_request, source_project: project) } + + it 'does not trigger note created subscription' do + expect(GraphqlTriggers).not_to receive(:work_item_note_created) + + change_labels + end + end end describe 'usage data' do diff --git a/spec/support/shared_examples/models/resource_event_shared_examples.rb b/spec/support/shared_examples/models/resource_event_shared_examples.rb index 8cab2de076d..038ff33c68a 100644 --- a/spec/support/shared_examples/models/resource_event_shared_examples.rb +++ b/spec/support/shared_examples/models/resource_event_shared_examples.rb @@ -160,6 +160,16 @@ RSpec.shared_examples 'a resource event for merge requests' do end end end + + context 'on callbacks' do + it 'does not trigger note created subscription' do + event = build(described_class.name.underscore.to_sym, merge_request: merge_request1) + + expect(GraphqlTriggers).not_to receive(:work_item_note_created) + expect(event).not_to receive(:trigger_note_subscription_create) + event.save! + end + end end RSpec.shared_examples 'a note for work item resource event' do @@ -172,4 +182,14 @@ RSpec.shared_examples 'a note for work item resource event' do expect(event.work_item_synthetic_system_note.class.name).to eq(event.synthetic_note_class.name) end + + context 'on callbacks' do + it 'triggers note created subscription' do + event = build(described_class.name.underscore.to_sym, issue: work_item) + + expect(GraphqlTriggers).to receive(:work_item_note_created) + expect(event).to receive(:trigger_note_subscription_create).and_call_original + event.save! + end + end end diff --git a/spec/views/layouts/snippets.html.haml_spec.rb b/spec/views/layouts/snippets.html.haml_spec.rb index 5c182f715d6..1e6963a6526 100644 --- a/spec/views/layouts/snippets.html.haml_spec.rb +++ b/spec/views/layouts/snippets.html.haml_spec.rb @@ -9,34 +9,18 @@ RSpec.describe 'layouts/snippets', feature_category: :source_code_management do end describe 'sidebar' do - context 'when feature flag is on' do - context 'when signed in' do - let(:user) { build_stubbed(:user) } - - it 'renders the "Your work" sidebar' do - render - - expect(rendered).to have_css('aside.nav-sidebar[aria-label="Your work"]') - end - end - - context 'when not signed in' do - let(:user) { nil } + context 'when signed in' do + let(:user) { build_stubbed(:user) } - it 'renders no sidebar' do - render + it 'renders the "Your work" sidebar' do + render - expect(rendered).not_to have_css('aside.nav-sidebar') - end + expect(rendered).to have_css('aside.nav-sidebar[aria-label="Your work"]') end end - context 'when feature flag is off' do - before do - stub_feature_flags(your_work_sidebar: false) - end - - let(:user) { build_stubbed(:user) } + context 'when not signed in' do + let(:user) { nil } it 'renders no sidebar' do render |