diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 21:12:16 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-20 21:12:16 +0300 |
commit | 72c050db64bd61ae767f47c4fa2bc97b94a67592 (patch) | |
tree | 6e3b239ffcc70d9ca88bf3144d8459a86bed7c38 /spec | |
parent | 1d033298a5973bdbd9c56d4eb0f1d29265b153a6 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
25 files changed, 276 insertions, 465 deletions
diff --git a/spec/factories/airflow/dags.rb b/spec/factories/airflow/dags.rb deleted file mode 100644 index ca4276e2c8f..00000000000 --- a/spec/factories/airflow/dags.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -FactoryBot.define do - factory :airflow_dags, class: '::Airflow::Dags' do - sequence(:dag_name) { |n| "dag_name_#{n}" } - - project - end -end diff --git a/spec/fixtures/lib/gitlab/import_export/complex/project.json b/spec/fixtures/lib/gitlab/import_export/complex/project.json index afec1bb2585..a0ac70d7d9c 100644 --- a/spec/fixtures/lib/gitlab/import_export/complex/project.json +++ b/spec/fixtures/lib/gitlab/import_export/complex/project.json @@ -7877,6 +7877,95 @@ } } ], + "commit_notes": [ + { + "note": "Commit note 1", + "noteable_type": "Commit", + "author_id": 1, + "created_at": "2023-01-30T19:27:36.585Z", + "updated_at": "2023-02-10T14:43:01.308Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": "sha-notes", + "system": false, + "st_diff": null, + "updated_by_id": 1, + "type": null, + "position": null, + "original_position": null, + "resolved_at": null, + "resolved_by_id": null, + "discussion_id": "e3fde7d585c6467a7a5147e83617eb6daa61aaf4", + "change_position": null, + "resolved_by_push": null, + "confidential": null, + "last_edited_at": "2023-02-10T14:43:01.306Z", + "author": { + "name": "Administrator" + }, + "events": [ + { + "project_id": 1, + "author_id": 1, + "created_at": "2023-01-30T19:27:36.815Z", + "updated_at": "2023-01-30T19:27:36.815Z", + "action": "commented", + "target_type": "Note", + "fingerprint": null, + "push_event_payload": { + "commit_count": 1, + "action": "pushed", + "ref_type": "branch", + "commit_to": "sha-notes", + "ref": "master" + } + } + ] + }, + { + "note": "Commit note 2", + "noteable_type": "Commit", + "author_id": 1, + "created_at": "2023-02-10T14:44:08.138Z", + "updated_at": "2023-02-10T14:54:42.828Z", + "project_id": 1, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": "sha-notes", + "system": false, + "st_diff": null, + "updated_by_id": 1, + "type": null, + "position": null, + "original_position": null, + "resolved_at": null, + "resolved_by_id": null, + "discussion_id": "53ca55a01732aff4f17daecdf076853f4ab152eb", + "change_position": null, + "resolved_by_push": null, + "confidential": null, + "last_edited_at": "2023-02-10T14:54:42.827Z", + "author": { + "name": "Administrator" + }, + "events": [ + { + "project_id": 1, + "author_id": 1, + "created_at": "2023-02-10T16:37:16.659Z", + "updated_at": "2023-02-10T16:37:16.659Z", + "action": "commented", + "target_type": "Note", + "fingerprint": null + } + ] + } + ], "pipeline_schedules": [ { "id": 1, diff --git a/spec/fixtures/lib/gitlab/import_export/complex/tree/project/commit_notes.ndjson b/spec/fixtures/lib/gitlab/import_export/complex/tree/project/commit_notes.ndjson new file mode 100644 index 00000000000..b623c388b4f --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/complex/tree/project/commit_notes.ndjson @@ -0,0 +1,2 @@ +{"note":"Commit note 1","noteable_type":"Commit","author_id":1,"created_at":"2023-01-30T19:27:36.585Z","updated_at":"2023-02-10T14:43:01.308Z","project_id":5,"attachment":{"url":null},"line_code":null,"commit_id":"sha-notes","system":false,"st_diff":null,"updated_by_id":1,"type":null,"position":null,"original_position":null,"resolved_at":null,"resolved_by_id":null,"discussion_id":"e3fde7d585c6467a7a5147e83617eb6daa61aaf4","change_position":null,"resolved_by_push":null,"confidential":null,"last_edited_at":"2023-02-10T14:43:01.306Z","author":{"name":"Administrator"},"events":[{"project_id":1,"author_id":1,"created_at":"2023-01-30T19:27:36.815Z","updated_at":"2023-01-30T19:27:36.815Z","action":"commented","target_type":"Note","fingerprint":null,"push_event_payload":{"commit_count":1,"action":"pushed","ref_type":"branch","commit_to":"sha-notes","ref":"master"}}]} +{"note":"Commit note 2","noteable_type":"Commit","author_id":1,"created_at":"2023-02-10T14:44:08.138Z","updated_at":"2023-02-10T14:54:42.828Z","project_id":1,"attachment":{"url":null},"line_code":null,"commit_id":"sha-notes","system":false,"st_diff":null,"updated_by_id":1,"type":null,"position":null,"original_position":null,"resolved_at":null,"resolved_by_id":null,"discussion_id":"53ca55a01732aff4f17daecdf076853f4ab152eb","change_position":null,"resolved_by_push":null,"confidential":null,"last_edited_at":"2023-02-10T14:54:42.827Z","author":{"name":"Administrator"},"events":[{"project_id":1,"author_id":1,"created_at":"2023-02-10T16:37:16.659Z","updated_at":"2023-02-10T16:37:16.659Z","action":"commented","target_type":"Note","fingerprint":null}]} diff --git a/spec/frontend/airflow/dags/components/dags_spec.js b/spec/frontend/airflow/dags/components/dags_spec.js deleted file mode 100644 index f9cf4fc87af..00000000000 --- a/spec/frontend/airflow/dags/components/dags_spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import { GlAlert, GlPagination, GlTableLite } from '@gitlab/ui'; -import { mountExtended } from 'helpers/vue_test_utils_helper'; -import { TEST_HOST } from 'helpers/test_constants'; -import AirflowDags from '~/airflow/dags/components/dags.vue'; -import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; -import { mockDags } from './mock_data'; - -describe('AirflowDags', () => { - let wrapper; - - const createWrapper = ( - dags = [], - pagination = { page: 1, isLastPage: false, per_page: 2, totalItems: 0 }, - ) => { - wrapper = mountExtended(AirflowDags, { - propsData: { - dags, - pagination, - }, - }); - }; - - const findAlert = () => wrapper.findComponent(GlAlert); - const findEmptyState = () => wrapper.findByText('There are no DAGs to show'); - const findPagination = () => wrapper.findComponent(GlPagination); - - describe('default (no dags)', () => { - beforeEach(() => { - createWrapper(); - }); - - it('shows incubation warning', () => { - expect(findAlert().exists()).toBe(true); - }); - - it('shows empty state', () => { - expect(findEmptyState().exists()).toBe(true); - }); - - it('does not show pagination', () => { - expect(findPagination().exists()).toBe(false); - }); - }); - - describe('with dags', () => { - const createWrapperWithDags = (pagination = {}) => { - createWrapper(mockDags, { - page: 1, - isLastPage: false, - per_page: 2, - totalItems: 5, - ...pagination, - }); - }; - - const findDagsData = () => { - return wrapper - .findComponent(GlTableLite) - .findAll('tbody tr') - .wrappers.map((tr) => { - return tr.findAll('td').wrappers.map((td) => { - const timeAgo = td.findComponent(TimeAgo); - - if (timeAgo.exists()) { - return { - type: 'time', - value: timeAgo.props('time'), - }; - } - - return { - type: 'text', - value: td.text(), - }; - }); - }); - }; - - it('renders the table of Dags with data', () => { - createWrapperWithDags(); - - expect(findDagsData()).toEqual( - mockDags.map((x) => [ - { type: 'text', value: x.dag_name }, - { type: 'text', value: x.schedule }, - { type: 'time', value: x.next_run }, - { type: 'text', value: String(x.is_active) }, - { type: 'text', value: String(x.is_paused) }, - { type: 'text', value: x.fileloc }, - ]), - ); - }); - - describe('Pagination behaviour', () => { - it.each` - pagination | expected - ${{}} | ${{ value: 1, prevPage: null, nextPage: 2 }} - ${{ page: 2 }} | ${{ value: 2, prevPage: 1, nextPage: 3 }} - ${{ isLastPage: true, page: 2 }} | ${{ value: 2, prevPage: 1, nextPage: null }} - `('with $pagination, sets pagination props', ({ pagination, expected }) => { - createWrapperWithDags({ ...pagination }); - - expect(findPagination().props()).toMatchObject(expected); - }); - - it('generates link for each page', () => { - createWrapperWithDags(); - - const generateLink = findPagination().props('linkGen'); - - expect(generateLink(3)).toBe(`${TEST_HOST}/?page=3`); - }); - }); - }); -}); diff --git a/spec/frontend/airflow/dags/components/mock_data.js b/spec/frontend/airflow/dags/components/mock_data.js deleted file mode 100644 index 9547282517d..00000000000 --- a/spec/frontend/airflow/dags/components/mock_data.js +++ /dev/null @@ -1,67 +0,0 @@ -export const mockDags = [ - { - id: 1, - project_id: 7, - created_at: '2023-01-05T14:07:02.975Z', - updated_at: '2023-01-05T14:07:02.975Z', - has_import_errors: false, - is_active: false, - is_paused: true, - next_run: '2023-01-05T14:07:02.975Z', - dag_name: 'Dag number 1', - schedule: 'Manual', - fileloc: '/opt/dag.py', - }, - { - id: 2, - project_id: 7, - created_at: '2023-01-05T14:07:02.975Z', - updated_at: '2023-01-05T14:07:02.975Z', - has_import_errors: false, - is_active: false, - is_paused: true, - next_run: '2023-01-05T14:07:02.975Z', - dag_name: 'Dag number 2', - schedule: 'Manual', - fileloc: '/opt/dag.py', - }, - { - id: 3, - project_id: 7, - created_at: '2023-01-05T14:07:02.975Z', - updated_at: '2023-01-05T14:07:02.975Z', - has_import_errors: false, - is_active: false, - is_paused: true, - next_run: '2023-01-05T14:07:02.975Z', - dag_name: 'Dag number 3', - schedule: 'Manual', - fileloc: '/opt/dag.py', - }, - { - id: 4, - project_id: 7, - created_at: '2023-01-05T14:07:02.975Z', - updated_at: '2023-01-05T14:07:02.975Z', - has_import_errors: false, - is_active: false, - is_paused: true, - next_run: '2023-01-05T14:07:02.975Z', - dag_name: 'Dag number 4', - schedule: 'Manual', - fileloc: '/opt/dag.py', - }, - { - id: 5, - project_id: 7, - created_at: '2023-01-05T14:07:02.975Z', - updated_at: '2023-01-05T14:07:02.975Z', - has_import_errors: false, - is_active: false, - is_paused: true, - next_run: '2023-01-05T14:07:02.975Z', - dag_name: 'Dag number 5', - schedule: 'Manual', - fileloc: '/opt/dag.py', - }, -]; diff --git a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap index 2f441f0f747..4b7439f6fd2 100644 --- a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap +++ b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap @@ -53,23 +53,22 @@ exports[`Contributors charts should render charts and a RefSelector when loading Excluding merge commits. Limited to 6,000 commits. </span> - <div> - <glareachart-stub - annotations="" - class="gl-mb-5" - data="[object Object]" - height="264" - includelegendavgmax="true" - legendaveragetext="Avg" - legendcurrenttext="Current" - legendlayout="inline" - legendmaxtext="Max" - legendmintext="Min" - option="[object Object]" - thresholds="" - width="0" - /> - </div> + <glareachart-stub + annotations="" + class="gl-mb-5" + data="[object Object]" + height="264" + includelegendavgmax="true" + legendaveragetext="Avg" + legendcurrenttext="Current" + legendlayout="inline" + legendmaxtext="Max" + legendmintext="Min" + option="[object Object]" + responsive="" + thresholds="" + width="auto" + /> <div class="row" @@ -91,22 +90,21 @@ exports[`Contributors charts should render charts and a RefSelector when loading </p> - <div> - <glareachart-stub - annotations="" - data="[object Object]" - height="216" - includelegendavgmax="true" - legendaveragetext="Avg" - legendcurrenttext="Current" - legendlayout="inline" - legendmaxtext="Max" - legendmintext="Min" - option="[object Object]" - thresholds="" - width="0" - /> - </div> + <glareachart-stub + annotations="" + data="[object Object]" + height="216" + includelegendavgmax="true" + legendaveragetext="Avg" + legendcurrenttext="Current" + legendlayout="inline" + legendmaxtext="Max" + legendmintext="Min" + option="[object Object]" + responsive="" + thresholds="" + width="auto" + /> </div> </div> </div> diff --git a/spec/frontend/profile/account/components/update_username_spec.js b/spec/frontend/profile/account/components/update_username_spec.js index fa0e86a7b05..028c30cb291 100644 --- a/spec/frontend/profile/account/components/update_username_spec.js +++ b/spec/frontend/profile/account/components/update_username_spec.js @@ -1,8 +1,8 @@ import { GlModal } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { nextTick } from 'vue'; import { TEST_HOST } from 'helpers/test_constants'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { createAlert } from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status'; @@ -21,8 +21,10 @@ describe('UpdateUsername component', () => { let wrapper; let axiosMock; + const findNewUsernameInput = () => wrapper.findByTestId('new-username-input'); + const createComponent = (props = {}) => { - wrapper = shallowMount(UpdateUsername, { + wrapper = shallowMountExtended(UpdateUsername, { propsData: { ...defaultProps, ...props, @@ -80,11 +82,7 @@ describe('UpdateUsername component', () => { beforeEach(async () => { createComponent(); - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ newUsername }); - - await nextTick(); + await findNewUsernameInput().setValue(newUsername); }); it('confirmation modal contains proper header and body', async () => { diff --git a/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap b/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap index fc51825f15b..1545c52d7cb 100644 --- a/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap +++ b/spec/frontend/projects/pipelines/charts/components/__snapshots__/ci_cd_analytics_area_chart_spec.js.snap @@ -8,20 +8,19 @@ exports[`CiCdAnalyticsAreaChart matches the snapshot 1`] = ` Some title </p> - <div> - <glareachart-stub - annotations="" - data="[object Object],[object Object]" - height="300" - legendaveragetext="Avg" - legendcurrenttext="Current" - legendlayout="inline" - legendmaxtext="Max" - legendmintext="Min" - option="[object Object]" - thresholds="" - width="0" - /> - </div> + <glareachart-stub + annotations="" + data="[object Object],[object Object]" + height="300" + legendaveragetext="Avg" + legendcurrenttext="Current" + legendlayout="inline" + legendmaxtext="Max" + legendmintext="Min" + option="[object Object]" + responsive="" + thresholds="" + width="auto" + /> </div> `; diff --git a/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/resizable_chart_container_spec.js.snap b/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/resizable_chart_container_spec.js.snap deleted file mode 100644 index cdfe311acd9..00000000000 --- a/spec/frontend/vue_shared/components/resizable_chart/__snapshots__/resizable_chart_container_spec.js.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Resizable Chart Container renders the component 1`] = ` -<div> - <template> - <div - class="slot" - > - <span - class="width" - > - 0 - </span> - - <span - class="height" - > - 0 - </span> - </div> - </template> -</div> -`; diff --git a/spec/frontend/vue_shared/components/resizable_chart/resizable_chart_container_spec.js b/spec/frontend/vue_shared/components/resizable_chart/resizable_chart_container_spec.js deleted file mode 100644 index 7536df24ac6..00000000000 --- a/spec/frontend/vue_shared/components/resizable_chart/resizable_chart_container_spec.js +++ /dev/null @@ -1,64 +0,0 @@ -import { mount } from '@vue/test-utils'; -import $ from 'jquery'; -import { nextTick } from 'vue'; -import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue'; - -jest.mock('~/lib/utils/common_utils', () => ({ - debounceByAnimationFrame(callback) { - return jest.spyOn({ callback }, 'callback'); - }, -})); - -describe('Resizable Chart Container', () => { - let wrapper; - - beforeEach(() => { - wrapper = mount(ResizableChartContainer, { - scopedSlots: { - default: ` - <template #default="{ width, height }"> - <div class="slot"> - <span class="width">{{width}}</span> - <span class="height">{{height}}</span> - </div> - </template> - `, - }, - }); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders the component', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - it('updates the slot width and height props', async () => { - const width = 1920; - const height = 1080; - - // JSDOM mocks and sets clientWidth/clientHeight to 0 so we set manually - wrapper.vm.$refs.chartWrapper = { clientWidth: width, clientHeight: height }; - - $(document).trigger('content.resize'); - - await nextTick(); - const widthNode = wrapper.find('.slot > .width'); - const heightNode = wrapper.find('.slot > .height'); - - expect(parseInt(widthNode.text(), 10)).toEqual(width); - expect(parseInt(heightNode.text(), 10)).toEqual(height); - }); - - it('calls onResize on manual resize', () => { - $(document).trigger('content.resize'); - expect(wrapper.vm.debouncedResize).toHaveBeenCalled(); - }); - - it('calls onResize on page resize', () => { - window.dispatchEvent(new Event('resize')); - expect(wrapper.vm.debouncedResize).toHaveBeenCalled(); - }); -}); diff --git a/spec/lib/bulk_imports/projects/pipelines/commit_notes_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/commit_notes_pipeline_spec.rb new file mode 100644 index 00000000000..f5f31c83033 --- /dev/null +++ b/spec/lib/bulk_imports/projects/pipelines/commit_notes_pipeline_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BulkImports::Projects::Pipelines::CommitNotesPipeline, feature_category: :importers do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:bulk_import) { create(:bulk_import, user: user) } + let_it_be(:entity) do + create( + :bulk_import_entity, + :project_entity, + project: project, + bulk_import: bulk_import, + source_full_path: 'source/full/path', + destination_slug: 'destination-project', + destination_namespace: group.full_path + ) + end + + let(:ci_pipeline_note) do + { + "note" => "Commit note 1", + "noteable_type" => "Commit", + "author_id" => 1, + "created_at" => "2023-01-30T19:27:36.585Z", + "updated_at" => "2023-02-10T14:43:01.308Z", + "project_id" => 1, + "commit_id" => "sha-notes", + "system" => false, + "updated_by_id" => 1, + "discussion_id" => "e3fde7d585c6467a7a5147e83617eb6daa61aaf4", + "last_edited_at" => "2023-02-10T14:43:01.306Z", + "author" => { + "name" => "Administrator" + }, + "events" => [ + { + "project_id" => 1, + "author_id" => 1, + "action" => "commented", + "target_type" => "Note" + } + ] + } + end + + let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } + let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } + + subject(:pipeline) { described_class.new(context) } + + describe '#run' do + before do + group.add_owner(user) + + allow_next_instance_of(BulkImports::Common::Extractors::NdjsonExtractor) do |extractor| + allow(extractor).to receive(:extract).and_return( + BulkImports::Pipeline::ExtractedData.new(data: [ci_pipeline_note]) + ) + end + end + + it 'imports ci pipeline notes into destination project' do + expect { pipeline.run }.to change { project.notes.for_commit_id("sha-notes").count }.from(0).to(1) + end + end +end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 9df23776be8..63a470c82a1 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -1049,6 +1049,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do describe '#foreign_key_exists?' do let(:referenced_table_name) { '_test_gitlab_main_referenced' } let(:referencing_table_name) { '_test_gitlab_main_referencing' } + let(:schema) { 'public' } + let(:identifier) { "#{schema}.#{referencing_table_name}" } before do model.connection.execute(<<~SQL) @@ -1085,6 +1087,10 @@ RSpec.describe Gitlab::Database::MigrationHelpers do expect(model.foreign_key_exists?(referencing_table_name, target_table)).to be_truthy end + it 'finds existing foreign_keys by identifier' do + expect(model.foreign_key_exists?(identifier, target_table)).to be_truthy + end + it 'compares by column name if given' do expect(model.foreign_key_exists?(referencing_table_name, target_table, column: :user_id)).to be_falsey end diff --git a/spec/lib/gitlab/database/postgres_foreign_key_spec.rb b/spec/lib/gitlab/database/postgres_foreign_key_spec.rb index ae56f66737d..75f94bf2654 100644 --- a/spec/lib/gitlab/database/postgres_foreign_key_spec.rb +++ b/spec/lib/gitlab/database/postgres_foreign_key_spec.rb @@ -70,13 +70,29 @@ RSpec.describe Gitlab::Database::PostgresForeignKey, type: :model, feature_categ end describe '#by_constrained_table_name' do - it 'finds the foreign keys for the constrained table' do - expected = described_class.where(name: %w[fk_constrained_to_referenced fk_constrained_to_other_referenced]).to_a + let(:expected) { described_class.where(name: %w[fk_constrained_to_referenced fk_constrained_to_other_referenced]).to_a } + it 'finds the foreign keys for the constrained table' do expect(described_class.by_constrained_table_name(table_name("constrained_table"))).to match_array(expected) end end + describe '#by_constrained_table_name_or_identifier' do + let(:expected) { described_class.where(name: %w[fk_constrained_to_referenced fk_constrained_to_other_referenced]).to_a } + + context 'when using table name' do + it 'finds the foreign keys for the constrained table' do + expect(described_class.by_constrained_table_name_or_identifier(table_name("constrained_table"))).to match_array(expected) + end + end + + context 'when using identifier' do + it 'finds the foreign keys for the constrained table' do + expect(described_class.by_constrained_table_name_or_identifier(schema_table_name('constrained_table'))).to match_array(expected) + end + end + end + describe '#by_name' do it 'finds foreign keys by name' do expect(described_class.by_name('fk_constrained_to_referenced').pluck(:name)).to contain_exactly('fk_constrained_to_referenced') diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 9607ac18548..63f1e50804c 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -92,6 +92,20 @@ notes: - suggestions - diff_note_positions - review +commit_notes: +- award_emoji +- noteable +- author +- updated_by +- last_edited_by +- resolved_by +- todos +- events +- system_note_metadata +- note_diff_file +- suggestions +- diff_note_positions +- review label_links: - target - label diff --git a/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb b/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb index 7cc503eb66b..02419267f0e 100644 --- a/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb +++ b/spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb @@ -141,8 +141,8 @@ RSpec.describe Gitlab::ImportExport::FastHashSerializer, :with_license, feature_ expect(subject['ci_pipelines']).not_to be_empty end - it 'has ci pipeline notes' do - expect(subject['ci_pipelines'].first['notes']).not_to be_empty + it 'has commit notes' do + expect(subject['commit_notes']).not_to be_empty end it 'has labels with no associations' do diff --git a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb index 6053df8ba97..75012aa80ec 100644 --- a/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/relation_tree_restorer_spec.rb @@ -50,6 +50,7 @@ RSpec.describe Gitlab::ImportExport::Project::RelationTreeRestorer, feature_cate expect(project.custom_attributes.count).to eq(2) expect(project.project_badges.count).to eq(2) expect(project.snippets.count).to eq(1) + expect(project.commit_notes.count).to eq(3) end end end diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb index 85d8809e4c5..bb735d6689e 100644 --- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb @@ -582,6 +582,10 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer, feature_category: :i expect(@project.import_failures.size).to eq 0 end end + + it 'restores commit notes' do + expect(@project.commit_notes.count).to eq(3) + end end end diff --git a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb index adb4b0e382a..b87992c4594 100644 --- a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb @@ -240,10 +240,12 @@ RSpec.describe Gitlab::ImportExport::Project::TreeSaver, :with_license, feature_ expect(count).to eq(1) end + end - it 'has ci pipeline notes' do - expect(subject.first['notes']).not_to be_empty - end + context 'with commit_notes' do + let(:relation_name) { :commit_notes } + + it { is_expected.not_to be_empty } end context 'with labels' do @@ -475,6 +477,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeSaver, :with_license, feature_ end end + # rubocop: disable Metrics/AbcSize def setup_project release = create(:release) @@ -537,4 +540,5 @@ RSpec.describe Gitlab::ImportExport::Project::TreeSaver, :with_license, feature_ project end + # rubocop: enable Metrics/AbcSize end diff --git a/spec/lib/gitlab/import_export/references_configuration_spec.rb b/spec/lib/gitlab/import_export/references_configuration_spec.rb index ad165790b77..84c5b564cb1 100644 --- a/spec/lib/gitlab/import_export/references_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/references_configuration_spec.rb @@ -9,7 +9,7 @@ require 'spec_helper' # or to be blacklisted by using the import_export.yml configuration file. # Likewise, new models added to import_export.yml, will need to be added with their correspondent relations # to this spec. -RSpec.describe 'Import/Export Project configuration' do +RSpec.describe 'Import/Export Project configuration', feature_category: :importers do include ConfigurationHelper where(:relation_path, :relation_name) do diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 5c43cfec612..2384baabb6b 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -86,6 +86,7 @@ Note: - original_discussion_id - confidential - last_edited_at +- internal LabelLink: - id - target_type diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 5325ef5b5dd..a2461545a56 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -1097,7 +1097,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic it 'returns the distinct count of user actions within the specified time period' do expect(described_class.action_monthly_active_users(time_period)).to eq( { - action_monthly_active_users_web_ide_edit: 2, action_monthly_active_users_sfe_edit: 2, action_monthly_active_users_snippet_editor_edit: 2 } diff --git a/spec/models/airflow/dags_spec.rb b/spec/models/airflow/dags_spec.rb deleted file mode 100644 index ff3c4522779..00000000000 --- a/spec/models/airflow/dags_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Airflow::Dags, feature_category: :dataops do - describe 'associations' do - it { is_expected.to belong_to(:project) } - end - - describe 'validations' do - it { is_expected.to validate_presence_of(:project) } - it { is_expected.to validate_presence_of(:dag_name) } - it { is_expected.to validate_length_of(:dag_name).is_at_most(255) } - it { is_expected.to validate_length_of(:schedule).is_at_most(255) } - it { is_expected.to validate_length_of(:fileloc).is_at_most(255) } - end -end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 5304fec506e..9db1dde6294 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -939,6 +939,17 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do end end + describe '#commit_notes' do + let_it_be(:project) { create(:project) } + + it "returns project's commit notes" do + note_1 = create(:note_on_commit, project: project, commit_id: 'commit_id_1') + note_2 = create(:note_on_commit, project: project, commit_id: 'commit_id_2') + + expect(project.commit_notes).to match_array([note_1, note_2]) + end + end + describe '#personal_namespace_holder?' do let_it_be(:group) { create(:group) } let_it_be(:namespace_user) { create(:user) } diff --git a/spec/requests/projects/airflow/dags_controller_spec.rb b/spec/requests/projects/airflow/dags_controller_spec.rb deleted file mode 100644 index 2dcedf5f128..00000000000 --- a/spec/requests/projects/airflow/dags_controller_spec.rb +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Airflow::DagsController, feature_category: :dataops do - let_it_be(:non_member) { create(:user) } - let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group).tap { |p| p.add_developer(user) } } - let_it_be(:project) { create(:project, group: group).tap { |p| p.add_developer(user) } } - - let(:current_user) { user } - let(:feature_flag) { true } - - let_it_be(:dags) do - create_list(:airflow_dags, 5, project: project) - end - - let(:params) { { namespace_id: project.namespace.to_param, project_id: project } } - let(:extra_params) { {} } - - before do - sign_in(current_user) if current_user - stub_feature_flags(airflow_dags: false) - stub_feature_flags(airflow_dags: project) if feature_flag - list_dags - end - - shared_examples 'returns a 404 if feature flag disabled' do - context 'when :airflow_dags disabled' do - let(:feature_flag) { false } - - it 'is 404' do - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - - describe 'GET index' do - it 'renders the template' do - expect(response).to render_template('projects/airflow/dags/index') - end - - describe 'pagination' do - before do - stub_const("Projects::Airflow::DagsController::MAX_DAGS_PER_PAGE", 2) - dags - - list_dags - end - - context 'when out of bounds' do - let(:params) { extra_params.merge(page: 10000) } - - it 'redirects to last page' do - last_page = (dags.size + 1) / 2 - expect(response).to redirect_to(project_airflow_dags_path(project, page: last_page)) - end - end - - context 'when bad page' do - let(:params) { extra_params.merge(page: 's') } - - it 'uses first page' do - expect(assigns(:pagination)).to include( - page: 1, - is_last_page: false, - per_page: 2, - total_items: dags.size) - end - end - end - - it 'does not perform N+1 sql queries' do - control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { list_dags } - - create_list(:airflow_dags, 1, project: project) - - expect { list_dags }.not_to exceed_all_query_limit(control_count) - end - - context 'when user is not logged in' do - let(:current_user) { nil } - - it 'redirects to login' do - expect(response).to redirect_to(new_user_session_path) - end - end - - context 'when user is not a member' do - let(:current_user) { non_member } - - it 'returns a 404' do - expect(response).to have_gitlab_http_status(:not_found) - end - end - - it_behaves_like 'returns a 404 if feature flag disabled' - end - - private - - def list_dags - get project_airflow_dags_path(project), params: params - end -end diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb index b74819d2ac7..08da55162b4 100644 --- a/spec/support/shared_contexts/navbar_structure_context.rb +++ b/spec/support/shared_contexts/navbar_structure_context.rb @@ -85,8 +85,7 @@ RSpec.shared_context 'project navbar structure' do _('Metrics'), _('Error Tracking'), _('Alerts'), - _('Incidents'), - _('Airflow') + _('Incidents') ] }, { |