Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-15 12:09:10 +00:00
parent 74e6480896
commit 3e0c035fe3
31 changed files with 1275 additions and 941 deletions

View File

@ -5,7 +5,7 @@ review-cleanup:
extends:
- .default-retry
- .review:rules:review-cleanup
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:gitlab-helm3-kubectl1.14
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:gitlab-helm3.5-kubectl1.17
stage: prepare
environment:
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}

View File

@ -287,6 +287,11 @@ Rails/HelperInstanceVariable:
- app/helpers/**/*.rb
- ee/app/helpers/**/*.rb
Rails/MailerName:
Exclude:
# See for the context on why it's excluded https://gitlab.com/gitlab-org/gitlab/-/issues/239356#note_956419227
- 'app/mailers/notify.rb'
# GitLab ###################################################################
Gitlab/ModuleWithInstanceVariables:

View File

@ -1,5 +0,0 @@
---
# Cop supports --auto-correct.
Rails/MailerName:
Exclude:
- 'app/mailers/notify.rb'

View File

@ -1 +1 @@
8eb17de6edf6b4044d90498e008035a8c980305f
9f87cdc737619e33cddc3ceddc2103dc11dd2577

View File

@ -1,5 +1,12 @@
<script>
import { GlFormGroup, GlFormInput, GlFormInputGroup, GlInputGroupText } from '@gitlab/ui';
import {
GlFormGroup,
GlFormInput,
GlFormInputGroup,
GlInputGroupText,
GlLink,
GlAlert,
} from '@gitlab/ui';
import { debounce } from 'lodash';
import { s__, __ } from '~/locale';
@ -33,23 +40,36 @@ export default {
),
validFeedback: s__('Groups|Group path is available.'),
},
groupId: {
label: s__('Groups|Group ID'),
},
},
apiLoadingMessage: s__('Groups|Checking group URL availability...'),
apiErrorMessage: __(
'An error occurred while checking group path. Please refresh and try again.',
),
changingUrlWarningMessage: s__('Groups|Changing group URL can have unintended side effects.'),
learnMore: s__('Groups|Learn more'),
},
nameInputSize: { md: 'lg' },
changingGroupPathHelpPagePath: helpPagePath('user/group/index', {
anchor: 'change-a-groups-path',
}),
mattermostDataBindName: 'create_chat_team',
components: { GlFormGroup, GlFormInput, GlFormInputGroup, GlInputGroupText },
components: {
GlFormGroup,
GlFormInput,
GlFormInputGroup,
GlInputGroupText,
GlLink,
GlAlert,
},
inject: ['fields', 'basePath', 'mattermostEnabled'],
data() {
return {
name: this.fields.name.value,
path: this.fields.path.value,
hasPathBeenManuallySet: false,
apiSuggestedPath: '',
apiLoading: false,
nameFeedbackState: null,
@ -65,16 +85,23 @@ export default {
pathDescription() {
return this.apiLoading ? this.$options.i18n.apiLoadingMessage : '';
},
isEditingGroup() {
return this.fields.groupId.value !== '';
},
},
watch: {
name: [
function updatePath(newName) {
if (this.isEditingGroup || this.hasPathBeenManuallySet) return;
this.nameFeedbackState = null;
this.pathFeedbackState = null;
this.apiSuggestedPath = '';
this.path = slugify(newName);
},
debounce(async function updatePathWithSuggestions() {
if (this.isEditingGroup || this.hasPathBeenManuallySet) return;
try {
const { suggests } = await this.checkPathAvailability();
@ -134,10 +161,13 @@ export default {
handlePathInput(value) {
this.pathFeedbackState = null;
this.apiSuggestedPath = '';
this.hasPathBeenManuallySet = true;
this.path = value;
this.debouncedValidatePath();
},
debouncedValidatePath: debounce(async function validatePath() {
if (this.isEditingGroup && this.path === this.fields.path.value) return;
try {
const {
exists,
@ -228,5 +258,22 @@ export default {
/>
</gl-form-input-group>
</gl-form-group>
<template v-if="isEditingGroup">
<gl-alert class="gl-mb-5" :dismissible="false" variant="warning">
{{ $options.i18n.changingUrlWarningMessage }}
<gl-link :href="$options.changingGroupPathHelpPagePath"
>{{ $options.i18n.learnMore }}
</gl-link>
</gl-alert>
<gl-form-group :label="$options.i18n.inputs.groupId.label" :label-for="fields.groupId.id">
<gl-form-input
:id="fields.groupId.id"
:value="fields.groupId.value"
:name="fields.groupId.name"
size="sm"
readonly
/>
</gl-form-group>
</template>
</div>
</template>

View File

@ -112,7 +112,7 @@ export default {
</script>
<template>
<gl-button
category="primary"
v-bind="$attrs"
variant="info"
:loading="loading"
:disabled="!canUseCrypto"

View File

@ -1,5 +1,6 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __ } from '~/locale';
import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
@ -7,7 +8,9 @@ export default {
components: {
GlLink,
GlSprintf,
SignInOauthButton: () => import('./sign_in_oauth_button.vue'),
},
mixins: [glFeatureFlagMixin()],
inject: {
usersPath: {
default: '',
@ -51,6 +54,9 @@ export default {
? this.$options.i18n.signedInAsUserText
: this.$options.i18n.signedInText;
},
isOauthEnabled() {
return this.glFeatures.jiraConnectOauth;
},
},
async created() {
this.signInURL = await getGitlabSignInURL(this.usersPath);
@ -72,13 +78,14 @@ export default {
</template>
</gl-sprintf>
<gl-link
v-else-if="hasSubscriptions"
data-testid="sign-in-link"
:href="signInURL"
target="_blank"
>
{{ $options.i18n.signInText }}
</gl-link>
<template v-else-if="hasSubscriptions">
<sign-in-oauth-button v-if="isOauthEnabled" category="tertiary">
{{ $options.i18n.signInText }}
</sign-in-oauth-button>
<gl-link v-else data-testid="sign-in-link" :href="signInURL" target="_blank">
{{ $options.i18n.signInText }}
</gl-link>
</template>
</div>
</template>

View File

@ -35,6 +35,7 @@ export default {
},
},
modalId: 'runners-empty-state-instructions-modal',
svgHeight: 145,
};
</script>
@ -43,9 +44,15 @@ export default {
v-if="isSearchFiltered"
:title="s__('Runners|No results found')"
:svg-path="filteredSvgPath"
:svg-height="$options.svgHeight"
:description="s__('Runners|Edit your search and try again')"
/>
<gl-empty-state v-else :title="s__('Runners|Get started with runners')" :svg-path="svgPath">
<gl-empty-state
v-else
:title="s__('Runners|Get started with runners')"
:svg-path="svgPath"
:svg-height="$options.svgHeight"
>
<template #description>
<gl-sprintf
:message="

View File

@ -3,8 +3,6 @@ import { stateKey } from './state_maps';
export default function deviseState() {
if (!this.commitsCount) {
return stateKey.nothingToMerge;
} else if (this.hasMergeChecksFailed && !this.autoMergeEnabled) {
return stateKey.mergeChecksFailed;
} else if (this.projectArchived) {
return stateKey.archived;
} else if (this.branchMissing) {
@ -15,6 +13,8 @@ export default function deviseState() {
return stateKey.conflicts;
} else if (this.shouldBeRebased) {
return stateKey.rebase;
} else if (this.hasMergeChecksFailed && !this.autoMergeEnabled) {
return stateKey.mergeChecksFailed;
} else if (this.onlyAllowMergeIfPipelineSucceeds && this.isPipelineFailed) {
return stateKey.pipelineFailed;
} else if (this.draft) {

View File

@ -822,18 +822,6 @@ table.code {
}
}
.commits-container {
.diff-files-changed {
@include media-breakpoint-up(sm) {
top: $header-height;
.with-performance-bar & {
top: calc(#{$header-height} + #{$performance-bar-height});
}
}
}
}
.diff-files-changed {
background-color: $body-bg;
@ -844,11 +832,11 @@ table.code {
@include media-breakpoint-up(sm) {
@include gl-sticky;
top: calc(#{$header-height} + #{$mr-tabs-height});
top: $header-height;
z-index: 200;
.with-performance-bar & {
top: calc(#{$header-height} + #{$mr-tabs-height} + #{$performance-bar-height});
top: calc(#{$header-height} + #{$performance-bar-height});
}
&.is-stuck {

View File

@ -95,6 +95,10 @@
}
}
.commits-row + .commits-row {
border-top: 1px solid $white-normal;
}
.text-expander {
display: inline-flex;
background: $white;

View File

@ -33,9 +33,14 @@ module Analytics
)
duration_in_seconds = Arel::Nodes::Extract.new(duration, :epoch)
# start_event_timestamp and end_event_timestamp do not really influence the order,
# but are included so that they are part of the returned result, for example when
# using Gitlab::Analytics::CycleAnalytics::Aggregated::RecordsFetcher
keyset_order(
:total_time => { order_expression: arel_order(duration_in_seconds, direction), distinct: false, sql_type: 'double precision' },
issuable_id_column => { order_expression: arel_order(arel_table[issuable_id_column], direction), distinct: true }
issuable_id_column => { order_expression: arel_order(arel_table[issuable_id_column], direction), distinct: true },
:end_event_timestamp => { order_expression: arel_order(arel_table[:end_event_timestamp], direction), distinct: true },
:start_event_timestamp => { order_expression: arel_order(arel_table[:start_event_timestamp], direction), distinct: true }
)
end
end

View File

@ -9,7 +9,7 @@
- page_description @commit.description
- add_page_specific_style 'page_bundles/pipelines'
.container-fluid.commits-container{ class: [limited_container_width, container_class] }
.container-fluid{ class: [limited_container_width, container_class] }
= render "commit_box"
= render "ci_menu"
= render "projects/diffs/diffs",

View File

@ -43,8 +43,9 @@
= gl_badge_tag @diffs_count, { size: :sm }
- if Feature.enabled?(:moved_mr_sidebar, @project)
.gl-ml-auto.gl-align-items-center.gl-display-none.gl-md-display-flex.js-expand-sidebar{ class: "gl-lg-display-none!" }
%button.btn.btn-default.gl-button.btn-sm.js-sidebar-toggle{ type: 'button' }
= sprite_icon('angle-double-left', size: 12, css_class: 'gl-mr-2')
= render Pajamas::ButtonComponent.new(size: 'small',
icon: 'angle-double-left',
button_options: { class: 'js-sidebar-toggle' }) do
= _('Expand')
.d-flex.flex-wrap.align-items-center.justify-content-lg-end
#js-vue-discussion-counter{ data: { blocks_merge: @project.only_allow_merge_if_all_discussions_are_resolved?.to_s } }

View File

@ -2,3 +2,4 @@
= f.hidden_field :name, data: { js_name: 'name' }
= f.hidden_field :path, maxlength: ::Namespace::URL_MAX_LENGTH, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, data: { js_name: 'path' }
= f.hidden_field :parent_id, data: { js_name: 'parentId' }
= f.hidden_field :id, data: { js_name: 'groupId' }

View File

@ -48,14 +48,7 @@
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end
- if @project # if in milestones list on project level
- if can_admin_group_milestones?
%button.js-promote-project-milestone-button.btn.gl-button.btn-icon.btn-default-tertiary.btn-sm.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
disabled: true,
type: 'button',
data: { url: promote_project_milestone_path(milestone.project, milestone),
milestone_title: milestone.title,
group_name: @project.group.name } }
= sprite_icon('level-up', size: 14, css_class: 'gl-button-icon gl-icon')
= render Pajamas::ButtonComponent.new(icon: 'level-up', category: :tertiary, size: :small, button_options: { class: 'js-promote-project-milestone-button', title: s_('Milestones|Promote to Group Milestone'), disabled: true, data: { toggle: 'tooltip', container: 'body', url: promote_project_milestone_path(milestone.project, milestone), milestone_title: milestone.title, group_name: @project.group.name } })
- if can?(current_user, :admin_milestone, milestone)
- if milestone.closed?
= link_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: "btn gl-button btn-sm gl-ml-3"

View File

@ -1,7 +1,5 @@
const coreJSVersion = require('./node_modules/core-js/package.json').version;
const BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV || null;
let presets = [
[
'@babel/preset-env',
@ -15,7 +13,6 @@ let presets = [
// include stage 3 proposals
const plugins = [
'@babel/plugin-syntax-import-meta',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-json-strings',
'@babel/plugin-proposal-private-methods',
@ -28,26 +25,9 @@ const plugins = [
'lodash',
];
// add code coverage tooling if necessary
if (BABEL_ENV === 'coverage') {
plugins.push([
'babel-plugin-istanbul',
{
exclude: ['app/assets/javascripts/locale/**/app.js'],
},
]);
}
// Jest is running in node environment, so we need additional plugins
// Jest is running in node environment
const isJest = Boolean(process.env.JEST_WORKER_ID);
if (isJest) {
plugins.push('@babel/plugin-transform-modules-commonjs');
/*
without the following, babel-plugin-istanbul throws an error:
https://gitlab.com/gitlab-org/gitlab-foss/issues/58390
*/
plugins.push('babel-plugin-dynamic-import-node');
presets = [
[
'@babel/preset-env',

View File

@ -38,7 +38,7 @@ module Gitlab
strong_memoize(:serialized_records) do
# When RecordsFetcher is used with query sourced from
# InOperatorOptimization::QueryBuilder only columns
# used in ORDER BY statement would be selected by Arel.start operation
# used in ORDER BY statement would be selected by Arel.star operation
selections = [stage_event_model.arel_table[Arel.star]]
selections << duration_in_seconds.as('total_time') if params[:sort] != :duration # duration sorting already exposes this data
@ -55,7 +55,9 @@ module Gitlab
project_path: project.path,
namespace_path: project.namespace.route.path,
author: issuable.author,
total_time: record.total_time
total_time: record.total_time,
start_event_timestamp: record.start_event_timestamp,
end_event_timestamp: record.end_event_timestamp
})
serializer.represent(attributes)
end

View File

@ -108,7 +108,7 @@ module Gitlab
authentication_abilities.include?(:download_code) &&
deploy_key? &&
deploy_key.has_access_to?(container) &&
(project? && project&.repository_access_level != ::Featurable::DISABLED)
(project? && repository_access_level != ::Featurable::DISABLED)
end
def user_can_download?
@ -533,6 +533,10 @@ module Gitlab
# overriden in EE
def check_additional_conditions!
end
def repository_access_level
project&.repository_access_level
end
end
end

View File

@ -39,6 +39,11 @@ module Gitlab
super && deploy_token.can?(download_ability, container)
end
override :repository_access_level
def repository_access_level
project&.wiki_access_level
end
override :check_change_access!
def check_change_access!
raise ForbiddenError, write_to_wiki_message unless user_can_push?

View File

@ -48,12 +48,8 @@
},
"dependencies": {
"@apollo/client": "^3.5.10",
"@babel/core": "^7.10.1",
"@babel/plugin-proposal-class-properties": "^7.10.1",
"@babel/plugin-proposal-json-strings": "^7.10.1",
"@babel/plugin-proposal-private-methods": "^7.10.1",
"@babel/plugin-syntax-import-meta": "^7.10.1",
"@babel/preset-env": "^7.10.1",
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "2.18.0",
@ -107,7 +103,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.22.8",
"core-js": "^3.23.0",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropper": "^2.3.0",
@ -204,7 +200,6 @@
"yaml": "^2.0.0-10"
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.10.1",
"@gitlab/eslint-plugin": "12.1.0",
"@gitlab/stylelint-config": "4.0.0",
"@graphql-eslint/eslint-plugin": "3.10.4",
@ -216,8 +211,6 @@
"ajv-formats": "^2.1.1",
"axios-mock-adapter": "^1.15.0",
"babel-jest": "^26.5.2",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-istanbul": "^6.0.0",
"chalk": "^2.4.1",
"cheerio": "^1.0.0-rc.9",
"commander": "^2.20.3",

View File

@ -61,7 +61,10 @@ module QA
#
# E.g: staging/failed-test-resources-<randomhex>.json
def upload(ci_project_name)
return puts "\nNothing to upload!" if files.empty?
if files.empty?
puts "\nNothing to upload!"
exit 0
end
files.each do |file|
file_name = "#{ci_project_name}/#{file.split('/').last}"
@ -81,7 +84,10 @@ module QA
arr << obj.name
end
return puts "\nNothing to download!" if files_list.blank?
if files_list.blank?
puts "\nNothing to download!"
exit 0
end
FileUtils.mkdir_p('tmp/')
@ -103,10 +109,19 @@ module QA
def files
Runtime::Logger.info('Gathering JSON files...')
files = Dir.glob(@file_pattern)
abort("There is no file with this pattern #{@file_pattern}") if files.empty?
if files.empty?
puts "There is no file with this pattern #{@file_pattern}"
exit 0
end
files.reject! { |file| File.zero?(file) }
if files.empty?
puts "\nAll files were empty and rejected, nothing more to do!"
exit 0
end
files
end
@ -132,7 +147,10 @@ module QA
end
def delete_resources(resources)
Runtime::Logger.info('Nothing to delete.') && return if resources.nil?
if resources.nil?
puts "\nNo resources left to delete after filtering!"
exit 0
end
resources.each_with_object([]) do |(key, value), failures|
value.each do |resource|

View File

@ -42,8 +42,6 @@ RSpec.describe 'Admin Groups' do
end
it 'creates new group' do
stub_feature_flags(group_name_path_vue: false)
visit admin_groups_path
page.within '#content-body' do
@ -96,8 +94,6 @@ RSpec.describe 'Admin Groups' do
end
it 'when entering in group path, group name does not change anymore' do
stub_feature_flags(group_name_path_vue: false)
visit admin_groups_path
click_link "New group"
group_path = 'my-gitlab-project'

View File

@ -1,9 +1,11 @@
import { merge } from 'lodash';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { GlAlert } from '@gitlab/ui';
import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import GroupNameAndPath from '~/groups/components/group_name_and_path.vue';
import { getGroupPathAvailability } from '~/rest_api';
import { createAlert } from '~/flash';
import { helpPagePath } from '~/helpers/help_page_helper';
jest.mock('~/flash');
jest.mock('~/rest_api', () => ({
@ -37,9 +39,15 @@ describe('GroupNameAndPath', () => {
const createComponent = ({ provide = {} } = {}) => {
wrapper = mountExtended(GroupNameAndPath, { provide: merge({}, defaultProvide, provide) });
};
const createComponentEditGroup = ({ path = mockGroupUrl } = {}) => {
createComponent({
provide: { fields: { groupId: { value: '1' }, path: { value: path } } },
});
};
const findGroupNameField = () => wrapper.findByLabelText(GroupNameAndPath.i18n.inputs.name.label);
const findGroupUrlField = () => wrapper.findByLabelText(GroupNameAndPath.i18n.inputs.path.label);
const findAlert = () => extendedWrapper(wrapper.findComponent(GlAlert));
const apiMockAvailablePath = () => {
getGroupPathAvailability.mockResolvedValue({
@ -60,12 +68,45 @@ describe('GroupNameAndPath', () => {
};
describe('when user types in the `Group name` field', () => {
it('updates `Group URL` field as user types', async () => {
createComponent();
describe('when creating a new group', () => {
it('updates `Group URL` field as user types', async () => {
createComponent();
await findGroupNameField().setValue(mockGroupName);
await findGroupNameField().setValue(mockGroupName);
expect(findGroupUrlField().element.value).toBe(mockGroupUrl);
expect(findGroupUrlField().element.value).toBe(mockGroupUrl);
});
});
describe('when editing a group', () => {
it('does not update `Group URL` field and does not call API', async () => {
const groupUrl = 'foo-bar';
createComponentEditGroup({ path: groupUrl });
await findGroupNameField().setValue(mockGroupName);
expect(findGroupUrlField().element.value).toBe(groupUrl);
expect(getGroupPathAvailability).not.toHaveBeenCalled();
});
});
describe('when `Group URL` field has been manually entered', () => {
it('does not update `Group URL` field and does not call API', async () => {
apiMockAvailablePath();
createComponent();
await findGroupUrlField().setValue(mockGroupUrl);
await waitForPromises();
getGroupPathAvailability.mockClear();
await findGroupNameField().setValue('Foo bar');
expect(findGroupUrlField().element.value).toBe(mockGroupUrl);
expect(getGroupPathAvailability).not.toHaveBeenCalled();
});
});
it('shows loading message', async () => {
@ -227,6 +268,30 @@ describe('GroupNameAndPath', () => {
expect(findGroupUrlField().element.value).toBe(mockGroupUrlSuggested);
});
});
describe('when editing a group', () => {
it('calls API if `Group URL` does not equal the original `Group URL`', async () => {
const groupUrl = 'foo-bar';
apiMockAvailablePath();
createComponentEditGroup({ path: groupUrl });
await findGroupUrlField().setValue('foo-bar1');
await waitForPromises();
expect(getGroupPathAvailability).toHaveBeenCalled();
expect(wrapper.findByText(GroupNameAndPath.i18n.inputs.path.validFeedback).exists()).toBe(
true,
);
getGroupPathAvailability.mockClear();
await findGroupUrlField().setValue('foo-bar');
expect(getGroupPathAvailability).not.toHaveBeenCalled();
});
});
});
describe('when `Group URL` field is invalid', () => {
@ -258,4 +323,25 @@ describe('GroupNameAndPath', () => {
expect(findGroupUrlField().attributes('data-bind-in')).toBeUndefined();
});
});
describe('when editing a group', () => {
it('shows warning alert with `Learn more` link', () => {
createComponentEditGroup();
expect(findAlert().exists()).toBe(true);
expect(findAlert().findByRole('link', { name: 'Learn more' }).attributes('href')).toBe(
helpPagePath('user/group/index', {
anchor: 'change-a-groups-path',
}),
);
});
it('shows `Group ID` field', () => {
createComponentEditGroup();
expect(
wrapper.findByLabelText(GroupNameAndPath.i18n.inputs.groupId.label).element.value,
).toBe('1');
});
});
});

View File

@ -35,7 +35,7 @@ describe('SignInOauthButton', () => {
let mockAxios;
let store;
const createComponent = ({ slots } = {}) => {
const createComponent = ({ slots, props } = {}) => {
store = createStore();
jest.spyOn(store, 'dispatch').mockImplementation();
jest.spyOn(store, 'commit').mockImplementation();
@ -46,6 +46,7 @@ describe('SignInOauthButton', () => {
provide: {
oauthMetadata: mockOauthMetadata,
},
propsData: props,
});
};
@ -65,6 +66,7 @@ describe('SignInOauthButton', () => {
expect(findButton().exists()).toBe(true);
expect(findButton().text()).toBe(I18N_DEFAULT_SIGN_IN_BUTTON_TEXT);
expect(findButton().props('category')).toBe('primary');
});
it.each`
@ -208,4 +210,11 @@ describe('SignInOauthButton', () => {
});
});
});
describe('when `category` prop is set', () => {
it('sets the `category` prop on the GlButton', () => {
createComponent({ props: { category: 'tertiary' } });
expect(findButton().props('category')).toBe('tertiary');
});
});
});

View File

@ -1,5 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
import UserLink from '~/jira_connect/subscriptions/components/user_link.vue';
import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_oauth_button.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
@ -16,6 +18,7 @@ describe('UserLink', () => {
provide,
stubs: {
GlSprintf,
SignInOauthButton,
},
});
};
@ -23,28 +26,48 @@ describe('UserLink', () => {
const findSignInLink = () => wrapper.findByTestId('sign-in-link');
const findGitlabUserLink = () => wrapper.findByTestId('gitlab-user-link');
const findSprintf = () => wrapper.findComponent(GlSprintf);
const findOauthButton = () => wrapper.findComponent(SignInOauthButton);
afterEach(() => {
wrapper.destroy();
});
describe.each`
userSignedIn | hasSubscriptions | expectGlSprintf | expectGlLink
${true} | ${false} | ${true} | ${false}
${false} | ${true} | ${false} | ${true}
${true} | ${true} | ${true} | ${false}
${false} | ${false} | ${false} | ${false}
userSignedIn | hasSubscriptions | expectGlSprintf | expectGlLink | expectOauthButton | jiraConnectOauthEnabled
${true} | ${false} | ${true} | ${false} | ${false} | ${false}
${false} | ${true} | ${false} | ${true} | ${false} | ${false}
${true} | ${true} | ${true} | ${false} | ${false} | ${false}
${false} | ${false} | ${false} | ${false} | ${false} | ${false}
${false} | ${true} | ${false} | ${false} | ${true} | ${true}
`(
'when `userSignedIn` is $userSignedIn and `hasSubscriptions` is $hasSubscriptions',
({ userSignedIn, hasSubscriptions, expectGlSprintf, expectGlLink }) => {
'when `userSignedIn` is $userSignedIn, `hasSubscriptions` is $hasSubscriptions, `jiraConnectOauthEnabled` is $jiraConnectOauthEnabled',
({
userSignedIn,
hasSubscriptions,
expectGlSprintf,
expectGlLink,
expectOauthButton,
jiraConnectOauthEnabled,
}) => {
it('renders template correctly', () => {
createComponent({
userSignedIn,
hasSubscriptions,
});
createComponent(
{
userSignedIn,
hasSubscriptions,
},
{
provide: {
glFeatures: {
jiraConnectOauth: jiraConnectOauthEnabled,
},
oauthMetadata: {},
},
},
);
expect(findSprintf().exists()).toBe(expectGlSprintf);
expect(findSignInLink().exists()).toBe(expectGlLink);
expect(findOauthButton().exists()).toBe(expectOauthButton);
});
},
);

View File

@ -27,6 +27,26 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Aggregated::RecordsFetcher do
expect(returned_iids).to eq(expected_issue_ids)
end
it 'passes a hash with all expected attributes to the serializer' do
expected_attributes = [
'created_at',
'id',
'iid',
'title',
:end_event_timestamp,
:start_event_timestamp,
:total_time,
:author,
:namespace_path,
:project_path
]
serializer = instance_double(records_fetcher.send(:serializer).class.name)
allow(records_fetcher).to receive(:serializer).and_return(serializer)
expect(serializer).to receive(:represent).at_least(:once).with(hash_including(*expected_attributes)).and_return({})
records_fetcher.serialized_records
end
end
describe '#serialized_records' do

View File

@ -8,15 +8,18 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
end
let(:params) { { from: 1.year.ago, current_user: user } }
let(:records_fetcher) do
Gitlab::Analytics::CycleAnalytics::DataCollector.new(
stage: stage,
params: params
).records_fetcher
end
let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:user) { create(:user) }
subject do
Gitlab::Analytics::CycleAnalytics::DataCollector.new(
stage: stage,
params: params
).records_fetcher.serialized_records
records_fetcher.serialized_records
end
describe '#serialized_records' do
@ -28,6 +31,26 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
it 'returns all records' do
expect(subject.size).to eq(2)
end
it 'passes a hash with all expected attributes to the serializer' do
expected_attributes = [
'created_at',
'id',
'iid',
'title',
'end_event_timestamp',
'start_event_timestamp',
'total_time',
:author,
:namespace_path,
:project_path
]
serializer = instance_double(records_fetcher.send(:serializer).class.name)
allow(records_fetcher).to receive(:serializer).and_return(serializer)
expect(serializer).to receive(:represent).twice.with(hash_including(*expected_attributes)).and_return({})
subject
end
end
describe 'for issue based stage' do

View File

@ -135,6 +135,30 @@ RSpec.describe Gitlab::GitAccessWiki do
end
end
context 'when the actor is a deploy key' do
let_it_be(:actor) { create(:deploy_key) }
let_it_be(:deploy_key_project) { create(:deploy_keys_project, project: project, deploy_key: actor) }
let_it_be(:user) { actor }
before do
project.project_feature.update_attribute(:wiki_access_level, wiki_access_level)
end
subject { access.check('git-upload-pack', changes) }
context 'when the wiki is enabled' do
let(:wiki_access_level) { ProjectFeature::ENABLED }
it { expect { subject }.not_to raise_error }
end
context 'when the wiki is disabled' do
let(:wiki_access_level) { ProjectFeature::DISABLED }
it { expect { subject }.to raise_wiki_forbidden }
end
end
describe 'when actor is a user provided by build via CI_JOB_TOKEN' do
let(:protocol) { 'http' }
let(:authentication_abilities) { [:build_download_code] }

View File

@ -17,12 +17,14 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let(:headers) { {} }
let(:token) { tokens[token_type] }
let(:tokens) do
{
personal_access_token: personal_access_token.token,
deploy_token: deploy_token.token,
job_token: job.token
job_token: job.token,
invalid: 'invalid-token123'
}
end
@ -48,44 +50,43 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
end
context 'with valid namespace' do
where(:visibility, :user_role, :member, :token_type, :valid_token, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | true | 'returns terraform module packages' | :success
:public | :guest | true | :personal_access_token | true | 'returns terraform module packages' | :success
:public | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | true | 'returns no terraform module packages' | :success
:public | :guest | false | :personal_access_token | true | 'returns no terraform module packages' | :success
:public | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | :personal_access_token | true | 'returns no terraform module packages' | :success
:private | :developer | true | :personal_access_token | true | 'returns terraform module packages' | :success
:private | :guest | true | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | :personal_access_token | true | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | true | 'returns terraform module packages' | :success
:public | :guest | true | :job_token | true | 'returns no terraform module packages' | :success
:public | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | true | 'returns no terraform module packages' | :success
:public | :guest | false | :job_token | true | 'returns no terraform module packages' | :success
:public | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | true | 'returns terraform module packages' | :success
:private | :guest | true | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
where(:visibility, :user_role, :member, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | 'returns terraform module packages' | :success
:public | :guest | true | :personal_access_token | 'returns terraform module packages' | :success
:public | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | 'returns no terraform module packages' | :success
:public | :guest | false | :personal_access_token | 'returns no terraform module packages' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | 'returns no terraform module packages' | :success
:private | :developer | true | :personal_access_token | 'returns terraform module packages' | :success
:private | :guest | true | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | 'returns terraform module packages' | :success
:public | :guest | true | :job_token | 'returns no terraform module packages' | :success
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | 'returns no terraform module packages' | :success
:public | :guest | false | :job_token | 'returns no terraform module packages' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | 'returns terraform module packages' | :success
:private | :guest | true | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:headers) { user_role == :anonymous ? {} : { 'Authorization' => "Bearer #{token}" } }
before do
@ -104,44 +105,43 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
subject { get(url, headers: headers) }
context 'with valid namespace' do
where(:visibility, :user_role, :member, :token_type, :valid_token, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | true | 'grants terraform module download' | :success
:public | :guest | true | :personal_access_token | true | 'grants terraform module download' | :success
:public | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | true | 'grants terraform module download' | :success
:public | :guest | false | :personal_access_token | true | 'grants terraform module download' | :success
:public | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | :anonymous | true | 'grants terraform module download' | :success
:private | :developer | true | :personal_access_token | true | 'grants terraform module download' | :success
:private | :guest | true | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | :anonymous | true | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | true | 'grants terraform module download' | :success
:public | :guest | true | :job_token | true | 'grants terraform module download' | :success
:public | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | true | 'grants terraform module download' | :success
:public | :guest | false | :job_token | true | 'grants terraform module download' | :success
:public | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | true | 'grants terraform module download' | :success
:private | :guest | true | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
where(:visibility, :user_role, :member, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | 'grants terraform module download' | :success
:public | :guest | true | :personal_access_token | 'grants terraform module download' | :success
:public | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | 'grants terraform module download' | :success
:public | :guest | false | :personal_access_token | 'grants terraform module download' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | 'grants terraform module download' | :success
:private | :developer | true | :personal_access_token | 'grants terraform module download' | :success
:private | :guest | true | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | 'grants terraform module download' | :success
:public | :guest | true | :job_token | 'grants terraform module download' | :success
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | 'grants terraform module download' | :success
:public | :guest | false | :job_token | 'grants terraform module download' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | 'grants terraform module download' | :success
:private | :guest | true | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:headers) { user_role == :anonymous ? {} : { 'Authorization' => "Bearer #{token}" } }
before do
@ -160,51 +160,50 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
{
personal_access_token: ::Gitlab::JWTToken.new.tap { |jwt| jwt['token'] = personal_access_token.id }.encoded,
job_token: ::Gitlab::JWTToken.new.tap { |jwt| jwt['token'] = job.token }.encoded,
anonymous: ""
invalid: 'invalid-token123'
}
end
subject { get(url, headers: headers) }
context 'with valid namespace' do
where(:visibility, :user_role, :member, :token_type, :valid_token, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | true | 'grants terraform module package file access' | :success
:public | :guest | true | :personal_access_token | true | 'grants terraform module package file access' | :success
:public | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | true | 'grants terraform module package file access' | :success
:public | :guest | false | :personal_access_token | true | 'grants terraform module package file access' | :success
:public | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | :anonymous | true | 'grants terraform module package file access' | :success
:private | :developer | true | :personal_access_token | true | 'grants terraform module package file access' | :success
:private | :guest | true | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | :anonymous | true | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | true | 'grants terraform module package file access' | :success
:public | :guest | true | :job_token | true | 'grants terraform module package file access' | :success
:public | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | true | 'grants terraform module package file access' | :success
:public | :guest | false | :job_token | true | 'grants terraform module package file access' | :success
:public | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | true | 'grants terraform module package file access' | :success
:private | :guest | true | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :job_token | false | 'rejects terraform module packages access' | :unauthorized
where(:visibility, :user_role, :member, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | :personal_access_token | 'grants terraform module package file access' | :success
:public | :guest | true | :personal_access_token | 'grants terraform module package file access' | :success
:public | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :personal_access_token | 'grants terraform module package file access' | :success
:public | :guest | false | :personal_access_token | 'grants terraform module package file access' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | 'grants terraform module package file access' | :success
:private | :developer | true | :personal_access_token | 'grants terraform module package file access' | :success
:private | :guest | true | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | :job_token | 'grants terraform module package file access' | :success
:public | :guest | true | :job_token | 'grants terraform module package file access' | :success
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | :job_token | 'grants terraform module package file access' | :success
:public | :guest | false | :job_token | 'grants terraform module package file access' | :success
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | :job_token | 'grants terraform module package file access' | :success
:private | :guest | true | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :guest | false | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:snowplow_gitlab_standard_context) do
{
project: project,
@ -253,49 +252,48 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
subject { put(url, headers: headers) }
context 'with valid project' do
where(:visibility, :user_role, :member, :token_header, :token_type, :valid_token, :shared_examples_name, :expected_status) do
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'process terraform module workhorse authorization' | :success
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'process terraform module workhorse authorization' | :success
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'JOB-TOKEN' | :job_token | true | 'process terraform module workhorse authorization' | :success
:public | :guest | true | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'JOB-TOKEN' | :job_token | true | 'process terraform module workhorse authorization' | :success
:private | :guest | true | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | true | 'process terraform module workhorse authorization' | :success
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | true | 'process terraform module workhorse authorization' | :success
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | false | 'rejects terraform module packages access' | :unauthorized
where(:visibility, :user_role, :member, :token_header, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | 'process terraform module workhorse authorization' | :success
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | nil | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | 'process terraform module workhorse authorization' | :success
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'JOB-TOKEN' | :job_token | 'process terraform module workhorse authorization' | :success
:public | :guest | true | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'JOB-TOKEN' | :job_token | 'process terraform module workhorse authorization' | :success
:private | :guest | true | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | 'process terraform module workhorse authorization' | :success
:public | :developer | true | 'DEPLOY-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | 'process terraform module workhorse authorization' | :success
:private | :developer | true | 'DEPLOY-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:headers) { user_headers.merge(workhorse_headers) }
let(:user_headers) { user_role == :anonymous ? {} : { token_header => token } }
@ -331,49 +329,48 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
end
context 'with valid project' do
where(:visibility, :user_role, :member, :token_header, :token_type, :valid_token, :shared_examples_name, :expected_status) do
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'process terraform module upload' | :created
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'process terraform module upload' | :created
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | 'PRIVATE-TOKEN' | :personal_access_token | true | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'JOB-TOKEN' | :job_token | true | 'process terraform module upload' | :created
:public | :guest | true | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'JOB-TOKEN' | :job_token | true | 'process terraform module upload' | :created
:private | :guest | true | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'JOB-TOKEN' | :job_token | true | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'JOB-TOKEN' | :job_token | false | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | true | 'process terraform module upload' | :created
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | false | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | true | 'process terraform module upload' | :created
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | false | 'rejects terraform module packages access' | :unauthorized
where(:visibility, :user_role, :member, :token_header, :token_type, :shared_examples_name, :expected_status) do
:public | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | 'process terraform module upload' | :created
:public | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :anonymous | false | nil | nil | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'PRIVATE-TOKEN' | :personal_access_token | 'process terraform module upload' | :created
:private | :guest | true | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'PRIVATE-TOKEN' | :personal_access_token | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'PRIVATE-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :anonymous | false | nil | nil | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'JOB-TOKEN' | :job_token | 'process terraform module upload' | :created
:public | :guest | true | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :guest | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:public | :developer | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :guest | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'JOB-TOKEN' | :job_token | 'process terraform module upload' | :created
:private | :guest | true | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :forbidden
:private | :developer | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | true | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :not_found
:private | :guest | false | 'JOB-TOKEN' | :job_token | 'rejects terraform module packages access' | :not_found
:private | :developer | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :guest | false | 'JOB-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:public | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | 'process terraform module upload' | :created
:public | :developer | true | 'DEPLOY-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
:private | :developer | true | 'DEPLOY-TOKEN' | :deploy_token | 'process terraform module upload' | :created
:private | :developer | true | 'DEPLOY-TOKEN' | :invalid | 'rejects terraform module packages access' | :unauthorized
end
with_them do
let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
let(:user_headers) { user_role == :anonymous ? {} : { token_header => token } }
let(:headers) { user_headers.merge(workhorse_headers) }
let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: snowplow_user } }

1389
yarn.lock

File diff suppressed because it is too large Load Diff