Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
4044a01bd7
commit
ede2fbdc87
|
@ -442,7 +442,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
||||||
- ee/spec/controllers/registrations/groups_controller_spec.rb
|
- ee/spec/controllers/registrations/groups_controller_spec.rb
|
||||||
- ee/spec/controllers/registrations/projects_controller_spec.rb
|
- ee/spec/controllers/registrations/projects_controller_spec.rb
|
||||||
- ee/spec/controllers/subscriptions_controller_spec.rb
|
- ee/spec/controllers/subscriptions_controller_spec.rb
|
||||||
- ee/spec/features/admin/admin_show_new_user_signups_cap_alert_spec.rb
|
|
||||||
- ee/spec/features/boards/group_boards/multiple_boards_spec.rb
|
- ee/spec/features/boards/group_boards/multiple_boards_spec.rb
|
||||||
- ee/spec/features/ci_shared_runner_warnings_spec.rb
|
- ee/spec/features/ci_shared_runner_warnings_spec.rb
|
||||||
- ee/spec/features/dashboards/todos_spec.rb
|
- ee/spec/features/dashboards/todos_spec.rb
|
||||||
|
@ -1036,12 +1035,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
||||||
- spec/services/markdown_content_rewriter_service_spec.rb
|
- spec/services/markdown_content_rewriter_service_spec.rb
|
||||||
- spec/services/members/create_service_spec.rb
|
- spec/services/members/create_service_spec.rb
|
||||||
- spec/services/members/invite_service_spec.rb
|
- spec/services/members/invite_service_spec.rb
|
||||||
- spec/services/merge_requests/base_service_spec.rb
|
|
||||||
- spec/services/merge_requests/create_pipeline_service_spec.rb
|
|
||||||
- spec/services/merge_requests/export_csv_service_spec.rb
|
|
||||||
- spec/services/merge_requests/merge_orchestration_service_spec.rb
|
|
||||||
- spec/services/merge_requests/merge_service_spec.rb
|
|
||||||
- spec/services/merge_requests/merge_to_ref_service_spec.rb
|
|
||||||
- spec/services/metrics/dashboard/annotations/create_service_spec.rb
|
- spec/services/metrics/dashboard/annotations/create_service_spec.rb
|
||||||
- spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
|
- spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
|
||||||
- spec/services/metrics/users_starred_dashboards/create_service_spec.rb
|
- spec/services/metrics/users_starred_dashboards/create_service_spec.rb
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2b9f2f35e178b8b56b5f657420aa72c6a77c62eb
|
ca2b1ea56e839a9bc4878abb1e9ecac8002b4b07
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -475,7 +475,7 @@ group :ed25519 do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gitaly GRPC protocol definitions
|
# Gitaly GRPC protocol definitions
|
||||||
gem 'gitaly', '~> 13.9.0.pre.rc1'
|
gem 'gitaly', '~> 13.11.0.pre.rc1'
|
||||||
|
|
||||||
gem 'grpc', '~> 1.30.2'
|
gem 'grpc', '~> 1.30.2'
|
||||||
|
|
||||||
|
|
|
@ -440,7 +440,7 @@ GEM
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
git (1.7.0)
|
git (1.7.0)
|
||||||
rchardet (~> 1.8)
|
rchardet (~> 1.8)
|
||||||
gitaly (13.9.0.pre.rc1)
|
gitaly (13.11.0.pre.rc1)
|
||||||
grpc (~> 1.0)
|
grpc (~> 1.0)
|
||||||
github-markup (1.7.0)
|
github-markup (1.7.0)
|
||||||
gitlab (4.16.1)
|
gitlab (4.16.1)
|
||||||
|
@ -1427,7 +1427,7 @@ DEPENDENCIES
|
||||||
gettext (~> 3.3)
|
gettext (~> 3.3)
|
||||||
gettext_i18n_rails (~> 1.8.0)
|
gettext_i18n_rails (~> 1.8.0)
|
||||||
gettext_i18n_rails_js (~> 1.3)
|
gettext_i18n_rails_js (~> 1.3)
|
||||||
gitaly (~> 13.9.0.pre.rc1)
|
gitaly (~> 13.11.0.pre.rc1)
|
||||||
github-markup (~> 1.7.0)
|
github-markup (~> 1.7.0)
|
||||||
gitlab-chronic (~> 0.10.5)
|
gitlab-chronic (~> 0.10.5)
|
||||||
gitlab-dangerfiles (~> 1.1.1)
|
gitlab-dangerfiles (~> 1.1.1)
|
||||||
|
|
|
@ -117,7 +117,12 @@ export default {
|
||||||
<div class="table-section section-50" role="rowheader">{{ s__('CiVariables|Value') }}</div>
|
<div class="table-section section-50" role="rowheader">{{ s__('CiVariables|Value') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="variable in variables" :key="variable.id" class="gl-responsive-table-row">
|
<div
|
||||||
|
v-for="variable in variables"
|
||||||
|
:key="variable.id"
|
||||||
|
class="gl-responsive-table-row"
|
||||||
|
data-testid="ci-variable-row"
|
||||||
|
>
|
||||||
<div class="table-section section-50">
|
<div class="table-section section-50">
|
||||||
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Key') }}</div>
|
<div class="table-mobile-header" role="rowheader">{{ s__('Pipeline|Key') }}</div>
|
||||||
<div class="table-mobile-content gl-mr-3">
|
<div class="table-mobile-content gl-mr-3">
|
||||||
|
@ -126,6 +131,7 @@ export default {
|
||||||
v-model="variable.key"
|
v-model="variable.key"
|
||||||
:placeholder="$options.i18n.keyPlaceholder"
|
:placeholder="$options.i18n.keyPlaceholder"
|
||||||
class="ci-variable-body-item form-control"
|
class="ci-variable-body-item form-control"
|
||||||
|
data-testid="ci-variable-key"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,6 +144,7 @@ export default {
|
||||||
v-model="variable.secret_value"
|
v-model="variable.secret_value"
|
||||||
:placeholder="$options.i18n.valuePlaceholder"
|
:placeholder="$options.i18n.valuePlaceholder"
|
||||||
class="ci-variable-body-item form-control"
|
class="ci-variable-body-item form-control"
|
||||||
|
data-testid="ci-variable-value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -149,6 +156,7 @@ export default {
|
||||||
category="tertiary"
|
category="tertiary"
|
||||||
icon="clear"
|
icon="clear"
|
||||||
:aria-label="__('Delete variable')"
|
:aria-label="__('Delete variable')"
|
||||||
|
data-testid="delete-variable-btn"
|
||||||
@click="deleteVariable(variable.id)"
|
@click="deleteVariable(variable.id)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -181,7 +189,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gl-mt-3 justify-content-center">
|
<div class="d-flex gl-mt-3 justify-content-center">
|
||||||
<p class="text-muted" v-html="helpText"></p>
|
<p class="text-muted" data-testid="form-help-text" v-html="helpText"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<gl-button
|
<gl-button
|
||||||
|
|
|
@ -5,11 +5,17 @@ module Clusters
|
||||||
module ApplicationVersion
|
module ApplicationVersion
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
EXTERNAL_VERSION = 'EXTERNALLY_INSTALLED'
|
||||||
|
|
||||||
included do
|
included do
|
||||||
state_machine :status do
|
state_machine :status do
|
||||||
before_transition any => [:installed, :updated] do |application|
|
before_transition any => [:installed, :updated] do |application|
|
||||||
application.version = application.class.const_get(:VERSION, false)
|
application.version = application.class.const_get(:VERSION, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
before_transition any => [:externally_installed] do |application|
|
||||||
|
application.version = EXTERNAL_VERSION
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Move to btn-confirm from btn-success in push_rules directory
|
||||||
|
merge_request: 58033
|
||||||
|
author: Yogi (@yo)
|
||||||
|
type: changed
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix EmptyLineAfterFinalLetItBe offenses in spec/services/merge_requests
|
||||||
|
merge_request: 58429
|
||||||
|
author: Huzaifa Iftikhar @huzaifaiftikhar
|
||||||
|
type: fixed
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Use object quarantine directory to enumerate new LFS pointers
|
||||||
|
merge_request: 58634
|
||||||
|
author:
|
||||||
|
type: performance
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix cop offenses for Style/HashTransformation in ee directory
|
||||||
|
merge_request: 56581
|
||||||
|
author: Karthik Sivadas @karthik.sivadas
|
||||||
|
type: other
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix cop offenses for Style/HashTransformation in spec directory
|
||||||
|
merge_request: 56586
|
||||||
|
author: Karthik Sivadas @karthik.sivadas
|
||||||
|
type: other
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: lfs_integrity_inspect_quarantined_objects
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58634
|
||||||
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327440
|
||||||
|
milestone: '13.11'
|
||||||
|
type: development
|
||||||
|
group: group::gitaly
|
||||||
|
default_enabled: false
|
|
@ -762,6 +762,21 @@ end
|
||||||
Gitlab::CurrentSettings.current_application_settings.runners_registration_token
|
Gitlab::CurrentSettings.current_application_settings.runners_registration_token
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Run pipeline schedules manually
|
||||||
|
|
||||||
|
You can run pipeline schedules manually through the Rails console to reveal any errors that are usually not visible.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# schedule_id can be obtained from Edit Pipeline Schedule page
|
||||||
|
schedule = Ci::PipelineSchedule.find_by(id: <schedule_id>)
|
||||||
|
|
||||||
|
# Select the user that you want to run the schedule for
|
||||||
|
user = User.find_by_username('<username>')
|
||||||
|
|
||||||
|
# Run the schedule
|
||||||
|
ps = Ci::CreatePipelineService.new(schedule.project, user, ref: schedule.ref).execute!(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
### See current license information
|
### See current license information
|
||||||
|
|
|
@ -78,17 +78,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_new_lfs_pointers(revision, limit, not_in, dynamic_timeout = nil)
|
def get_new_lfs_pointers(revision, limit, not_in, dynamic_timeout = nil)
|
||||||
request = Gitaly::GetNewLFSPointersRequest.new(
|
request, rpc = create_new_lfs_pointers_request(revision, limit, not_in)
|
||||||
repository: @gitaly_repo,
|
|
||||||
revision: encode_binary(revision),
|
|
||||||
limit: limit || 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if not_in.nil? || not_in == :all
|
|
||||||
request.not_in_all = true
|
|
||||||
else
|
|
||||||
request.not_in_refs += not_in
|
|
||||||
end
|
|
||||||
|
|
||||||
timeout =
|
timeout =
|
||||||
if dynamic_timeout
|
if dynamic_timeout
|
||||||
|
@ -100,7 +90,7 @@ module Gitlab
|
||||||
response = GitalyClient.call(
|
response = GitalyClient.call(
|
||||||
@gitaly_repo.storage_name,
|
@gitaly_repo.storage_name,
|
||||||
:blob_service,
|
:blob_service,
|
||||||
:get_new_lfs_pointers,
|
rpc,
|
||||||
request,
|
request,
|
||||||
timeout: timeout
|
timeout: timeout
|
||||||
)
|
)
|
||||||
|
@ -118,6 +108,39 @@ module Gitlab
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def create_new_lfs_pointers_request(revision, limit, not_in)
|
||||||
|
# If the check happens for a change which is using a quarantine
|
||||||
|
# environment for incoming objects, then we can avoid doing the
|
||||||
|
# necessary graph walk to detect only new LFS pointers and instead scan
|
||||||
|
# through all quarantined objects.
|
||||||
|
git_env = ::Gitlab::Git::HookEnv.all(@gitaly_repo.gl_repository)
|
||||||
|
if Feature.enabled?(:lfs_integrity_inspect_quarantined_objects, @project, default_enabled: :yaml) && git_env['GIT_OBJECT_DIRECTORY_RELATIVE'].present?
|
||||||
|
repository = @gitaly_repo.dup
|
||||||
|
repository.git_alternate_object_directories = Google::Protobuf::RepeatedField.new(:string)
|
||||||
|
|
||||||
|
request = Gitaly::ListAllLFSPointersRequest.new(
|
||||||
|
repository: repository,
|
||||||
|
limit: limit || 0
|
||||||
|
)
|
||||||
|
|
||||||
|
[request, :list_all_lfs_pointers]
|
||||||
|
else
|
||||||
|
request = Gitaly::GetNewLFSPointersRequest.new(
|
||||||
|
repository: @gitaly_repo,
|
||||||
|
revision: encode_binary(revision),
|
||||||
|
limit: limit || 0
|
||||||
|
)
|
||||||
|
|
||||||
|
if not_in.nil? || not_in == :all
|
||||||
|
request.not_in_all = true
|
||||||
|
else
|
||||||
|
request.not_in_refs += not_in
|
||||||
|
end
|
||||||
|
|
||||||
|
[request, :get_new_lfs_pointers]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def consume_blob_response(response)
|
def consume_blob_response(response)
|
||||||
data = []
|
data = []
|
||||||
blob = nil
|
blob = nil
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { GlButton } from '@gitlab/ui';
|
|
||||||
import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
|
import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
|
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||||
import Form from '~/jobs/components/manual_variables_form.vue';
|
import Form from '~/jobs/components/manual_variables_form.vue';
|
||||||
|
|
||||||
const localVue = createLocalVue();
|
const localVue = createLocalVue();
|
||||||
|
@ -21,49 +21,48 @@ describe('Manual Variables Form', () => {
|
||||||
variablesSettingsUrl: '/settings',
|
variablesSettingsUrl: '/settings',
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponent = (props = {}, mountFn = shallowMount) => {
|
const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
|
||||||
store = new Vuex.Store({
|
store = new Vuex.Store({
|
||||||
actions: {
|
actions: {
|
||||||
triggerManualJob: jest.fn(),
|
triggerManualJob: jest.fn(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper = mountFn(localVue.extend(Form), {
|
wrapper = extendedWrapper(
|
||||||
propsData: props,
|
mountFn(localVue.extend(Form), {
|
||||||
localVue,
|
propsData: { ...requiredProps, ...props },
|
||||||
store,
|
localVue,
|
||||||
});
|
store,
|
||||||
|
}),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const findTriggerBtn = () => wrapper.find('[data-testid="trigger-manual-job-btn"]');
|
const findInputKey = () => wrapper.findComponent({ ref: 'inputKey' });
|
||||||
|
const findInputValue = () => wrapper.findComponent({ ref: 'inputSecretValue' });
|
||||||
|
|
||||||
afterEach((done) => {
|
const findTriggerBtn = () => wrapper.findByTestId('trigger-manual-job-btn');
|
||||||
// The component has a `nextTick` callback after some events so we need
|
const findHelpText = () => wrapper.findByTestId('form-help-text');
|
||||||
// to wait for those to finish before destroying.
|
const findDeleteVarBtn = () => wrapper.findByTestId('delete-variable-btn');
|
||||||
setImmediate(() => {
|
const findCiVariableKey = () => wrapper.findByTestId('ci-variable-key');
|
||||||
wrapper.destroy();
|
const findCiVariableValue = () => wrapper.findByTestId('ci-variable-value');
|
||||||
wrapper = null;
|
const findAllVariables = () => wrapper.findAllByTestId('ci-variable-row');
|
||||||
|
|
||||||
done();
|
afterEach(() => {
|
||||||
});
|
wrapper.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('shallowMount', () => {
|
describe('shallowMount', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent(requiredProps);
|
createComponent();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders empty form with correct placeholders', () => {
|
it('renders empty form with correct placeholders', () => {
|
||||||
expect(wrapper.find({ ref: 'inputKey' }).attributes('placeholder')).toBe(
|
expect(findInputKey().attributes('placeholder')).toBe('Input variable key');
|
||||||
'Input variable key',
|
expect(findInputValue().attributes('placeholder')).toBe('Input variable value');
|
||||||
);
|
|
||||||
expect(wrapper.find({ ref: 'inputSecretValue' }).attributes('placeholder')).toBe(
|
|
||||||
'Input variable value',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders help text with provided link', () => {
|
it('renders help text with provided link', () => {
|
||||||
expect(wrapper.find('p').text()).toBe(
|
expect(findHelpText().text()).toBe(
|
||||||
'Specify variable values to be used in this run. The values specified in CI/CD settings will be used as default',
|
'Specify variable values to be used in this run. The values specified in CI/CD settings will be used as default',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -71,57 +70,47 @@ describe('Manual Variables Form', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when adding a new variable', () => {
|
describe('when adding a new variable', () => {
|
||||||
it('creates a new variable when user types a new key and resets the form', (done) => {
|
it('creates a new variable when user types a new key and resets the form', async () => {
|
||||||
wrapper.vm
|
await findInputKey().setValue('new key');
|
||||||
.$nextTick()
|
|
||||||
.then(() => wrapper.find({ ref: 'inputKey' }).setValue('new key'))
|
expect(findAllVariables()).toHaveLength(1);
|
||||||
.then(() => {
|
expect(findCiVariableKey().element.value).toBe('new key');
|
||||||
expect(wrapper.vm.variables.length).toBe(1);
|
expect(findInputKey().attributes('value')).toBe(undefined);
|
||||||
expect(wrapper.vm.variables[0].key).toBe('new key');
|
|
||||||
expect(wrapper.find({ ref: 'inputKey' }).attributes('value')).toBe(undefined);
|
|
||||||
})
|
|
||||||
.then(done)
|
|
||||||
.catch(done.fail);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates a new variable when user types a new value and resets the form', (done) => {
|
it('creates a new variable when user types a new value and resets the form', async () => {
|
||||||
wrapper.vm
|
await findInputValue().setValue('new value');
|
||||||
.$nextTick()
|
|
||||||
.then(() => wrapper.find({ ref: 'inputSecretValue' }).setValue('new value'))
|
|
||||||
.then(() => {
|
|
||||||
expect(wrapper.vm.variables.length).toBe(1);
|
|
||||||
expect(wrapper.vm.variables[0].secret_value).toBe('new value');
|
|
||||||
expect(wrapper.find({ ref: 'inputSecretValue' }).attributes('value')).toBe(undefined);
|
|
||||||
})
|
|
||||||
.then(done)
|
|
||||||
.catch(done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when deleting a variable', () => {
|
expect(findAllVariables()).toHaveLength(1);
|
||||||
beforeEach((done) => {
|
expect(findCiVariableValue().element.value).toBe('new value');
|
||||||
wrapper.vm.variables = [
|
expect(findInputValue().attributes('value')).toBe(undefined);
|
||||||
{
|
|
||||||
key: 'new key',
|
|
||||||
secret_value: 'value',
|
|
||||||
id: '1',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
wrapper.vm.$nextTick(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('removes the variable row', () => {
|
|
||||||
wrapper.find(GlButton).vm.$emit('click');
|
|
||||||
|
|
||||||
expect(wrapper.vm.variables.length).toBe(0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent(requiredProps, mount);
|
createComponent({ mountFn: mount });
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when deleting a variable', () => {
|
||||||
|
it('removes the variable row', async () => {
|
||||||
|
await wrapper.setData({
|
||||||
|
variables: [
|
||||||
|
{
|
||||||
|
key: 'new key',
|
||||||
|
secret_value: 'value',
|
||||||
|
id: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
findDeleteVarBtn().trigger('click');
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
expect(findAllVariables()).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('trigger button is disabled after trigger action', async () => {
|
it('trigger button is disabled after trigger action', async () => {
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'knapsack'
|
||||||
|
|
||||||
|
module KnapsackEnv
|
||||||
|
class RSpecContextAdapter < Knapsack::Adapters::RSpecAdapter
|
||||||
|
def bind_time_tracker
|
||||||
|
::RSpec.configure do |config|
|
||||||
|
# Original version starts timer in `config.prepend_before(:each) do`
|
||||||
|
# https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L9
|
||||||
|
config.prepend_before(:context) do
|
||||||
|
Knapsack.tracker.start_timer
|
||||||
|
end
|
||||||
|
|
||||||
|
# Original version is `config.prepend_before(:each) do`
|
||||||
|
# https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L9
|
||||||
|
config.prepend_before(:each) do # rubocop:disable RSpec/HookArgument
|
||||||
|
current_example_group =
|
||||||
|
if ::RSpec.respond_to?(:current_example)
|
||||||
|
::RSpec.current_example.metadata[:example_group]
|
||||||
|
else
|
||||||
|
example.metadata
|
||||||
|
end
|
||||||
|
|
||||||
|
Knapsack.tracker.test_path = Knapsack::Adapters::RSpecAdapter.test_path(current_example_group)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Original version stops timer in `config.append_after(:each) do`
|
||||||
|
# https://github.com/KnapsackPro/knapsack/blob/v1.17.0/lib/knapsack/adapters/rspec_adapter.rb#L20
|
||||||
|
config.append_after(:context) do
|
||||||
|
Knapsack.tracker.stop_timer
|
||||||
|
end
|
||||||
|
|
||||||
|
config.after(:suite) do
|
||||||
|
Knapsack.logger.info(Knapsack::Presenter.global_time)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.configure!
|
||||||
|
return unless ENV['CI'] && ENV['KNAPSACK_GENERATE_REPORT'] && !ENV['NO_KNAPSACK']
|
||||||
|
|
||||||
|
RSpecContextAdapter.bind
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,7 +14,7 @@ RSpec.describe Atlassian::JiraConnect::Serializers::PullRequestEntity do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with user_notes_count option' do
|
context 'with user_notes_count option' do
|
||||||
let(:user_notes_count) { merge_requests.map { |merge_request| [merge_request.id, 1] }.to_h }
|
let(:user_notes_count) { merge_requests.to_h { |merge_request| [merge_request.id, 1] } }
|
||||||
|
|
||||||
subject { described_class.represent(merge_requests, user_notes_count: user_notes_count).as_json }
|
subject { described_class.represent(merge_requests, user_notes_count: user_notes_count).as_json }
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@ RSpec.describe Gitlab::Ci::Status::Composite do
|
||||||
let_it_be(:pipeline) { create(:ci_pipeline) }
|
let_it_be(:pipeline) { create(:ci_pipeline) }
|
||||||
|
|
||||||
before_all do
|
before_all do
|
||||||
@statuses = Ci::HasStatus::STATUSES_ENUM.map do |status, idx|
|
@statuses = Ci::HasStatus::STATUSES_ENUM.to_h do |status, idx|
|
||||||
[status, create(:ci_build, pipeline: pipeline, status: status, importing: true)]
|
[status, create(:ci_build, pipeline: pipeline, status: status, importing: true)]
|
||||||
end.to_h
|
end
|
||||||
|
|
||||||
@statuses_with_allow_failure = Ci::HasStatus::STATUSES_ENUM.map do |status, idx|
|
@statuses_with_allow_failure = Ci::HasStatus::STATUSES_ENUM.to_h do |status, idx|
|
||||||
[status, create(:ci_build, pipeline: pipeline, status: status, allow_failure: true, importing: true)]
|
[status, create(:ci_build, pipeline: pipeline, status: status, allow_failure: true, importing: true)]
|
||||||
end.to_h
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#status' do
|
describe '#status' do
|
||||||
|
|
|
@ -21,7 +21,7 @@ RSpec.describe Gitlab::Conflict::File do
|
||||||
let(:section_keys) { conflict_file.sections.map { |section| section[:id] }.compact }
|
let(:section_keys) { conflict_file.sections.map { |section| section[:id] }.compact }
|
||||||
|
|
||||||
context 'when resolving everything to the same side' do
|
context 'when resolving everything to the same side' do
|
||||||
let(:resolution_hash) { section_keys.map { |key| [key, 'head'] }.to_h }
|
let(:resolution_hash) { section_keys.to_h { |key| [key, 'head'] } }
|
||||||
let(:resolved_lines) { conflict_file.resolve_lines(resolution_hash) }
|
let(:resolved_lines) { conflict_file.resolve_lines(resolution_hash) }
|
||||||
let(:expected_lines) { conflict_file.lines.reject { |line| line.type == 'old' } }
|
let(:expected_lines) { conflict_file.lines.reject { |line| line.type == 'old' } }
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ RSpec.describe Gitlab::Conflict::File do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises ResolutionError when passed a hash without resolutions for all sections' do
|
it 'raises ResolutionError when passed a hash without resolutions for all sections' do
|
||||||
empty_hash = section_keys.map { |key| [key, nil] }.to_h
|
empty_hash = section_keys.to_h { |key| [key, nil] }
|
||||||
invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h
|
invalid_hash = section_keys.to_h { |key| [key, 'invalid'] }
|
||||||
|
|
||||||
expect { conflict_file.resolve_lines({}) }
|
expect { conflict_file.resolve_lines({}) }
|
||||||
.to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
|
.to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
|
||||||
|
|
|
@ -43,6 +43,33 @@ RSpec.describe Gitlab::GitalyClient::BlobService do
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with hook environment' do
|
||||||
|
let(:git_env) do
|
||||||
|
{
|
||||||
|
'GIT_OBJECT_DIRECTORY_RELATIVE' => '.git/objects',
|
||||||
|
'GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE' => ['/dir/one', '/dir/two']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_params) do
|
||||||
|
expected_repository = repository.gitaly_repository
|
||||||
|
expected_repository.git_alternate_object_directories = Google::Protobuf::RepeatedField.new(:string)
|
||||||
|
|
||||||
|
{ limit: limit, repository: expected_repository }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends a list_all_lfs_pointers message' do
|
||||||
|
allow(Gitlab::Git::HookEnv).to receive(:all).with(repository.gl_repository).and_return(git_env)
|
||||||
|
|
||||||
|
expect_any_instance_of(Gitaly::BlobService::Stub)
|
||||||
|
.to receive(:list_all_lfs_pointers)
|
||||||
|
.with(gitaly_request_with_params(expected_params), kind_of(Hash))
|
||||||
|
.and_return([])
|
||||||
|
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#get_all_lfs_pointers' do
|
describe '#get_all_lfs_pointers' do
|
||||||
|
|
|
@ -684,7 +684,7 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
|
||||||
|
|
||||||
it 'overrides project feature access levels' do
|
it 'overrides project feature access levels' do
|
||||||
access_level_keys = ProjectFeature.available_features.map { |feature| ProjectFeature.access_level_attribute(feature) }
|
access_level_keys = ProjectFeature.available_features.map { |feature| ProjectFeature.access_level_attribute(feature) }
|
||||||
disabled_access_levels = Hash[access_level_keys.collect { |item| [item, 'disabled'] }]
|
disabled_access_levels = access_level_keys.to_h { |item| [item, 'disabled'] }
|
||||||
|
|
||||||
project.create_import_data(data: { override_params: disabled_access_levels })
|
project.create_import_data(data: { override_params: disabled_access_levels })
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ RSpec.describe Featurable do
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_all_project_features(project, features, value)
|
def update_all_project_features(project, features, value)
|
||||||
project_feature_attributes = features.map { |f| ["#{f}_access_level", value] }.to_h
|
project_feature_attributes = features.to_h { |f| ["#{f}_access_level", value] }
|
||||||
project.project_feature.update!(project_feature_attributes)
|
project.project_feature.update!(project_feature_attributes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -299,11 +299,11 @@ RSpec.describe Event do
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_to_none_except(*roles)
|
def visible_to_none_except(*roles)
|
||||||
visible_to_none.merge(roles.map { |role| [role, true] }.to_h)
|
visible_to_none.merge(roles.to_h { |role| [role, true] })
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_to_all_except(*roles)
|
def visible_to_all_except(*roles)
|
||||||
visible_to_all.merge(roles.map { |role| [role, false] }.to_h)
|
visible_to_all.merge(roles.to_h { |role| [role, false] })
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'visibility examples' do
|
shared_examples 'visibility examples' do
|
||||||
|
@ -723,7 +723,7 @@ RSpec.describe Event do
|
||||||
note_on_design: true,
|
note_on_design: true,
|
||||||
note_on_commit: true
|
note_on_commit: true
|
||||||
}
|
}
|
||||||
valid_target_factories.map do |kind, needs_project|
|
valid_target_factories.to_h do |kind, needs_project|
|
||||||
extra_data = if kind == :merge_request
|
extra_data = if kind == :merge_request
|
||||||
{ source_project: project }
|
{ source_project: project }
|
||||||
elsif needs_project
|
elsif needs_project
|
||||||
|
@ -735,7 +735,7 @@ RSpec.describe Event do
|
||||||
target = kind == :project ? nil : build(kind, **extra_data)
|
target = kind == :project ? nil : build(kind, **extra_data)
|
||||||
|
|
||||||
[kind, build(:event, :created, author: project.owner, project: project, target: target)]
|
[kind, build(:event, :created, author: project.owner, project: project, target: target)]
|
||||||
end.to_h
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'passes a sanity check', :aggregate_failures do
|
it 'passes a sanity check', :aggregate_failures do
|
||||||
|
|
|
@ -54,7 +54,7 @@ RSpec.describe Packages::Dependency, type: :model do
|
||||||
|
|
||||||
context 'with too big parameter' do
|
context 'with too big parameter' do
|
||||||
let(:size) { (Packages::Dependency::MAX_CHUNKED_QUERIES_COUNT * chunk_size) + 1 }
|
let(:size) { (Packages::Dependency::MAX_CHUNKED_QUERIES_COUNT * chunk_size) + 1 }
|
||||||
let(:names_and_version_patterns) { Hash[(1..size).map { |v| [v, v] }] }
|
let(:names_and_version_patterns) { (1..size).to_h { |v| [v, v] } }
|
||||||
|
|
||||||
it { expect { subject }.to raise_error(ArgumentError, 'Too many names_and_version_patterns') }
|
it { expect { subject }.to raise_error(ArgumentError, 'Too many names_and_version_patterns') }
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,7 @@ RSpec.describe 'getting Alert Management Alert Assignees' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
||||||
let(:assignees) { alerts.map { |alert| [alert['iid'], alert['assignees']['nodes']] }.to_h }
|
let(:assignees) { alerts.to_h { |alert| [alert['iid'], alert['assignees']['nodes']] } }
|
||||||
let(:first_assignees) { assignees[first_alert.iid.to_s] }
|
let(:first_assignees) { assignees[first_alert.iid.to_s] }
|
||||||
let(:second_assignees) { assignees[second_alert.iid.to_s] }
|
let(:second_assignees) { assignees[second_alert.iid.to_s] }
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ RSpec.describe 'getting Alert Management Alert Notes' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:alerts_result) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
let(:alerts_result) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
||||||
let(:notes_result) { alerts_result.map { |alert| [alert['iid'], alert['notes']['nodes']] }.to_h }
|
let(:notes_result) { alerts_result.to_h { |alert| [alert['iid'], alert['notes']['nodes']] } }
|
||||||
let(:first_notes_result) { notes_result[first_alert.iid.to_s] }
|
let(:first_notes_result) { notes_result[first_alert.iid.to_s] }
|
||||||
let(:second_notes_result) { notes_result[second_alert.iid.to_s] }
|
let(:second_notes_result) { notes_result[second_alert.iid.to_s] }
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ RSpec.describe 'getting Alert Management Alert Assignees' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:gql_alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
let(:gql_alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
|
||||||
let(:gql_todos) { gql_alerts.map { |gql_alert| [gql_alert['iid'], gql_alert['todos']['nodes']] }.to_h }
|
let(:gql_todos) { gql_alerts.to_h { |gql_alert| [gql_alert['iid'], gql_alert['todos']['nodes']] } }
|
||||||
let(:gql_alert_todo) { gql_todos[alert.iid.to_s].first }
|
let(:gql_alert_todo) { gql_todos[alert.iid.to_s].first }
|
||||||
let(:gql_other_alert_todo) { gql_todos[other_alert.iid.to_s].first }
|
let(:gql_other_alert_todo) { gql_todos[other_alert.iid.to_s].first }
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.shared_examples 'languages and percentages JSON response' do
|
RSpec.shared_examples 'languages and percentages JSON response' do
|
||||||
let(:expected_languages) { project.repository.languages.map { |language| language.values_at(:label, :value)}.to_h }
|
let(:expected_languages) { project.repository.languages.to_h { |language| language.values_at(:label, :value) } }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(project.repository).to receive(:languages).and_return(
|
allow(project.repository).to receive(:languages).and_return(
|
||||||
|
|
|
@ -6,6 +6,7 @@ RSpec.describe MergeRequests::BaseService do
|
||||||
include ProjectForksHelper
|
include ProjectForksHelper
|
||||||
|
|
||||||
let_it_be(:project) { create(:project, :repository) }
|
let_it_be(:project) { create(:project, :repository) }
|
||||||
|
|
||||||
let(:title) { 'Awesome merge_request' }
|
let(:title) { 'Awesome merge_request' }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,7 @@ RSpec.describe MergeRequests::CreatePipelineService do
|
||||||
|
|
||||||
let_it_be(:project, reload: true) { create(:project, :repository) }
|
let_it_be(:project, reload: true) { create(:project, :repository) }
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
let(:service) { described_class.new(project, actor, params) }
|
let(:service) { described_class.new(project, actor, params) }
|
||||||
let(:actor) { user }
|
let(:actor) { user }
|
||||||
let(:params) { {} }
|
let(:params) { {} }
|
||||||
|
@ -50,6 +51,7 @@ RSpec.describe MergeRequests::CreatePipelineService do
|
||||||
|
|
||||||
context 'with fork merge request' do
|
context 'with fork merge request' do
|
||||||
let_it_be(:forked_project) { fork_project(project, nil, repository: true, target_project: create(:project, :private, :repository)) }
|
let_it_be(:forked_project) { fork_project(project, nil, repository: true, target_project: create(:project, :private, :repository)) }
|
||||||
|
|
||||||
let(:source_project) { forked_project }
|
let(:source_project) { forked_project }
|
||||||
|
|
||||||
context 'when actor has permission to create pipelines in target project' do
|
context 'when actor has permission to create pipelines in target project' do
|
||||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe MergeRequests::ExportCsvService do
|
RSpec.describe MergeRequests::ExportCsvService do
|
||||||
let_it_be(:merge_request) { create(:merge_request) }
|
let_it_be(:merge_request) { create(:merge_request) }
|
||||||
|
|
||||||
let(:csv) { CSV.parse(subject.csv_data, headers: true).first }
|
let(:csv) { CSV.parse(subject.csv_data, headers: true).first }
|
||||||
|
|
||||||
subject { described_class.new(MergeRequest.where(id: merge_request.id), merge_request.project) }
|
subject { described_class.new(MergeRequest.where(id: merge_request.id), merge_request.project) }
|
||||||
|
@ -46,6 +47,7 @@ RSpec.describe MergeRequests::ExportCsvService do
|
||||||
describe 'approvers' do
|
describe 'approvers' do
|
||||||
context 'when approved' do
|
context 'when approved' do
|
||||||
let_it_be(:merge_request) { create(:merge_request) }
|
let_it_be(:merge_request) { create(:merge_request) }
|
||||||
|
|
||||||
let(:approvers) { create_list(:user, 2) }
|
let(:approvers) { create_list(:user, 2) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe MergeRequests::MergeOrchestrationService do
|
RSpec.describe MergeRequests::MergeOrchestrationService do
|
||||||
let_it_be(:maintainer) { create(:user) }
|
let_it_be(:maintainer) { create(:user) }
|
||||||
|
|
||||||
let(:merge_params) { { sha: merge_request.diff_head_sha } }
|
let(:merge_params) { { sha: merge_request.diff_head_sha } }
|
||||||
let(:user) { maintainer }
|
let(:user) { maintainer }
|
||||||
let(:service) { described_class.new(project, user, merge_params) }
|
let(:service) { described_class.new(project, user, merge_params) }
|
||||||
|
|
|
@ -5,6 +5,7 @@ require 'spec_helper'
|
||||||
RSpec.describe MergeRequests::MergeService do
|
RSpec.describe MergeRequests::MergeService do
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
let_it_be(:user2) { create(:user) }
|
let_it_be(:user2) { create(:user) }
|
||||||
|
|
||||||
let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
|
let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
|
||||||
let(:project) { merge_request.project }
|
let(:project) { merge_request.project }
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ RSpec.describe MergeRequests::MergeToRefService do
|
||||||
end
|
end
|
||||||
|
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
let(:merge_request) { create(:merge_request, :simple) }
|
let(:merge_request) { create(:merge_request, :simple) }
|
||||||
let(:project) { merge_request.project }
|
let(:project) { merge_request.project }
|
||||||
|
|
||||||
|
@ -226,6 +227,7 @@ RSpec.describe MergeRequests::MergeToRefService do
|
||||||
|
|
||||||
describe 'cascading merge refs' do
|
describe 'cascading merge refs' do
|
||||||
let_it_be(:project) { create(:project, :repository) }
|
let_it_be(:project) { create(:project, :repository) }
|
||||||
|
|
||||||
let(:params) { { commit_message: 'Cascading merge', first_parent_ref: first_parent_ref, target_ref: target_ref, sha: merge_request.diff_head_sha } }
|
let(:params) { { commit_message: 'Cascading merge', first_parent_ref: first_parent_ref, target_ref: target_ref, sha: merge_request.diff_head_sha } }
|
||||||
|
|
||||||
context 'when first merge happens' do
|
context 'when first merge happens' do
|
||||||
|
|
|
@ -15,6 +15,9 @@ Warning[:deprecated] = true unless ENV.key?('SILENCE_DEPRECATIONS')
|
||||||
require './spec/deprecation_toolkit_env'
|
require './spec/deprecation_toolkit_env'
|
||||||
DeprecationToolkitEnv.configure!
|
DeprecationToolkitEnv.configure!
|
||||||
|
|
||||||
|
require './spec/knapsack_env'
|
||||||
|
KnapsackEnv.configure!
|
||||||
|
|
||||||
require './spec/simplecov_env'
|
require './spec/simplecov_env'
|
||||||
SimpleCovEnv.start!
|
SimpleCovEnv.start!
|
||||||
|
|
||||||
|
@ -47,11 +50,6 @@ if rspec_profiling_is_configured && (!ENV.key?('CI') || branch_can_be_profiled)
|
||||||
require 'rspec_profiling/rspec'
|
require 'rspec_profiling/rspec'
|
||||||
end
|
end
|
||||||
|
|
||||||
if ENV['CI'] && ENV['KNAPSACK_GENERATE_REPORT'] && !ENV['NO_KNAPSACK']
|
|
||||||
require 'knapsack'
|
|
||||||
Knapsack::Adapters::RSpecAdapter.bind
|
|
||||||
end
|
|
||||||
|
|
||||||
# require rainbow gem String monkeypatch, so we can test SystemChecks
|
# require rainbow gem String monkeypatch, so we can test SystemChecks
|
||||||
require 'rainbow/ext/string'
|
require 'rainbow/ext/string'
|
||||||
Rainbow.enabled = false
|
Rainbow.enabled = false
|
||||||
|
@ -81,7 +79,7 @@ RSpec.configure do |config|
|
||||||
config.run_all_when_everything_filtered = true
|
config.run_all_when_everything_filtered = true
|
||||||
|
|
||||||
config.use_transactional_fixtures = true
|
config.use_transactional_fixtures = true
|
||||||
config.use_instantiated_fixtures = false
|
config.use_instantiated_fixtures = false
|
||||||
config.fixture_path = Rails.root
|
config.fixture_path = Rails.root
|
||||||
|
|
||||||
config.verbose_retry = true
|
config.verbose_retry = true
|
||||||
|
|
|
@ -277,11 +277,11 @@ module GraphqlHelpers
|
||||||
# prepare_input_for_mutation({ 'my_key' => 1 })
|
# prepare_input_for_mutation({ 'my_key' => 1 })
|
||||||
# => { 'myKey' => 1}
|
# => { 'myKey' => 1}
|
||||||
def prepare_input_for_mutation(input)
|
def prepare_input_for_mutation(input)
|
||||||
input.map do |name, value|
|
input.to_h do |name, value|
|
||||||
value = prepare_input_for_mutation(value) if value.is_a?(Hash)
|
value = prepare_input_for_mutation(value) if value.is_a?(Hash)
|
||||||
|
|
||||||
[GraphqlHelpers.fieldnamerize(name), value]
|
[GraphqlHelpers.fieldnamerize(name), value]
|
||||||
end.to_h
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def input_variable_name_for_mutation(mutation_name)
|
def input_variable_name_for_mutation(mutation_name)
|
||||||
|
|
|
@ -97,13 +97,13 @@ module ImportExport
|
||||||
def normalize_elements(elem)
|
def normalize_elements(elem)
|
||||||
case elem
|
case elem
|
||||||
when Hash
|
when Hash
|
||||||
elem.map do |key, value|
|
elem.to_h do |key, value|
|
||||||
if ignore_key?(key, value)
|
if ignore_key?(key, value)
|
||||||
[key, :ignored]
|
[key, :ignored]
|
||||||
else
|
else
|
||||||
[key, normalize_elements(value)]
|
[key, normalize_elements(value)]
|
||||||
end
|
end
|
||||||
end.to_h
|
end
|
||||||
when Array
|
when Array
|
||||||
elem.map { |a| normalize_elements(a) }
|
elem.map { |a| normalize_elements(a) }
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,7 +23,7 @@ RSpec.shared_context 'container repository delete tags service shared context' d
|
||||||
end
|
end
|
||||||
|
|
||||||
def stub_delete_reference_requests(tags)
|
def stub_delete_reference_requests(tags)
|
||||||
tags = Hash[Array.wrap(tags).map { |tag| [tag, 200] }] unless tags.is_a?(Hash)
|
tags = Array.wrap(tags).to_h { |tag| [tag, 200] } unless tags.is_a?(Hash)
|
||||||
|
|
||||||
tags.each do |tag, status|
|
tags.each do |tag, status|
|
||||||
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/#{tag}")
|
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/#{tag}")
|
||||||
|
|
|
@ -47,4 +47,15 @@ RSpec.shared_examples 'cluster application version specs' do |application_name|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#make_externally_installed' do
|
||||||
|
subject { build(application_name) }
|
||||||
|
|
||||||
|
it 'sets to a special version' do
|
||||||
|
subject.make_externally_installed!
|
||||||
|
|
||||||
|
expect(subject).to be_persisted
|
||||||
|
expect(subject.version).to eq('EXTERNALLY_INSTALLED')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue