Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5ca32d2dac
commit
3e9e2cd52e
24 changed files with 237 additions and 70 deletions
|
@ -1 +1 @@
|
||||||
1.45.0
|
1.46.0
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlButton } from '@gitlab/ui';
|
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions, mapState } from 'vuex';
|
||||||
|
import { __ } from '~/locale';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlButton,
|
GlButton,
|
||||||
},
|
},
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
mixins: [Tracking.mixin()],
|
mixins: [Tracking.mixin()],
|
||||||
|
computed: {
|
||||||
|
...mapState({ isNewListShowing: ({ addColumnForm }) => addColumnForm.visible }),
|
||||||
|
tooltip() {
|
||||||
|
return this.isNewListShowing ? __('The list creation wizard is already open') : '';
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['setAddColumnFormVisibility']),
|
...mapActions(['setAddColumnFormVisibility']),
|
||||||
handleClick() {
|
handleClick() {
|
||||||
|
@ -19,7 +29,14 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="gl-ml-3 gl-display-flex gl-align-items-center" data-testid="boards-create-list">
|
<div
|
||||||
<gl-button variant="confirm" @click="handleClick">{{ __('Create list') }} </gl-button>
|
v-gl-tooltip="tooltip"
|
||||||
|
:tabindex="isNewListShowing ? '0' : undefined"
|
||||||
|
class="gl-ml-3 gl-display-flex gl-align-items-center"
|
||||||
|
data-testid="boards-create-list"
|
||||||
|
>
|
||||||
|
<gl-button :disabled="isNewListShowing" variant="confirm" @click="handleClick"
|
||||||
|
>{{ __('Create list') }}
|
||||||
|
</gl-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: linear_ee_group_ancestor_scopes
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70708
|
||||||
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341350
|
||||||
|
milestone: '14.4'
|
||||||
|
type: development
|
||||||
|
group: group::access
|
||||||
|
default_enabled: false
|
|
@ -485,7 +485,7 @@ config:
|
||||||
|
|
||||||
agent:
|
agent:
|
||||||
monitor:
|
monitor:
|
||||||
eventTypes: ["drop"]
|
eventTypes: ["drop"] # Note: possible values are documented at https://docs.cilium.io/en/stable/cmdref/cilium_monitor/
|
||||||
```
|
```
|
||||||
|
|
||||||
The Cilium monitor log for traffic is logged out by the
|
The Cilium monitor log for traffic is logged out by the
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module BulkImports
|
module BulkImports
|
||||||
module Groups
|
module Common
|
||||||
module Pipelines
|
module Pipelines
|
||||||
class BoardsPipeline
|
class BoardsPipeline
|
||||||
include NdjsonPipeline
|
include NdjsonPipeline
|
|
@ -36,7 +36,7 @@ module BulkImports
|
||||||
stage: 1
|
stage: 1
|
||||||
},
|
},
|
||||||
boards: {
|
boards: {
|
||||||
pipeline: BulkImports::Groups::Pipelines::BoardsPipeline,
|
pipeline: BulkImports::Common::Pipelines::BoardsPipeline,
|
||||||
stage: 2
|
stage: 2
|
||||||
},
|
},
|
||||||
finisher: {
|
finisher: {
|
||||||
|
|
|
@ -23,9 +23,13 @@ module BulkImports
|
||||||
pipeline: BulkImports::Projects::Pipelines::IssuesPipeline,
|
pipeline: BulkImports::Projects::Pipelines::IssuesPipeline,
|
||||||
stage: 3
|
stage: 3
|
||||||
},
|
},
|
||||||
|
boards: {
|
||||||
|
pipeline: BulkImports::Common::Pipelines::BoardsPipeline,
|
||||||
|
stage: 4
|
||||||
|
},
|
||||||
finisher: {
|
finisher: {
|
||||||
pipeline: BulkImports::Common::Pipelines::EntityFinisher,
|
pipeline: BulkImports::Common::Pipelines::EntityFinisher,
|
||||||
stage: 4
|
stage: 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,14 +11,15 @@
|
||||||
module Gitlab
|
module Gitlab
|
||||||
class SidekiqEnq
|
class SidekiqEnq
|
||||||
def enqueue_jobs(now = Time.now.to_f.to_s, sorted_sets = Sidekiq::Scheduled::SETS)
|
def enqueue_jobs(now = Time.now.to_f.to_s, sorted_sets = Sidekiq::Scheduled::SETS)
|
||||||
start_time = ::Gitlab::Metrics::System.monotonic_time
|
|
||||||
jobs = redundant_jobs = 0
|
|
||||||
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs', status: 'start')
|
|
||||||
|
|
||||||
# A job's "score" in Redis is the time at which it should be processed.
|
# A job's "score" in Redis is the time at which it should be processed.
|
||||||
# Just check Redis for the set of jobs with a timestamp before now.
|
# Just check Redis for the set of jobs with a timestamp before now.
|
||||||
Sidekiq.redis do |conn|
|
Sidekiq.redis do |conn|
|
||||||
sorted_sets.each do |sorted_set|
|
sorted_sets.each do |sorted_set|
|
||||||
|
start_time = ::Gitlab::Metrics::System.monotonic_time
|
||||||
|
jobs = redundant_jobs = 0
|
||||||
|
|
||||||
|
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs', status: 'start', sorted_set: sorted_set)
|
||||||
|
|
||||||
# Get the next item in the queue if it's score (time to execute) is <= now.
|
# Get the next item in the queue if it's score (time to execute) is <= now.
|
||||||
# We need to go through the list one at a time to reduce the risk of something
|
# We need to go through the list one at a time to reduce the risk of something
|
||||||
# going wrong between the time jobs are popped from the scheduled queue and when
|
# going wrong between the time jobs are popped from the scheduled queue and when
|
||||||
|
@ -35,11 +36,16 @@ module Gitlab
|
||||||
redundant_jobs += 1
|
redundant_jobs += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end_time = ::Gitlab::Metrics::System.monotonic_time
|
||||||
|
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs',
|
||||||
|
status: 'done',
|
||||||
|
sorted_set: sorted_set,
|
||||||
|
jobs_count: jobs,
|
||||||
|
redundant_jobs_count: redundant_jobs,
|
||||||
|
duration_s: end_time - start_time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end_time = ::Gitlab::Metrics::System.monotonic_time
|
|
||||||
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs', status: 'done', jobs_count: jobs, redundant_jobs_count: redundant_jobs, duration_s: end_time - start_time)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34065,6 +34065,9 @@ msgstr ""
|
||||||
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
|
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The list creation wizard is already open"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The maximum file size allowed is %{size}."
|
msgid "The maximum file size allowed is %{size}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ settings:
|
||||||
jest:
|
jest:
|
||||||
jestConfigFile: 'jest.config.js'
|
jestConfigFile: 'jest.config.js'
|
||||||
globals:
|
globals:
|
||||||
getJSONFixture: false
|
|
||||||
loadFixtures: false
|
loadFixtures: false
|
||||||
setFixtures: false
|
setFixtures: false
|
||||||
rules:
|
rules:
|
||||||
|
|
|
@ -20,6 +20,11 @@ Did you run bin/rake frontend:fixtures?`,
|
||||||
return fs.readFileSync(absolutePath, 'utf8');
|
return fs.readFileSync(absolutePath, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use `import` to load a JSON fixture instead.
|
||||||
|
* See https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#use-fixtures,
|
||||||
|
* https://gitlab.com/gitlab-org/gitlab/-/issues/339346.
|
||||||
|
*/
|
||||||
export const getJSONFixture = (relativePath) => JSON.parse(getFixture(relativePath));
|
export const getJSONFixture = (relativePath) => JSON.parse(getFixture(relativePath));
|
||||||
|
|
||||||
export const resetHTMLFixture = () => {
|
export const resetHTMLFixture = () => {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { GlButton } from '@gitlab/ui';
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
|
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
|
||||||
|
import { createStore } from '~/boards/stores';
|
||||||
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
describe('BoardAddNewColumnTrigger', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
const findBoardsCreateList = () => wrapper.findByTestId('boards-create-list');
|
||||||
|
const findTooltipText = () => getBinding(findBoardsCreateList().element, 'gl-tooltip');
|
||||||
|
|
||||||
|
const mountComponent = () => {
|
||||||
|
wrapper = mountExtended(BoardAddNewColumnTrigger, {
|
||||||
|
directives: {
|
||||||
|
GlTooltip: createMockDirective(),
|
||||||
|
},
|
||||||
|
store: createStore(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mountComponent();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when button is active', () => {
|
||||||
|
it('does not show the tooltip', () => {
|
||||||
|
const tooltip = findTooltipText();
|
||||||
|
|
||||||
|
expect(tooltip.value).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders an enabled button', () => {
|
||||||
|
const button = wrapper.find(GlButton);
|
||||||
|
|
||||||
|
expect(button.props('disabled')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when button is disabled', () => {
|
||||||
|
it('shows the tooltip', async () => {
|
||||||
|
wrapper.find(GlButton).vm.$emit('click');
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
const tooltip = findTooltipText();
|
||||||
|
|
||||||
|
expect(tooltip.value).toBe('The list creation wizard is already open');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,11 +1,13 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import jsYaml from 'js-yaml';
|
import jsYaml from 'js-yaml';
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
import { getJSONFixture } from 'helpers/fixtures';
|
import { getJSONFixture } from 'helpers/fixtures';
|
||||||
|
|
||||||
export const loadMarkdownApiResult = (testName) => {
|
export const loadMarkdownApiResult = (testName) => {
|
||||||
const fixturePathPrefix = `api/markdown/${testName}.json`;
|
const fixturePathPrefix = `api/markdown/${testName}.json`;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
const fixture = getJSONFixture(fixturePathPrefix);
|
const fixture = getJSONFixture(fixturePathPrefix);
|
||||||
return fixture.body || fixture.html;
|
return fixture.body || fixture.html;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable import/no-deprecated */
|
||||||
|
|
||||||
import { getJSONFixture } from 'helpers/fixtures';
|
import { getJSONFixture } from 'helpers/fixtures';
|
||||||
import { TEST_HOST } from 'helpers/test_constants';
|
import { TEST_HOST } from 'helpers/test_constants';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
||||||
import '~/lib/utils/common_utils';
|
import '~/lib/utils/common_utils';
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
|
import { getJSONFixture } from 'helpers/fixtures';
|
||||||
import { visitUrl } from '~/lib/utils/url_utility';
|
import { visitUrl } from '~/lib/utils/url_utility';
|
||||||
|
|
||||||
jest.mock('~/lib/utils/url_utility', () => ({
|
jest.mock('~/lib/utils/url_utility', () => ({
|
||||||
|
@ -66,6 +68,7 @@ describe('deprecatedJQueryDropdown', () => {
|
||||||
loadFixtures('static/deprecated_jquery_dropdown.html');
|
loadFixtures('static/deprecated_jquery_dropdown.html');
|
||||||
test.dropdownContainerElement = $('.dropdown.inline');
|
test.dropdownContainerElement = $('.dropdown.inline');
|
||||||
test.$dropdownMenuElement = $('.dropdown-menu', test.dropdownContainerElement);
|
test.$dropdownMenuElement = $('.dropdown-menu', test.dropdownContainerElement);
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
test.projectsData = getJSONFixture('static/projects.json');
|
test.projectsData = getJSONFixture('static/projects.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
import { getJSONFixture, setHTMLFixture } from 'helpers/fixtures';
|
import { getJSONFixture, setHTMLFixture } from 'helpers/fixtures';
|
||||||
import FilterableList from '~/filterable_list';
|
import FilterableList from '~/filterable_list';
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ describe('FilterableList', () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="js-projects-list-holder"></div>
|
<div class="js-projects-list-holder"></div>
|
||||||
`);
|
`);
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
getJSONFixture('static/projects.json');
|
getJSONFixture('static/projects.json');
|
||||||
form = document.querySelector('form#project-filter-form');
|
form = document.querySelector('form#project-filter-form');
|
||||||
filter = document.querySelector('.js-projects-list-filter');
|
filter = document.querySelector('.js-projects-list-filter');
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
import { getJSONFixture, setHTMLFixture } from 'helpers/fixtures';
|
import { getJSONFixture, setHTMLFixture } from 'helpers/fixtures';
|
||||||
import ProjectsFilterableList from '~/projects/projects_filterable_list';
|
import ProjectsFilterableList from '~/projects/projects_filterable_list';
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ describe('ProjectsFilterableList', () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="js-projects-list-holder"></div>
|
<div class="js-projects-list-holder"></div>
|
||||||
`);
|
`);
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
getJSONFixture('static/projects.json');
|
getJSONFixture('static/projects.json');
|
||||||
form = document.querySelector('form#project-filter-form');
|
form = document.querySelector('form#project-filter-form');
|
||||||
filter = document.querySelector('.js-projects-list-filter');
|
filter = document.querySelector('.js-projects-list-filter');
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { setGlobalDateToFakeDate } from 'helpers/fake_date';
|
||||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||||
import { TEST_HOST } from 'helpers/test_constants';
|
import { TEST_HOST } from 'helpers/test_constants';
|
||||||
import Translate from '~/vue_shared/translate';
|
import Translate from '~/vue_shared/translate';
|
||||||
import { getJSONFixture, loadHTMLFixture, setHTMLFixture } from './__helpers__/fixtures';
|
import { loadHTMLFixture, setHTMLFixture } from './__helpers__/fixtures';
|
||||||
import { initializeTestTimeout } from './__helpers__/timeout';
|
import { initializeTestTimeout } from './__helpers__/timeout';
|
||||||
import customMatchers from './matchers';
|
import customMatchers from './matchers';
|
||||||
import { setupManualMocks } from './mocks/mocks_helper';
|
import { setupManualMocks } from './mocks/mocks_helper';
|
||||||
|
@ -43,7 +43,6 @@ Vue.use(Translate);
|
||||||
|
|
||||||
// convenience wrapper for migration from Karma
|
// convenience wrapper for migration from Karma
|
||||||
Object.assign(global, {
|
Object.assign(global, {
|
||||||
getJSONFixture,
|
|
||||||
loadFixtures: loadHTMLFixture,
|
loadFixtures: loadHTMLFixture,
|
||||||
setFixtures: setHTMLFixture,
|
setFixtures: setHTMLFixture,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
|
import { getJSONFixture } from 'helpers/fixtures';
|
||||||
import { trimText } from 'helpers/text_helper';
|
import { trimText } from 'helpers/text_helper';
|
||||||
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue';
|
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue';
|
||||||
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
|
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
|
||||||
|
@ -11,6 +13,7 @@ describe('ProjectListItem component', () => {
|
||||||
let vm;
|
let vm;
|
||||||
let options;
|
let options;
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
const project = getJSONFixture('static/projects.json')[0];
|
const project = getJSONFixture('static/projects.json')[0];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui';
|
||||||
import { mount, createLocalVue } from '@vue/test-utils';
|
import { mount, createLocalVue } from '@vue/test-utils';
|
||||||
import { head } from 'lodash';
|
import { head } from 'lodash';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
|
import { getJSONFixture } from 'helpers/fixtures';
|
||||||
import { trimText } from 'helpers/text_helper';
|
import { trimText } from 'helpers/text_helper';
|
||||||
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
|
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
|
||||||
import ProjectSelector from '~/vue_shared/components/project_selector/project_selector.vue';
|
import ProjectSelector from '~/vue_shared/components/project_selector/project_selector.vue';
|
||||||
|
@ -11,6 +13,7 @@ const localVue = createLocalVue();
|
||||||
describe('ProjectSelector component', () => {
|
describe('ProjectSelector component', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let vm;
|
let vm;
|
||||||
|
// eslint-disable-next-line import/no-deprecated
|
||||||
const allProjects = getJSONFixture('static/projects.json');
|
const allProjects = getJSONFixture('static/projects.json');
|
||||||
const searchResults = allProjects.slice(0, 5);
|
const searchResults = allProjects.slice(0, 5);
|
||||||
let selected = [];
|
let selected = [];
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe BulkImports::Common::Pipelines::BoardsPipeline 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(:board_data) do
|
||||||
|
{
|
||||||
|
"name" => "Test Board",
|
||||||
|
"lists" => [
|
||||||
|
{
|
||||||
|
"list_type" => "backlog",
|
||||||
|
"position" => 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"list_type" => "closed",
|
||||||
|
"position" => 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"list_type" => "label",
|
||||||
|
"position" => 2,
|
||||||
|
"label" => {
|
||||||
|
"title" => "test",
|
||||||
|
"type" => "GroupLabel",
|
||||||
|
"group_id" => group.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:tracker) { create(:bulk_import_tracker, entity: entity) }
|
||||||
|
let(:context) { BulkImports::Pipeline::Context.new(tracker) }
|
||||||
|
|
||||||
|
subject { described_class.new(context) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow_next_instance_of(BulkImports::Common::Extractors::NdjsonExtractor) do |extractor|
|
||||||
|
allow(extractor).to receive(:extract).and_return(BulkImports::Pipeline::ExtractedData.new(data: board_data))
|
||||||
|
end
|
||||||
|
group.add_owner(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when issue board belongs to a project' do
|
||||||
|
let_it_be(:entity) do
|
||||||
|
create(
|
||||||
|
:bulk_import_entity,
|
||||||
|
source_type: :project_entity,
|
||||||
|
project: project,
|
||||||
|
bulk_import: bulk_import,
|
||||||
|
source_full_path: 'source/full/path',
|
||||||
|
destination_name: 'My Destination Group',
|
||||||
|
destination_namespace: group.full_path
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#run' do
|
||||||
|
it 'imports issue boards into destination project' do
|
||||||
|
expect { subject.run }.to change(::Board, :count).by(1)
|
||||||
|
board = project.boards.find_by(name: board_data["name"])
|
||||||
|
expect(board).to be
|
||||||
|
expect(board.project.id).to eq(project.id)
|
||||||
|
expect(board.lists.count).to eq(3)
|
||||||
|
expect(board.lists.map(&:list_type).sort).to match_array(%w(backlog closed label))
|
||||||
|
expect(board.lists.find_by(list_type: "label").label.title).to eq("test")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when issue board belongs to a group' do
|
||||||
|
let_it_be(:entity) do
|
||||||
|
create(
|
||||||
|
:bulk_import_entity,
|
||||||
|
group: group,
|
||||||
|
bulk_import: bulk_import,
|
||||||
|
source_full_path: 'source/full/path',
|
||||||
|
destination_name: 'My Destination Group',
|
||||||
|
destination_namespace: group.full_path
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#run' do
|
||||||
|
it 'imports issue boards into destination group' do
|
||||||
|
expect { subject.run }.to change(::Board, :count).by(1)
|
||||||
|
board = group.boards.find_by(name: board_data["name"])
|
||||||
|
expect(board).to be
|
||||||
|
expect(board.group.id).to eq(group.id)
|
||||||
|
expect(board.lists.count).to eq(3)
|
||||||
|
expect(board.lists.map(&:list_type).sort).to match_array(%w(backlog closed label))
|
||||||
|
expect(board.lists.find_by(list_type: "label").label.title).to eq("test")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,49 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
RSpec.describe BulkImports::Groups::Pipelines::BoardsPipeline do
|
|
||||||
let_it_be(:user) { create(:user) }
|
|
||||||
let_it_be(:group) { create(:group) }
|
|
||||||
let_it_be(:bulk_import) { create(:bulk_import, user: user) }
|
|
||||||
let_it_be(:filepath) { 'spec/fixtures/bulk_imports/gz/boards.ndjson.gz' }
|
|
||||||
let_it_be(:entity) do
|
|
||||||
create(
|
|
||||||
:bulk_import_entity,
|
|
||||||
group: group,
|
|
||||||
bulk_import: bulk_import,
|
|
||||||
source_full_path: 'source/full/path',
|
|
||||||
destination_name: 'My Destination Group',
|
|
||||||
destination_namespace: group.full_path
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
|
|
||||||
let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
|
|
||||||
|
|
||||||
let(:tmpdir) { Dir.mktmpdir }
|
|
||||||
|
|
||||||
before do
|
|
||||||
FileUtils.copy_file(filepath, File.join(tmpdir, 'boards.ndjson.gz'))
|
|
||||||
group.add_owner(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { described_class.new(context) }
|
|
||||||
|
|
||||||
describe '#run' do
|
|
||||||
it 'imports group boards into destination group and removes tmpdir' do
|
|
||||||
allow(Dir).to receive(:mktmpdir).and_return(tmpdir)
|
|
||||||
allow_next_instance_of(BulkImports::FileDownloadService) do |service|
|
|
||||||
allow(service).to receive(:execute)
|
|
||||||
end
|
|
||||||
|
|
||||||
expect { subject.run }.to change(Board, :count).by(1)
|
|
||||||
|
|
||||||
lists = group.boards.find_by(name: 'first board').lists
|
|
||||||
|
|
||||||
expect(lists.count).to eq(3)
|
|
||||||
expect(lists.first.label.title).to eq('TSL')
|
|
||||||
expect(lists.second.label.title).to eq('Sosync')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -14,7 +14,7 @@ RSpec.describe BulkImports::Groups::Stage do
|
||||||
[1, BulkImports::Common::Pipelines::LabelsPipeline],
|
[1, BulkImports::Common::Pipelines::LabelsPipeline],
|
||||||
[1, BulkImports::Groups::Pipelines::MilestonesPipeline],
|
[1, BulkImports::Groups::Pipelines::MilestonesPipeline],
|
||||||
[1, BulkImports::Groups::Pipelines::BadgesPipeline],
|
[1, BulkImports::Groups::Pipelines::BadgesPipeline],
|
||||||
[2, BulkImports::Groups::Pipelines::BoardsPipeline]
|
[2, BulkImports::Common::Pipelines::BoardsPipeline]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ RSpec.describe BulkImports::Projects::Stage do
|
||||||
[1, BulkImports::Projects::Pipelines::RepositoryPipeline],
|
[1, BulkImports::Projects::Pipelines::RepositoryPipeline],
|
||||||
[2, BulkImports::Common::Pipelines::LabelsPipeline],
|
[2, BulkImports::Common::Pipelines::LabelsPipeline],
|
||||||
[3, BulkImports::Projects::Pipelines::IssuesPipeline],
|
[3, BulkImports::Projects::Pipelines::IssuesPipeline],
|
||||||
[4, BulkImports::Common::Pipelines::EntityFinisher]
|
[4, BulkImports::Common::Pipelines::BoardsPipeline],
|
||||||
|
[5, BulkImports::Common::Pipelines::EntityFinisher]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue