Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-25 06:10:36 +00:00
parent 01fbd09ea9
commit 866b1f8ed7
36 changed files with 1114 additions and 98 deletions

View File

@ -1 +1 @@
e1dd9bfe694190e9350dad37b5cd8b5ea44eafa3
bb32df05c777d0cd8a8d15249c99e2d8055e0769

View File

@ -104,18 +104,13 @@ export default {
@[$options.EVENT_ERROR]="onError"
@[$options.EVENT_SUCCESS]="onSuccess"
>
<div ref="container">
<div ref="container" data-testid="access-token-section" data-qa-selector="access_token_section">
<template v-if="newToken">
<!--
After issue https://gitlab.com/gitlab-org/gitlab/-/issues/360921 is
closed remove the `initial-visibility`.
-->
<input-copy-toggle-visibility
:copy-button-title="copyButtonTitle"
:label="label"
:label-for="$options.tokenInputId"
:value="newToken"
initial-visibility
:form-input-group-props="formInputGroupProps"
>
<template #description>

View File

@ -1,5 +1,7 @@
import initSearchSettings from '~/search_settings';
import initWebhookForm from '~/webhooks';
import { initPushEventsEditForm } from '~/webhooks/webhook';
initSearchSettings();
initWebhookForm();
initPushEventsEditForm();

View File

@ -129,6 +129,8 @@ export default {
v-gl-tooltip.hover="toggleVisibilityLabel"
:aria-label="toggleVisibilityLabel"
:icon="toggleVisibilityIcon"
data-testid="toggle-visibility-button"
data-qa-selector="toggle_visibility_button"
@click.stop="handleToggleVisibilityButtonClick"
/>
<clipboard-button

View File

@ -0,0 +1,112 @@
<script>
import { GlFormCheckbox, GlFormRadio, GlFormRadioGroup, GlFormInput, GlSprintf } from '@gitlab/ui';
import {
BRANCH_FILTER_ALL_BRANCHES,
WILDCARD_CODE_STABLE,
WILDCARD_CODE_PRODUCTION,
REGEX_CODE,
descriptionText,
} from '~/webhooks/constants';
export default {
components: {
GlFormCheckbox,
GlFormRadio,
GlFormRadioGroup,
GlFormInput,
GlSprintf,
},
inject: ['pushEvents', 'strategy', 'isNewHook', 'pushEventsBranchFilter'],
data() {
return {
pushEventsData: !this.isNewHook && this.pushEvents,
branchFilterStrategyData: this.isNewHook ? BRANCH_FILTER_ALL_BRANCHES : this.strategy,
pushEventsBranchFilterData: this.pushEventsBranchFilter,
};
},
WILDCARD_CODE_STABLE,
WILDCARD_CODE_PRODUCTION,
REGEX_CODE,
descriptionText,
};
</script>
<template>
<div>
<gl-form-checkbox v-model="pushEventsData">{{ s__('Webhooks|Push events') }}</gl-form-checkbox>
<input type="hidden" :value="pushEventsData" name="hook[push_events]" />
<div v-if="pushEventsData" class="gl-pl-6">
<gl-form-radio-group v-model="branchFilterStrategyData" name="hook[branch_filter_strategy]">
<gl-form-radio
class="gl-mt-2 branch-filter-strategy-radio"
value="all_branches"
data-testid="rule_all_branches"
>
<div data-qa-selector="strategy_radio_all">{{ __('All branches') }}</div>
</gl-form-radio>
<!-- wildcard -->
<gl-form-radio
class="gl-mt-2 branch-filter-strategy-radio"
value="wildcard"
data-testid="rule_wildcard"
>
<div data-qa-selector="strategy_radio_wildcard">
{{ s__('Webhooks|Wildcard pattern') }}
</div>
</gl-form-radio>
<div class="gl-ml-6">
<gl-form-input
v-if="branchFilterStrategyData === 'wildcard'"
v-model="pushEventsBranchFilterData"
name="hook[push_events_branch_filter]"
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
/>
</div>
<p
v-if="branchFilterStrategyData === 'wildcard'"
class="form-text text-muted custom-control"
>
<gl-sprintf :message="$options.descriptionText.wildcard">
<template #WILDCARD_CODE_STABLE>
<code>{{ $options.WILDCARD_CODE_STABLE }}</code>
</template>
<template #WILDCARD_CODE_PRODUCTION>
<code>{{ $options.WILDCARD_CODE_PRODUCTION }}</code>
</template>
</gl-sprintf>
</p>
<!-- regex -->
<gl-form-radio
class="gl-mt-2 branch-filter-strategy-radio"
value="regex"
data-testid="rule_regex"
>
<div data-qa-selector="strategy_radio_regex">
{{ s__('Webhooks|Regular expression') }}
</div>
</gl-form-radio>
<div class="gl-ml-6">
<gl-form-input
v-if="branchFilterStrategyData === 'regex'"
v-model="pushEventsBranchFilterData"
name="hook[push_events_branch_filter]"
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
/>
</div>
<p v-if="branchFilterStrategyData === 'regex'" class="form-text text-muted custom-control">
<gl-sprintf :message="$options.descriptionText.regex">
<template #REGEX_CODE>
<code>{{ $options.REGEX_CODE }}</code>
</template>
</gl-sprintf>
</p>
</gl-form-radio-group>
</div>
</div>
</template>

View File

@ -0,0 +1,17 @@
import { s__ } from '~/locale';
export const BRANCH_FILTER_ALL_BRANCHES = 'all_branches';
export const BRANCH_FILTER_WILDCARD = 'wildcard';
export const BRANCH_FILTER_REGEX = 'regex';
export const WILDCARD_CODE_STABLE = '*-stable';
export const WILDCARD_CODE_PRODUCTION = 'production/*';
export const REGEX_CODE = '(feature|hotfix)/*';
export const descriptionText = {
[BRANCH_FILTER_WILDCARD]: s__(
'Webhooks|Wildcards such as %{WILDCARD_CODE_STABLE} or %{WILDCARD_CODE_PRODUCTION} are supported.',
),
[BRANCH_FILTER_REGEX]: s__('Webhooks|Regex such as %{REGEX_CODE} is supported.'),
};

View File

@ -0,0 +1,23 @@
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import pushEvents from './components/push_events.vue';
export function initPushEventsEditForm() {
const el = document.querySelector('.js-vue-push-events');
if (!el) return false;
const provide = {
isNewHook: parseBoolean(el.dataset.isNewHook),
pushEvents: parseBoolean(el.dataset.pushEvents),
strategy: el.dataset.strategy,
pushEventsBranchFilter: el.dataset.pushEventsBranchFilter,
};
return new Vue({
el,
provide,
render(createElement) {
return createElement(pushEvents);
},
});
}

View File

@ -68,7 +68,7 @@ module EventsHelper
author = event.author
if author
name = self_added ? 'You' : author.name
name = self_added ? _('You') : author.name
link_to name, user_path(author.username), title: name
else
escape_once(event.author_name)

View File

@ -160,6 +160,31 @@ module IntegrationsHelper
!Gitlab.com?
end
def integration_issue_type(issue_type)
issue_type_i18n_map = {
'issue' => _('Issue'),
'incident' => _('Incident'),
'test_case' => _('Test case'),
'requirement' => _('Requirement'),
'task' => _('Task')
}
issue_type_i18n_map[issue_type] || issue_type
end
def integration_todo_target_type(target_type)
target_type_i18n_map = {
'Commit' => _('Commit'),
'Issue' => _('Issue'),
'MergeRequest' => _('Merge Request'),
'Epic' => _('Epic'),
DesignManagement::Design.name => _('design'),
AlertManagement::Alert.name => _('alert')
}
target_type_i18n_map[target_type] || target_type
end
extend self
private

View File

@ -15,21 +15,25 @@ module TodosHelper
def todo_action_name(todo)
case todo.action
when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you'
when Todo::REVIEW_REQUESTED then 'requested a review of'
when Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED then "mentioned #{todo_action_subject(todo)} on"
when Todo::BUILD_FAILED then 'The pipeline failed in'
when Todo::MARKED then 'added a todo for'
when Todo::APPROVAL_REQUIRED then "set #{todo_action_subject(todo)} as an approver for"
when Todo::UNMERGEABLE then 'Could not merge'
when Todo::MERGE_TRAIN_REMOVED then "Removed from Merge Train:"
when Todo::ASSIGNED then todo.self_added? ? _('assigned') : _('assigned you')
when Todo::REVIEW_REQUESTED then s_('Todos|requested a review of')
when Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED then format(
s_("Todos|mentioned %{who} on"), who: todo_action_subject(todo)
)
when Todo::BUILD_FAILED then s_('Todos|The pipeline failed in')
when Todo::MARKED then s_('Todos|added a todo for')
when Todo::APPROVAL_REQUIRED then format(
s_("Todos|set %{who} as an approver for"), who: todo_action_subject(todo)
)
when Todo::UNMERGEABLE then s_('Todos|Could not merge')
when Todo::MERGE_TRAIN_REMOVED then s_("Todos|Removed from Merge Train:")
end
end
def todo_self_addressing(todo)
case todo.action
when Todo::ASSIGNED then 'to yourself'
when Todo::REVIEW_REQUESTED then 'from yourself'
when Todo::ASSIGNED then _('to yourself')
when Todo::REVIEW_REQUESTED then _('from yourself')
end
end
@ -66,9 +70,9 @@ module TodosHelper
return _('alert') if todo.for_alert?
target_type = if todo.for_issue_or_work_item?
todo.target.issue_type
IntegrationsHelper.integration_issue_type(todo.target.issue_type)
else
todo.target_type
IntegrationsHelper.integration_todo_target_type(todo.target_type)
end
target_type.titleize.downcase
@ -109,6 +113,11 @@ module TodosHelper
return unless show_todo_state?(todo)
state = todo.target.state.to_s
raw_state_to_i18n = {
"closed" => _('Closed'),
"merged" => _('Merged'),
"resolved" => _('Resolved')
}
case todo.target
when MergeRequest
@ -124,7 +133,7 @@ module TodosHelper
end
tag.span class: "gl-my-0 gl-px-2 status-box #{background_class}" do
todo.target.state.to_s.capitalize
raw_state_to_i18n[state] || state.capitalize
end
end
@ -237,7 +246,7 @@ module TodosHelper
end
def todo_action_subject(todo)
todo.self_added? ? 'yourself' : 'you'
todo.self_added? ? s_('Todos|yourself') : _('you')
end
def show_todo_state?(todo)

View File

@ -27,8 +27,7 @@
= todo_target_title(todo)
%span.title-item.todo-project.todo-label
at
= todo_parent_path(todo)
= s_('Todo|at %{todo_parent_path}').html_safe % { todo_parent_path: todo_parent_path(todo) }
- if todo.self_assigned?
%span.title-item.action-name

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class FinalizeInvalidMemberCleanup < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
MIGRATION = 'DestroyInvalidMembers'
def up
ensure_batched_background_migration_is_finished(
job_class_name: MIGRATION,
table_name: :members,
column_name: :id,
job_arguments: []
)
end
def down
# noop
end
end

View File

@ -0,0 +1 @@
933cb5a869696f2343b0b8dfc32f94a64ed7a5119c3f6b2b64ce30e3ae4e555c

View File

@ -32,7 +32,7 @@ module Banzai
# Corresponds to the $$\n...\n$$ syntax
DOLLAR_DISPLAY_BLOCK_PATTERN = %r{
^(?<matched>\$\$\ *\n(?<math>.*)\n\$\$\ *)$
}x.freeze
}mx.freeze
# Order dependent. Handle the `$$` syntax before the `$` syntax
DOLLAR_MATH_PIPELINE = [

View File

@ -42348,6 +42348,9 @@ msgstr ""
msgid "Todos|Assigned"
msgstr ""
msgid "Todos|Could not merge"
msgstr ""
msgid "Todos|Design"
msgstr ""
@ -42399,9 +42402,15 @@ msgstr ""
msgid "Todos|Pipelines"
msgstr ""
msgid "Todos|Removed from Merge Train:"
msgstr ""
msgid "Todos|Review requested"
msgstr ""
msgid "Todos|The pipeline failed in"
msgstr ""
msgid "Todos|Undo mark all as done"
msgstr ""
@ -42414,6 +42423,24 @@ msgstr ""
msgid "Todos|Your To-Do List shows what to work on next"
msgstr ""
msgid "Todos|added a todo for"
msgstr ""
msgid "Todos|mentioned %{who} on"
msgstr ""
msgid "Todos|requested a review of"
msgstr ""
msgid "Todos|set %{who} as an approver for"
msgstr ""
msgid "Todos|yourself"
msgstr ""
msgid "Todo|at %{todo_parent_path}"
msgstr ""
msgid "Toggle GitLab Next"
msgstr ""
@ -45418,6 +45445,12 @@ msgstr ""
msgid "Webhooks|Push to the repository."
msgstr ""
msgid "Webhooks|Regex such as %{REGEX_CODE} is supported."
msgstr ""
msgid "Webhooks|Regular expression"
msgstr ""
msgid "Webhooks|Releases events"
msgstr ""
@ -45478,6 +45511,12 @@ msgstr ""
msgid "Webhooks|Wiki page events"
msgstr ""
msgid "Webhooks|Wildcard pattern"
msgstr ""
msgid "Webhooks|Wildcards such as %{WILDCARD_CODE_STABLE} or %{WILDCARD_CODE_PRODUCTION} are supported."
msgstr ""
msgid "Website"
msgstr ""
@ -47276,6 +47315,12 @@ msgstr ""
msgid "assign yourself"
msgstr ""
msgid "assigned"
msgstr ""
msgid "assigned you"
msgstr ""
msgid "at"
msgstr ""
@ -48018,6 +48063,9 @@ msgid_plural "from %d jobs"
msgstr[0] ""
msgstr[1] ""
msgid "from yourself"
msgstr ""
msgid "frontmatter"
msgstr ""
@ -49076,6 +49124,9 @@ msgstr ""
msgid "time summary"
msgstr ""
msgid "to yourself"
msgstr ""
msgid "today"
msgstr ""
@ -49212,6 +49263,9 @@ msgstr ""
msgid "yaml invalid"
msgstr ""
msgid "you"
msgstr ""
msgid "your GitLab instance"
msgstr ""

View File

@ -106,7 +106,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.25.5",
"core-js": "^3.26.0",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropper": "^2.3.0",

View File

@ -28,9 +28,14 @@ module QA
end
base.view 'app/assets/javascripts/access_tokens/components/new_access_token_app.vue' do
element :access_token_section
element :created_access_token_field
end
base.view 'app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue' do
element :toggle_visibility_button
end
base.view 'app/assets/javascripts/access_tokens/components/access_token_table_app.vue' do
element :revoke_button
end
@ -49,7 +54,10 @@ module QA
end
def created_access_token
find_element(:created_access_token_field, wait: 30).value
within_element(:access_token_section) do
click_element(:toggle_visibility_button, wait: 30)
find_element(:created_access_token_field).value
end
end
def fill_expiry_date(date)

View File

@ -1380,7 +1380,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
{
'Channel' => {
'Subprotocols' => ["terminal.gitlab.com"],
'Url' => 'wss://localhost/proxy/build/default_port/',
'Url' => 'wss://gitlab.example.com/proxy/build/default_port/',
'Header' => {
'Authorization' => [nil]
},
@ -1536,7 +1536,8 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil)
expect(job.runner_session_url).to start_with('https://')
expect(Gitlab::Workhorse).to receive(:channel_websocket).with(a_hash_including(url: "wss://localhost/proxy/build/default_port/"))
expect(Gitlab::Workhorse).to receive(:channel_websocket)
.with(a_hash_including(url: "wss://gitlab.example.com/proxy/build/default_port/"))
make_request
end

View File

@ -716,7 +716,7 @@ FactoryBot.define do
trait :with_runner_session do
after(:build) do |build|
build.build_runner_session(url: 'https://localhost')
build.build_runner_session(url: 'https://gitlab.example.com')
end
end

View File

@ -4,18 +4,11 @@ require 'spec_helper'
RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
include Spec::Support::Helpers::ModalHelpers
include Spec::Support::Helpers::AccessTokenHelpers
let(:admin) { create(:admin) }
let!(:user) { create(:user) }
def active_impersonation_tokens
find("[data-testid='active-tokens']")
end
def created_impersonation_token
find_field('new-access-token').value
end
before do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
@ -39,12 +32,12 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
click_on "Create impersonation token"
expect(active_impersonation_tokens).to have_text(name)
expect(active_impersonation_tokens).to have_text('in')
expect(active_impersonation_tokens).to have_text('read_api')
expect(active_impersonation_tokens).to have_text('read_user')
expect(active_access_tokens).to have_text(name)
expect(active_access_tokens).to have_text('in')
expect(active_access_tokens).to have_text('read_api')
expect(active_access_tokens).to have_text('read_user')
expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
expect(created_impersonation_token).not_to be_empty
expect(created_access_token).to match(/[\w-]{20}/)
end
end
@ -55,16 +48,16 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
it 'only shows impersonation tokens' do
visit admin_user_impersonation_tokens_path(user_id: user.username)
expect(active_impersonation_tokens).to have_text(impersonation_token.name)
expect(active_impersonation_tokens).not_to have_text(personal_access_token.name)
expect(active_impersonation_tokens).to have_text('in')
expect(active_access_tokens).to have_text(impersonation_token.name)
expect(active_access_tokens).not_to have_text(personal_access_token.name)
expect(active_access_tokens).to have_text('in')
end
it 'shows absolute times' do
admin.update!(time_display_relative: false)
visit admin_user_impersonation_tokens_path(user_id: user.username)
expect(active_impersonation_tokens).to have_text(personal_access_token.expires_at.strftime('%b %-d'))
expect(active_access_tokens).to have_text(personal_access_token.expires_at.strftime('%b %-d'))
end
end
@ -76,7 +69,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" }
expect(active_impersonation_tokens).to have_text("This user has no active impersonation tokens.")
expect(active_access_tokens).to have_text("This user has no active impersonation tokens.")
end
it "removes expired tokens from 'active' section" do
@ -84,7 +77,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
visit admin_user_impersonation_tokens_path(user_id: user.username)
expect(active_impersonation_tokens).to have_text("This user has no active impersonation tokens.")
expect(active_access_tokens).to have_text("This user has no active impersonation tokens.")
end
end

View File

@ -4,22 +4,11 @@ require 'spec_helper'
RSpec.describe 'Profile > Personal Access Tokens', :js do
include Spec::Support::Helpers::ModalHelpers
include Spec::Support::Helpers::AccessTokenHelpers
let(:user) { create(:user) }
let(:pat_create_service) { double('PersonalAccessTokens::CreateService', execute: ServiceResponse.error(message: 'error', payload: { personal_access_token: PersonalAccessToken.new })) }
def active_personal_access_tokens
find("[data-testid='active-tokens']")
end
def created_personal_access_token
find_field('new-access-token').value
end
def feed_token_description
"Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
end
before do
sign_in(user)
end
@ -43,11 +32,11 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
click_on "Create personal access token"
wait_for_all_requests
expect(active_personal_access_tokens).to have_text(name)
expect(active_personal_access_tokens).to have_text('in')
expect(active_personal_access_tokens).to have_text('read_api')
expect(active_personal_access_tokens).to have_text('read_user')
expect(created_personal_access_token).not_to be_empty
expect(active_access_tokens).to have_text(name)
expect(active_access_tokens).to have_text('in')
expect(active_access_tokens).to have_text('read_api')
expect(active_access_tokens).to have_text('read_user')
expect(created_access_token).to match(/[\w-]{20}/)
end
context "when creation fails" do
@ -73,8 +62,8 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
it 'only shows personal access tokens' do
visit profile_personal_access_tokens_path
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(active_personal_access_tokens).not_to have_text(impersonation_token.name)
expect(active_access_tokens).to have_text(personal_access_token.name)
expect(active_access_tokens).not_to have_text(impersonation_token.name)
end
context 'when User#time_display_relative is false' do
@ -85,7 +74,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
it 'shows absolute times for expires_at' do
visit profile_personal_access_tokens_path
expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d'))
expect(active_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %-d'))
end
end
end
@ -97,14 +86,14 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
visit profile_personal_access_tokens_path
accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" }
expect(active_personal_access_tokens).to have_text("This user has no active personal access tokens.")
expect(active_access_tokens).to have_text("This user has no active personal access tokens.")
end
it "removes expired tokens from 'active' section" do
personal_access_token.update!(expires_at: 5.days.ago)
visit profile_personal_access_tokens_path
expect(active_personal_access_tokens).to have_text("This user has no active personal access tokens.")
expect(active_access_tokens).to have_text("This user has no active personal access tokens.")
end
context "when revocation fails" do
@ -115,12 +104,16 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
visit profile_personal_access_tokens_path
accept_gl_confirm(button_text: "Revoke") { click_on "Revoke" }
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(active_access_tokens).to have_text(personal_access_token.name)
end
end
end
describe "feed token" do
def feed_token_description
"Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
end
context "when enabled" do
it "displays feed token" do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)

View File

@ -87,7 +87,7 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
expect(page).to have_content('SSL Verification: enabled')
expect(page).to have_content('Tag push events')
expect(page).to have_content('Job events')
expect(page).to have_selector('.js-vue-push-events', visible: :all)
expect(page).to have_content('Push events')
end
end

View File

@ -73,7 +73,6 @@ describe('~/access_tokens/components/new_access_token_app', () => {
expect(InputCopyToggleVisibilityComponent.props('copyButtonTitle')).toBe(
sprintf(__('Copy %{accessTokenType}'), { accessTokenType }),
);
expect(InputCopyToggleVisibilityComponent.props('initialVisibility')).toBe(true);
expect(InputCopyToggleVisibilityComponent.attributes('label')).toBe(
sprintf(__('Your new %{accessTokenType}'), { accessTokenType }),
);

View File

@ -0,0 +1,453 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Webhook push events form editor component Different push events rules when editing existing hook with "all_branches" strategy selected 1`] = `
<gl-form-radio-group-stub
checked="all_branches"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
</gl-form-radio-group-stub>
`;
exports[`Webhook push events form editor component Different push events rules when editing existing hook with "regex" strategy selected 1`] = `
<gl-form-radio-group-stub
checked="regex"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<gl-form-input-stub
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
name="hook[push_events_branch_filter]"
value="foo"
/>
</div>
<p
class="form-text text-muted custom-control"
>
<gl-sprintf-stub
message="Regex such as %{REGEX_CODE} is supported."
/>
</p>
</gl-form-radio-group-stub>
`;
exports[`Webhook push events form editor component Different push events rules when editing existing hook with "wildcard" strategy selected 1`] = `
<gl-form-radio-group-stub
checked="wildcard"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<gl-form-input-stub
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
name="hook[push_events_branch_filter]"
value="foo"
/>
</div>
<p
class="form-text text-muted custom-control"
>
<gl-sprintf-stub
message="Wildcards such as %{WILDCARD_CODE_STABLE} or %{WILDCARD_CODE_PRODUCTION} are supported."
/>
</p>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
</gl-form-radio-group-stub>
`;
exports[`Webhook push events form editor component Different push events rules when editing new hook all_branches should be selected by default 1`] = `
<gl-form-radio-group-stub
checked="all_branches"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
</gl-form-radio-group-stub>
`;
exports[`Webhook push events form editor component Different push events rules when editing new hook should be able to set regex rule 1`] = `
<gl-form-radio-group-stub
checked="regex"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<gl-form-input-stub
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
name="hook[push_events_branch_filter]"
value=""
/>
</div>
<p
class="form-text text-muted custom-control"
>
<gl-sprintf-stub
message="Regex such as %{REGEX_CODE} is supported."
/>
</p>
</gl-form-radio-group-stub>
`;
exports[`Webhook push events form editor component Different push events rules when editing new hook should be able to set wildcard rule 1`] = `
<gl-form-radio-group-stub
checked="wildcard"
disabledfield="disabled"
htmlfield="html"
name="hook[branch_filter_strategy]"
options=""
textfield="text"
valuefield="value"
>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_all_branches"
value="all_branches"
>
<div
data-qa-selector="strategy_radio_all"
>
All branches
</div>
</gl-form-radio-stub>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_wildcard"
value="wildcard"
>
<div
data-qa-selector="strategy_radio_wildcard"
>
Wildcard pattern
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<gl-form-input-stub
data-qa-selector="webhook_branch_filter_field"
data-testid="webhook_branch_filter_field"
name="hook[push_events_branch_filter]"
value=""
/>
</div>
<p
class="form-text text-muted custom-control"
>
<gl-sprintf-stub
message="Wildcards such as %{WILDCARD_CODE_STABLE} or %{WILDCARD_CODE_PRODUCTION} are supported."
/>
</p>
<gl-form-radio-stub
class="gl-mt-2 branch-filter-strategy-radio"
data-testid="rule_regex"
value="regex"
>
<div
data-qa-selector="strategy_radio_regex"
>
Regular expression
</div>
</gl-form-radio-stub>
<div
class="gl-ml-6"
>
<!---->
</div>
<!---->
</gl-form-radio-group-stub>
`;

View File

@ -0,0 +1,117 @@
import { nextTick } from 'vue';
import { GlFormCheckbox, GlFormRadioGroup } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PushEvents from '~/webhooks/components/push_events.vue';
describe('Webhook push events form editor component', () => {
let wrapper;
const findPushEventsCheckBox = (w = wrapper) => w.findComponent(GlFormCheckbox);
const findPushEventsIndicator = (w = wrapper) => w.find('input[name="hook[push_events]"]');
const findPushEventRulesGroup = (w = wrapper) => w.findComponent(GlFormRadioGroup);
const getPushEventsRuleValue = (w = wrapper) => findPushEventRulesGroup(w).vm.$attrs.checked;
const findWildcardRuleInput = (w = wrapper) => w.findByTestId('webhook_branch_filter_field');
const findRegexRuleInput = (w = wrapper) => w.findByTestId('webhook_branch_filter_field');
const createComponent = (provides) =>
shallowMountExtended(PushEvents, {
provide: {
isNewHook: true,
pushEvents: false,
strategy: 'wildcard',
pushEventsBranchFilter: '',
...provides,
},
});
describe('Renders push events checkbox', () => {
it('when it is a new hook', async () => {
wrapper = createComponent({
isNewHook: true,
});
await nextTick();
const checkbox = findPushEventsCheckBox();
expect(checkbox.exists()).toBe(true);
expect(findPushEventRulesGroup().exists()).toBe(false);
expect(findPushEventsIndicator().attributes('value')).toBe('false');
});
it('when it is not a new hook and push events is enabled', async () => {
wrapper = createComponent({
isNewHook: false,
pushEvents: true,
});
await nextTick();
expect(findPushEventsCheckBox().exists()).toBe(true);
expect(findPushEventRulesGroup().exists()).toBe(true);
expect(findPushEventsIndicator().attributes('value')).toBe('true');
});
});
describe('Different push events rules', () => {
describe('when editing new hook', () => {
beforeEach(async () => {
wrapper = createComponent({
isNewHook: true,
});
await nextTick();
await findPushEventsCheckBox().vm.$emit('input', true);
await nextTick();
});
it('all_branches should be selected by default', async () => {
expect(findPushEventRulesGroup().element).toMatchSnapshot();
});
it('should be able to set wildcard rule', async () => {
expect(getPushEventsRuleValue()).toBe('all_branches');
expect(findWildcardRuleInput().exists()).toBe(false);
expect(findRegexRuleInput().exists()).toBe(false);
await findPushEventRulesGroup(wrapper).vm.$emit('input', 'wildcard');
expect(findWildcardRuleInput().exists()).toBe(true);
expect(findPushEventRulesGroup().element).toMatchSnapshot();
const testVal = 'test-val';
findWildcardRuleInput().vm.$emit('input', testVal);
await nextTick();
expect(findWildcardRuleInput().attributes('value')).toBe(testVal);
});
it('should be able to set regex rule', async () => {
expect(getPushEventsRuleValue()).toBe('all_branches');
expect(findRegexRuleInput().exists()).toBe(false);
expect(findWildcardRuleInput().exists()).toBe(false);
await findPushEventRulesGroup(wrapper).vm.$emit('input', 'regex');
expect(findRegexRuleInput().exists()).toBe(true);
expect(findPushEventRulesGroup().element).toMatchSnapshot();
const testVal = 'test-val';
findRegexRuleInput().vm.$emit('input', testVal);
await nextTick();
expect(findRegexRuleInput().attributes('value')).toBe(testVal);
});
});
describe('when editing existing hook', () => {
it.each(['all_branches', 'wildcard', 'regex'])(
'with "%s" strategy selected',
async (strategy) => {
wrapper = createComponent({
isNewHook: false,
pushEvents: true,
pushEventsBranchFilter: 'foo',
strategy,
});
await nextTick();
expect(findPushEventsIndicator().attributes('value')).toBe('true');
expect(findPushEventRulesGroup().element).toMatchSnapshot();
},
);
});
});
});

View File

@ -4,6 +4,30 @@ require 'spec_helper'
RSpec.describe EventsHelper do
include Gitlab::Routing
include Banzai::Filter::OutputSafety
describe '#link_to_author' do
let(:user) { create(:user) }
let(:event) { create(:event, author: user) }
it 'returns a link to the author' do
name = user.name
expect(helper.link_to_author(event)).to eq(link_to(name, user_path(user.username), title: name))
end
it 'returns the author name if the author is not present' do
event.author = nil
expect(helper.link_to_author(event)).to eq(escape_once(event.author_name))
end
it 'returns "You" if the author is the current user' do
allow(helper).to receive(:current_user).and_return(user)
name = _('You')
expect(helper.link_to_author(event, self_added: true)).to eq(link_to(name, user_path(user.username), title: name))
end
end
describe '#event_target_path' do
subject { helper.event_target_path(event.present) }

View File

@ -150,4 +150,54 @@ RSpec.describe IntegrationsHelper do
end
end
end
describe '#integration_issue_type' do
using RSpec::Parameterized::TableSyntax
let_it_be(:issue) { create(:issue) }
where(:issue_type, :expected_i18n_issue_type) do
"issue" | _('Issue')
"incident" | _('Incident')
"test_case" | _('Test case')
"requirement" | _('Requirement')
"task" | _('Task')
end
with_them do
before do
issue.update!(issue_type: issue_type)
end
it "return the correct i18n issue type" do
expect(described_class.integration_issue_type(issue.issue_type)).to eq(expected_i18n_issue_type)
end
end
it "only consider these enumeration values are valid" do
expected_valid_types = %w[issue incident test_case requirement task]
expect(Issue.issue_types.keys).to contain_exactly(*expected_valid_types)
end
end
describe '#integration_todo_target_type' do
using RSpec::Parameterized::TableSyntax
let!(:todo) { create(:todo, commit_id: '123') }
where(:target_type, :expected_i18n_target_type) do
"Commit" | _("Commit")
"Issue" | _("Issue")
"MergeRequest" | _("Merge Request")
'Epic' | _('Epic')
DesignManagement::Design.name | _('design')
AlertManagement::Alert.name | _('alert')
end
with_them do
before do
todo.update!(target_type: target_type)
end
it { expect(described_class.integration_todo_target_type(todo.target_type)).to eq(expected_i18n_target_type) }
end
end
end

View File

@ -310,4 +310,33 @@ RSpec.describe TodosHelper do
it { expect(helper.todos_filter_params[:state]).to eq(result) }
end
end
describe '#todo_action_name' do
using RSpec::Parameterized::TableSyntax
where(:action, :self_added?, :expected_action_name) do
Todo::ASSIGNED | false | s_('Todos|assigned you')
Todo::ASSIGNED | true | s_('Todos|assigned')
Todo::REVIEW_REQUESTED | true | s_('Todos|requested a review of')
Todo::MENTIONED | true | format(s_("Todos|mentioned %{who} on"), who: s_('Todos|yourself'))
Todo::MENTIONED | false | format(s_("Todos|mentioned %{who} on"), who: _('you'))
Todo::DIRECTLY_ADDRESSED | true | format(s_("Todos|mentioned %{who} on"), who: s_('Todos|yourself'))
Todo::DIRECTLY_ADDRESSED | false | format(s_("Todos|mentioned %{who} on"), who: _('you'))
Todo::BUILD_FAILED | true | s_('Todos|The pipeline failed in')
Todo::MARKED | true | s_('Todos|added a todo for')
Todo::APPROVAL_REQUIRED | true | format(s_("Todos|set %{who} as an approver for"), who: s_('Todos|yourself'))
Todo::APPROVAL_REQUIRED | false | format(s_("Todos|set %{who} as an approver for"), who: _('you'))
Todo::UNMERGEABLE | true | s_('Todos|Could not merge')
Todo::MERGE_TRAIN_REMOVED | true | s_("Todos|Removed from Merge Train:")
end
with_them do
before do
alert_todo.action = action
alert_todo.user = self_added? ? alert_todo.author : user
end
it { expect(helper.todo_action_name(alert_todo)).to eq(expected_action_name) }
end
end
end

View File

@ -97,7 +97,8 @@ RSpec.describe Banzai::Filter::MathFilter do
describe 'block display math using $$\n...\n$$ syntax' do
context 'with valid syntax' do
where(:text, :result_template) do
"$$\n2+2\n$$" | "<math>2+2</math>"
"$$\n2+2\n$$" | "<math>2+2</math>"
"$$\n2+2\n3+4\n$$" | "<math>2+2\n3+4</math>"
end
with_them do

View File

@ -0,0 +1,72 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe FinalizeInvalidMemberCleanup, :migration do
let(:batched_migrations) { table(:batched_background_migrations) }
let_it_be(:migration) { described_class::MIGRATION }
describe '#up' do
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).to receive(:finalize).with('DestroyInvalidMembers', :members, :id, [])
end
end
end
context 'when migration is missing' do
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
migrate!
end
end
context 'with migration present' do
let!(:destroy_invalid_member_migration) do
batched_migrations.create!(
job_class_name: 'DestroyInvalidMembers',
table_name: :members,
column_name: :id,
job_arguments: [],
interval: 2.minutes,
min_value: 1,
max_value: 2,
batch_size: 1000,
sub_batch_size: 200,
gitlab_schema: :gitlab_main,
status: 3 # finished
)
end
context 'when migration finished successfully' do
it 'does not raise exception' do
expect { migrate! }.not_to raise_error
end
end
context 'with different migration statuses' do
using RSpec::Parameterized::TableSyntax
where(:status, :description) do
0 | 'paused'
1 | 'active'
4 | 'failed'
5 | 'finalizing'
end
with_them do
before do
destroy_invalid_member_migration.update!(status: status)
end
it_behaves_like 'finalizes the migration'
end
end
end
end
end

View File

@ -72,7 +72,7 @@ RSpec.describe Ci::BuildRunnerSession, model: true do
let(:specification) { subject.service_specification(service: service, port: port, path: path, subprotocols: subprotocols) }
it 'returns service proxy url' do
expect(specification[:url]).to eq "https://localhost/proxy/#{service}/#{port}/#{path}"
expect(specification[:url]).to eq "https://gitlab.example.com/proxy/#{service}/#{port}/#{path}"
end
it 'returns default service proxy websocket subprotocol' do
@ -89,7 +89,7 @@ RSpec.describe Ci::BuildRunnerSession, model: true do
let(:port) { nil }
it 'uses the default port name' do
expect(specification[:url]).to eq "https://localhost/proxy/#{service}/default_port/#{path}"
expect(specification[:url]).to eq "https://gitlab.example.com/proxy/#{service}/default_port/#{path}"
end
end
@ -97,7 +97,7 @@ RSpec.describe Ci::BuildRunnerSession, model: true do
let(:service) { '' }
it 'uses the service name "build" as default' do
expect(specification[:url]).to eq "https://localhost/proxy/build/#{port}/#{path}"
expect(specification[:url]).to eq "https://gitlab.example.com/proxy/build/#{port}/#{path}"
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module Spec
module Support
module Helpers
module AccessTokenHelpers
def active_access_tokens
find("[data-testid='active-tokens']")
end
def created_access_token
within('[data-testid=access-token-section]') do
find('[data-testid=toggle-visibility-button]').click
find_field('new-access-token').value
end
end
end
end
end
end

View File

@ -9,13 +9,7 @@ RSpec.shared_examples 'resource access tokens missing access rights' do
end
RSpec.shared_examples 'resource access tokens creation' do |resource_type|
def active_resource_access_tokens
find("[data-testid='active-tokens']")
end
def created_resource_access_token
find_field('new-access-token').value
end
include Spec::Support::Helpers::AccessTokenHelpers
it 'allows creation of an access token', :aggregate_failures do
name = 'My access token'
@ -34,12 +28,12 @@ RSpec.shared_examples 'resource access tokens creation' do |resource_type|
click_on "Create #{resource_type} access token"
expect(active_resource_access_tokens).to have_text(name)
expect(active_resource_access_tokens).to have_text('in')
expect(active_resource_access_tokens).to have_text('read_api')
expect(active_resource_access_tokens).to have_text('read_repository')
expect(active_resource_access_tokens).to have_text('Guest')
expect(created_resource_access_token).not_to be_empty
expect(active_access_tokens).to have_text(name)
expect(active_access_tokens).to have_text('in')
expect(active_access_tokens).to have_text('read_api')
expect(active_access_tokens).to have_text('read_repository')
expect(active_access_tokens).to have_text('Guest')
expect(created_access_token).to match(/[\w-]{20}/)
end
end

View File

@ -25,7 +25,7 @@ require (
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
github.com/sirupsen/logrus v1.9.0
github.com/smartystreets/goconvey v1.7.2
github.com/stretchr/testify v1.8.0
github.com/stretchr/testify v1.8.1
gitlab.com/gitlab-org/gitaly/v15 v15.4.2
gitlab.com/gitlab-org/golang-archive-zip v0.1.1
gitlab.com/gitlab-org/labkit v1.16.0

View File

@ -896,8 +896,9 @@ github.com/ssgelm/cookiejarparser v1.0.1/go.mod h1:DUfC0mpjIzlDN7DzKjXpHj0qMI5m9
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -906,8 +907,9 @@ github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=

View File

@ -3903,10 +3903,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^3.25.5:
version "3.25.5"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.5.tgz#e86f651a2ca8a0237a5f064c2fe56cef89646e27"
integrity sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==
core-js@^3.26.0:
version "3.26.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.0.tgz#a516db0ed0811be10eac5d94f3b8463d03faccfe"
integrity sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==
core-util-is@~1.0.0:
version "1.0.3"