Commit 2bbeaf70 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 15eaeb59 2b4a7ee4
......@@ -60,7 +60,6 @@ Rails/SaveBang:
- 'ee/spec/lib/gitlab/git_access_spec.rb'
- 'ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb'
- 'ee/spec/lib/gitlab/mirror_spec.rb'
- 'ee/spec/mailers/notify_spec.rb'
- 'ee/spec/models/application_setting_spec.rb'
- 'ee/spec/models/approval_merge_request_rule_spec.rb'
- 'ee/spec/models/approval_project_rule_spec.rb'
......@@ -513,12 +512,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- ee/spec/services/merge_request_approval_settings/update_service_spec.rb
- ee/spec/services/personal_access_tokens/create_service_audit_log_spec.rb
- ee/spec/services/personal_access_tokens/groups/update_lifetime_service_spec.rb
- ee/spec/services/projects/after_rename_service_spec.rb
- ee/spec/services/projects/alerting/notify_service_spec.rb
- ee/spec/services/projects/destroy_service_spec.rb
- ee/spec/services/projects/gitlab_projects_import_service_spec.rb
- ee/spec/services/projects/import_export/export_service_spec.rb
- ee/spec/services/projects/transfer_service_spec.rb
- ee/spec/services/push_rules/create_or_update_service_spec.rb
- ee/spec/services/quality_management/test_cases/create_service_spec.rb
- ee/spec/services/quick_actions/interpret_service_spec.rb
......
......@@ -266,19 +266,6 @@ Performance/CollectionLiteralInLoop:
Performance/ConstantRegexp:
Enabled: false
# Offense count: 18
# Cop supports --auto-correct.
Performance/Count:
Exclude:
- 'app/helpers/groups_helper.rb'
- 'app/services/merge_requests/add_context_service.rb'
- 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
- 'lib/gitlab/sidekiq_status.rb'
- 'spec/lib/gitlab/conflict/file_spec.rb'
- 'spec/lib/gitlab/git/tree_spec.rb'
- 'spec/models/ci/build_spec.rb'
- 'spec/support_specs/helpers/active_record/query_recorder_spec.rb'
# Offense count: 14
# Cop supports --auto-correct.
# Configuration parameters: SafeMultiline.
......
......@@ -141,9 +141,9 @@ module GroupsHelper
def projects_lfs_status(group)
lfs_status =
if group.lfs_enabled?
group.projects.select(&:lfs_enabled?).size
group.projects.count(&:lfs_enabled?)
else
group.projects.reject(&:lfs_enabled?).size
group.projects.count { |project| !project.lfs_enabled? }
end
size = group.projects.size
......
......@@ -50,7 +50,7 @@ module MergeRequests
def duplicates
existing_oids = merge_request.merge_request_context_commits.map { |commit| commit.sha.to_s }
existing_oids.select do |existing_oid|
commit_ids.select { |commit_id| existing_oid.start_with?(commit_id) }.count > 0
commit_ids.count { |commit_id| existing_oid.start_with?(commit_id) } > 0
end
end
......
---
title: Resolve offense Performance/Count
merge_request: 57007
author: Shubham Kumar (@imskr)
type: fixed
......@@ -579,6 +579,7 @@ The [`StandardContext`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/g
| `namespace_id` | **{dotted-circle}** | integer | |
| `environment` | **{check-circle}** | string (max 32 chars) | Name of the source environment, such as `production` or `staging` |
| `source` | **{check-circle}** | string (max 32 chars) | Name of the source application, such as `gitlab-rails` or `gitlab-javascript` |
| `plan` | **{dotted-circle}** | string (max 32 chars) | Name of the plan for the namespace, such as `free`, `premium`, or `ultimate`. Automatically picked from the `namespace`. |
| `extra` | **{dotted-circle}** | JSON | Any additional data associated with the event, in the form of key-value pairs |
### Default Schema
......
<script>
import List from './types/list.vue';
import Url from './types/url.vue';
import { REPORT_COMPONENTS, getComponentNameForType } from './types/constants';
export default {
components: {
List,
Url,
...REPORT_COMPONENTS,
},
props: {
item: {
......@@ -13,8 +11,13 @@ export default {
required: true,
},
},
computed: {
componentName() {
return getComponentNameForType(this.item.type);
},
},
};
</script>
<template>
<component :is="item.type" v-bind="item" data-testid="reportComponent" />
<component :is="componentName" v-bind="item" data-testid="reportComponent" />
</template>
export const REPORT_TYPE_LIST = 'list';
export const REPORT_TYPE_URL = 'url';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
export const REPORT_TYPES = [REPORT_TYPE_LIST, REPORT_TYPE_URL];
export const REPORT_TYPES = {
list: 'list',
url: 'url',
};
const REPORT_TYPE_TO_COMPONENT_MAP = {
[REPORT_TYPES.list]: () => import('./list.vue'),
[REPORT_TYPES.url]: () => import('./url.vue'),
};
export const getComponentNameForType = (reportType) =>
`ReportType${capitalizeFirstCharacter(reportType)}`;
export const REPORT_COMPONENTS = Object.fromEntries(
Object.entries(REPORT_TYPE_TO_COMPONENT_MAP).map(([reportType, component]) => [
getComponentNameForType(reportType),
component,
]),
);
......@@ -27,7 +27,7 @@ export default {
:key="item.name"
:class="{ 'gl-list-style-none!': $options.isListType(item) }"
>
<report-item :item="item" />
<report-item :item="item" data-testid="reportItem" />
</li>
</ul>
</template>
import { overEvery } from 'lodash';
import { REPORT_TYPES, REPORT_TYPE_LIST } from './constants';
import { REPORT_TYPES } from './constants';
/**
* Check if the given report is of a type that can be rendered (i.e, is mapped to a component and can be rendered)
......@@ -7,7 +7,7 @@ import { REPORT_TYPES, REPORT_TYPE_LIST } from './constants';
* @param {{ type: string }} reportItem
* @returns boolean
*/
const isSupportedType = ({ type }) => REPORT_TYPES.includes(type);
const isSupportedType = ({ type }) => Object.values(REPORT_TYPES).includes(type);
/**
* Check if the given report is of type list
......@@ -15,7 +15,7 @@ const isSupportedType = ({ type }) => REPORT_TYPES.includes(type);
* @param {{ type: string } } reportItem
* @returns boolean
*/
export const isListType = ({ type }) => type === REPORT_TYPE_LIST;
export const isListType = ({ type }) => type === REPORT_TYPES.list;
/**
* Check if the current report item is of that list and is not nested deeper than the maximum depth
......
---
title: Fix Rails/SaveBang rubocop offenses in ee/spec/mailers
merge_request: 58097
author: Abdul Wadood @abdulwd
type: fixed
---
title: Fix RSpec/EmptyLineAfterFinalLetItBe rubocop offenses in ee/spec/services/projects
merge_request: 58330
author: Abdul Wadood @abdulwd
type: fixed
......@@ -88,7 +88,7 @@ module Gitlab
# {iid: 1, epic_state_id: 1, issues_count: 1, issues_weight_sum: 2, parent_id: nil, issues_state_id: 2}
if type == EPIC_TYPE
# can only be COUNT
children.select { |node| node.epic_state_id == state }.count
children.count { |node| node.epic_state_id == state }
else
matching_record = epic_info_flat_list.find do |record|
record[:issues_state_id] == state
......
......@@ -2,17 +2,16 @@ import { shallowMount } from '@vue/test-utils';
import ReportItem from 'ee/vulnerabilities/components/generic_report/report_item.vue';
import {
REPORT_TYPES,
REPORT_TYPE_URL,
REPORT_TYPE_LIST,
REPORT_COMPONENTS,
} from 'ee/vulnerabilities/components/generic_report/types/constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
const TEST_DATA = {
[REPORT_TYPE_URL]: {
[REPORT_TYPES.url]: {
href: 'http://foo.com',
},
[REPORT_TYPE_LIST]: {
items: [{ type: 'foo' }],
[REPORT_TYPES.list]: {
items: [],
},
};
......@@ -26,12 +25,18 @@ describe('ee/vulnerabilities/components/generic_report/report_item.vue', () => {
item: {},
...props,
},
// manual stubbing is needed because the components are dynamically imported
stubs: Object.keys(REPORT_COMPONENTS),
}),
);
const findReportComponent = () => wrapper.findByTestId('reportComponent');
describe.each(REPORT_TYPES)('with report type "%s"', (reportType) => {
afterEach(() => {
wrapper.destroy();
});
describe.each(Object.values(REPORT_TYPES))('with report type "%s"', (reportType) => {
const reportItem = { type: reportType, ...TEST_DATA[reportType] };
beforeEach(() => {
......
......@@ -2,19 +2,19 @@ import { within, fireEvent } from '@testing-library/dom';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import ReportSection from 'ee/vulnerabilities/components/generic_report/report_section.vue';
import { REPORT_TYPE_URL } from 'ee/vulnerabilities/components/generic_report/types/constants';
import { REPORT_TYPES } from 'ee/vulnerabilities/components/generic_report/types/constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
const TEST_DATA = {
supportedTypes: {
one: {
name: 'one',
type: REPORT_TYPE_URL,
type: REPORT_TYPES.url,
href: 'http://foo.com',
},
two: {
name: 'two',
type: REPORT_TYPE_URL,
type: REPORT_TYPES.url,
href: 'http://bar.com',
},
},
......
import { screen } from '@testing-library/dom';
import { shallowMount } from '@vue/test-utils';
import ReportItem from 'ee/vulnerabilities/components/generic_report/report_item.vue';
import List from 'ee/vulnerabilities/components/generic_report/types/list.vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
const TEST_DATA = {
items: [
......@@ -13,21 +13,30 @@ const TEST_DATA = {
describe('ee/vulnerabilities/components/generic_report/types/list.vue', () => {
let wrapper;
const createWrapper = () => {
return shallowMount(List, {
propsData: {
items: TEST_DATA.items,
},
attachTo: document.body,
});
};
const createWrapper = () =>
extendedWrapper(
shallowMount(List, {
propsData: {
items: TEST_DATA.items,
},
attachTo: document.body,
// manual stubbing is needed because the component is dynamically imported
stubs: {
ReportItem: true,
},
}),
);
const findReportItems = () => wrapper.findAllComponents(ReportItem);
const findReportItems = () => wrapper.findAllByTestId('reportItem');
beforeEach(() => {
wrapper = createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it('renders a list', () => {
expect(screen.getByRole('list')).toBeInstanceOf(HTMLElement);
});
......
......@@ -23,6 +23,10 @@ describe('ee/vulnerabilities/components/generic_report/types/url.vue', () => {
wrapper = createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it('renders a link', () => {
expect(findLink().exists()).toBe(true);
});
......
import {
REPORT_TYPE_LIST,
REPORT_TYPE_URL,
} from 'ee/vulnerabilities/components/generic_report/types/constants';
import { REPORT_TYPES } from 'ee/vulnerabilities/components/generic_report/types/constants';
import { filterTypesAndLimitListDepth } from 'ee/vulnerabilities/components/generic_report/types/utils';
const MOCK_REPORT_TYPE_UNSUPPORTED = 'MOCK_REPORT_TYPE_UNSUPPORTED';
const TEST_DATA = {
url: {
type: REPORT_TYPE_URL,
type: REPORT_TYPES.url,
name: 'url1',
},
list: {
type: REPORT_TYPE_LIST,
type: REPORT_TYPES.list,
name: 'rootList',
items: [
{ type: REPORT_TYPE_URL, name: 'url2' },
{ type: REPORT_TYPES.url, name: 'url2' },
{
type: REPORT_TYPE_LIST,
type: REPORT_TYPES.list,
name: 'listDepthOne',
items: [
{ type: REPORT_TYPE_URL, name: 'url3' },
{ type: REPORT_TYPES.url, name: 'url3' },
{
type: REPORT_TYPE_LIST,
type: REPORT_TYPES.list,
name: 'listDepthTwo',
items: [
{ type: REPORT_TYPE_URL, name: 'url4' },
{ type: REPORT_TYPES.url, name: 'url4' },
{
type: REPORT_TYPE_LIST,
type: REPORT_TYPES.list,
name: 'listDepthThree',
items: [
{ type: REPORT_TYPE_URL, name: 'url5' },
{ type: REPORT_TYPES.url, name: 'url5' },
{ type: MOCK_REPORT_TYPE_UNSUPPORTED },
],
},
......@@ -52,7 +49,7 @@ describe('ee/vulnerabilities/components/generic_report/types/utils', () => {
const getListWithDepthTwo = (reportsData) => reportsData.list.items[1].items[1];
const includesType = (type) => (items) =>
items.find(({ type: currentType }) => currentType === type) !== undefined;
const includesListItem = includesType(REPORT_TYPE_LIST);
const includesListItem = includesType(REPORT_TYPES.list);
const includesUnsupportedType = includesType(MOCK_REPORT_TYPE_UNSUPPORTED);
describe.each`
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Tracking::StandardContext do
let_it_be(:project) { create(:project) }
let_it_be(:namespace) { create(:namespace) }
let_it_be(:plan) { :ultimate_plan }
let(:snowplow_context) { subject.to_context }
describe '#to_context' do
context 'plan' do
context 'when namespace is not available' do
it 'is nil' do
expect(snowplow_context.to_json.dig(:data, :plan)).to be_nil
end
end
context 'when namespace is available' do
subject { described_class.new(namespace: create(:namespace_with_plan, plan: plan)) }
it 'contains plan name' do
expect(snowplow_context.to_json.dig(:data, :plan)).to eq(Plan::ULTIMATE)
end
end
end
end
end
......@@ -93,8 +93,8 @@ RSpec.describe Notify do
subject { described_class.approved_merge_request_email(recipient.id, merge_request.id, last_approver.id) }
before do
merge_request.approvals.create(user: assignee)
merge_request.approvals.create(user: last_approver)
merge_request.approvals.create!(user: assignee)
merge_request.approvals.create!(user: last_approver)
end
it_behaves_like 'a multiple recipients email'
......@@ -141,7 +141,7 @@ RSpec.describe Notify do
context 'when merge request has no assignee' do
before do
merge_request.update(assignees: [])
merge_request.update!(assignees: [])
end
it 'does not show the assignee' do
......@@ -156,7 +156,7 @@ RSpec.describe Notify do
subject { described_class.unapproved_merge_request_email(recipient.id, merge_request.id, last_unapprover.id) }
before do
merge_request.approvals.create(user: assignee)
merge_request.approvals.create!(user: assignee)
end
it_behaves_like 'a multiple recipients email'
......@@ -209,10 +209,6 @@ RSpec.describe Notify do
subject { described_class.unapproved_merge_request_email(recipient.id, merge_request_without_assignee.id, last_unapprover.id) }
before do
merge_request_without_assignee.approvals.create(user: merge_request_without_assignee.assignees.first)
end
it 'contains the new status' do
is_expected.to have_body_text('unapproved')
end
......
......@@ -9,6 +9,7 @@ RSpec.describe Projects::AfterRenameService do
context 'when running on a primary node' do
let_it_be(:primary) { create(:geo_node, :primary) }
let_it_be(:secondary) { create(:geo_node) }
let(:project) { create(:project, :repository, :legacy_storage) }
let!(:path_before_rename) { project.path }
let!(:full_path_before_rename) { project.full_path }
......
......@@ -7,6 +7,7 @@ RSpec.describe Projects::Alerting::NotifyService do
describe '#execute' do
let_it_be(:integration) { create(:alert_management_http_integration, project: project) }
let(:service) { described_class.new(project, payload) }
let(:token) { integration.token }
let(:payload) do
......@@ -68,6 +69,7 @@ RSpec.describe Projects::Alerting::NotifyService do
let_it_be(:schedule) { create(:incident_management_oncall_schedule, project: project) }
let_it_be(:rotation) { create(:incident_management_oncall_rotation, schedule: schedule) }
let_it_be(:participant) { create(:incident_management_oncall_participant, :with_developer_access, rotation: rotation) }
let(:payload) { { 'fingerprint' => 'fingerprint' } }
let(:resolving_payload) { { 'fingerprint' => 'fingerprint', "end_time": Time.current.iso8601 } }
let(:users) { [participant.user] }
......
......@@ -23,6 +23,7 @@ RSpec.describe Projects::DestroyService do
context 'when project is a mirror' do
let(:max_capacity) { Gitlab::CurrentSettings.mirror_max_capacity }
let_it_be(:project_mirror) { create(:project, :mirror, :repository, :import_scheduled) }
let(:result) { described_class.new(project_mirror, project_mirror.owner, {}).execute }
before do
......
......@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Projects::GitlabProjectsImportService do
let_it_be(:namespace) { create(:namespace) }
let(:path) { 'test-path' }
let(:custom_template) { create(:project) }
let(:overwrite) { false }
......
......@@ -9,6 +9,7 @@ RSpec.describe Projects::ImportExport::ExportService do
let_it_be(:subgroup) { create(:group, :private, parent: group) }
let_it_be(:project_template) { create(:project, group: subgroup) }
let_it_be(:user) { create(:user) }
let(:shared) { project_template.import_export_shared }
subject { described_class.new(project_template, user).execute }
......
......@@ -7,6 +7,7 @@ RSpec.describe Projects::TransferService do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group, :public) }
let(:project) { create(:project, :repository, :public, :legacy_storage, namespace: user.namespace) }
subject { described_class.new(project, user) }
......
......@@ -66,7 +66,7 @@ module Gitlab
def self.num_running(job_ids)
responses = self.job_status(job_ids)
responses.select(&:present?).count
responses.count(&:present?)
end
# Returns the number of jobs that have completed.
......
......@@ -3,10 +3,12 @@
module Gitlab
module Tracking
class StandardContext
GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-0-4'
GITLAB_STANDARD_SCHEMA_URL = 'iglu:com.gitlab/gitlab_standard/jsonschema/1-0-5'
GITLAB_RAILS_SOURCE = 'gitlab-rails'
def initialize(namespace: nil, project: nil, user: nil, **extra)
@namespace = namespace
@plan = @namespace&.actual_plan_name
@extra = extra
end
......@@ -36,6 +38,7 @@ module Gitlab
{
environment: environment,
source: source,
plan: @plan,
extra: @extra
}
end
......
......@@ -298,12 +298,12 @@ RSpec.describe Gitlab::Conflict::File do
end
it 'creates context sections of the correct length' do
expect(sections[0][:lines].reject(&:type).length).to eq(3)
expect(sections[2][:lines].reject(&:type).length).to eq(3)
expect(sections[3][:lines].reject(&:type).length).to eq(3)
expect(sections[5][:lines].reject(&:type).length).to eq(3)
expect(sections[6][:lines].reject(&:type).length).to eq(3)
expect(sections[8][:lines].reject(&:type).length).to eq(1)
expect(sections[0][:lines].count { |line| line.type.nil? }).to eq(3)
expect(sections[2][:lines].count { |line| line.type.nil? }).to eq(3)
expect(sections[3][:lines].count { |line| line.type.nil? }).to eq(3)
expect(sections[5][:lines].count { |line| line.type.nil? }).to eq(3)
expect(sections[6][:lines].count { |line| line.type.nil? }).to eq(3)
expect(sections[8][:lines].count { |line| line.type.nil? }).to eq(1)
end
end
end
......
......@@ -10,9 +10,9 @@ RSpec.describe Gitlab::Git::Tree, :seed_helper do
it { expect(tree).to be_kind_of Array }
it { expect(tree.empty?).to be_falsey }
it { expect(tree.select(&:dir?).size).to eq(2) }
it { expect(tree.select(&:file?).size).to eq(10) }
it { expect(tree.select(&:submodule?).size).to eq(2) }
it { expect(tree.count(&:dir?)).to eq(2) }
it { expect(tree.count(&:file?)).to eq(10) }
it { expect(tree.count(&:submodule?)).to eq(2) }
it 'returns an empty array when called with an invalid ref' do
expect(described_class.where(repository, 'foobar-does-not-exist')).to eq([])
......
......@@ -57,6 +57,22 @@ RSpec.describe Gitlab::Tracking::StandardContext do
expect(snowplow_context.to_json.dig(:data, :source)).to eq(described_class::GITLAB_RAILS_SOURCE)
end
context 'plan' do
context 'when namespace is not available' do
it 'is nil' do
expect(snowplow_context.to_json.dig(:data, :plan)).to be_nil
end
end
context 'when namespace is available' do
subject { described_class.new(namespace: create(:namespace)) }
it 'contains plan name' do
expect(snowplow_context.to_json.dig(:data, :plan)).to eq(Plan::DEFAULT)
end
end
end
context 'with extra data' do
subject { described_class.new(extra_key_1: 'extra value 1', extra_key_2: 'extra value 2') }
......
......@@ -36,6 +36,8 @@ RSpec.describe Gitlab::Tracking do
end
describe '.event' do
let(:namespace) { create(:namespace) }
shared_examples 'delegates to destination' do |klass|
before do
allow_any_instance_of(Gitlab::Tracking::Destinations::Snowplow).to receive(:event)
......@@ -47,7 +49,6 @@ RSpec.describe Gitlab::Tracking do
project = double(:project)
user = double(:user)
namespace = double(:namespace)
expect(Gitlab::Tracking::StandardContext)
.to receive(:new)
......
......@@ -1132,7 +1132,7 @@ RSpec.describe Ci::Build do
it "executes UPDATE query" do
recorded = ActiveRecord::QueryRecorder.new { subject }
expect(recorded.log.select { |l| l.match?(/UPDATE.*ci_builds/) }.count).to eq(1)
expect(recorded.log.count { |l| l.match?(/UPDATE.*ci_builds/) }).to eq(1)
end
end
......@@ -1140,7 +1140,7 @@ RSpec.describe Ci::Build do
it 'does not execute UPDATE query' do
recorded = ActiveRecord::QueryRecorder.new { subject }
expect(recorded.log.select { |l| l.match?(/UPDATE.*ci_builds/) }.count).to eq(0)
expect(recorded.log.count { |l| l.match?(/UPDATE.*ci_builds/) }).to eq(0)
end
end
end
......
......@@ -907,10 +907,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@29.9.0":
version "29.9.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.9.0.tgz#c1ff951897fda289d213bac74f70a106e13dd24b"
integrity sha512-c8rGMfFhNOqs+y0S1uhXqXNqu2ydZsv6B5ati2n0YzsrIwQucBfpMqjy8YDjKN7XSQIAi7R5V1puUmslh0KyfA==
"@gitlab/ui@29.11.0":
version "29.11.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.11.0.tgz#e0f82c7047ef6301694c5f76851c5812f5be4d8f"
integrity sha512-+ukRbw6Kc937krnTS434dnkfBKeDedZ25hAqMikATWDAeEt4wfslr9Yio5NRucYiafH3v3cIGyeQ6wGLz9BlQw==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment