Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-05-07 09:10:27 +00:00
parent a158bebe03
commit e8a31d8dc2
39 changed files with 420 additions and 59 deletions

View file

@ -11,7 +11,6 @@ import { contentTop } from '~/lib/utils/common_utils';
import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
headerHeight: `${contentTop()}px`,
@ -32,7 +31,17 @@ export default {
SidebarIterationWidget: () =>
import('ee_component/sidebar/components/sidebar_iteration_widget.vue'),
},
mixins: [glFeatureFlagsMixin()],
inject: {
epicFeatureAvailable: {
default: false,
},
iterationFeatureAvailable: {
default: false,
},
weightFeatureAvailable: {
default: false,
},
},
computed: {
...mapGetters([
'isSidebarOpen',
@ -77,10 +86,11 @@ export default {
class="assignee"
@assignees-updated="setAssignees"
/>
<board-sidebar-epic-select class="epic" />
<board-sidebar-epic-select v-if="epicFeatureAvailable" class="epic" />
<div>
<board-sidebar-milestone-select />
<sidebar-iteration-widget
v-if="iterationFeatureAvailable"
:iid="activeBoardItem.iid"
:workspace-path="projectPathForActiveIssue"
:iterations-workspace-path="groupPathForActiveIssue"
@ -91,7 +101,7 @@ export default {
<board-sidebar-time-tracker class="swimlanes-sidebar-time-tracker" />
<board-sidebar-due-date />
<board-sidebar-labels-select class="labels" />
<board-sidebar-weight-input v-if="glFeatures.issueWeights" class="weight" />
<board-sidebar-weight-input v-if="weightFeatureAvailable" class="weight" />
<sidebar-confidentiality-widget
:iid="activeBoardItem.iid"
:full-path="fullPath"

View file

@ -101,6 +101,8 @@ export default () => {
labelsManagePath: $boardApp.dataset.labelsManagePath,
labelsFilterBasePath: $boardApp.dataset.labelsFilterBasePath,
timeTrackingLimitToHours: parseBoolean($boardApp.dataset.timeTrackingLimitToHours),
epicFeatureAvailable: parseBoolean($boardApp.dataset.epicFeatureAvailable),
iterationFeatureAvailable: parseBoolean($boardApp.dataset.iterationFeatureAvailable),
weightFeatureAvailable: parseBoolean($boardApp.dataset.weightFeatureAvailable),
boardWeight: $boardApp.dataset.boardWeight
? parseInt($boardApp.dataset.boardWeight, 10)

View file

@ -301,7 +301,7 @@ export default {
<statistics-list v-else :counts="formattedCounts" />
</div>
<div v-if="!loading" class="col-md-6">
<strong>{{ __('Duration for the last 30 commits') }}</strong>
<strong>{{ __('Pipeline durations for the last 30 commits') }}</strong>
<gl-column-chart
:height="$options.chartContainerHeight"
:option="$options.timesChartOptions"

View file

@ -1,7 +1,6 @@
import { s__, __ } from '~/locale';
export const BRANCH_SUFFIX_COUNT = 8;
export const DEFAULT_TARGET_BRANCH = 'master';
export const ISSUABLE_TYPE = 'merge_request';
export const SUBMIT_CHANGES_BRANCH_ERROR = s__('StaticSiteEditor|Branch could not be created.');

View file

@ -9,6 +9,7 @@ const submitContentChangesResolver = (
project: projectId,
username,
sourcePath,
targetBranch,
content,
images,
mergeRequestMeta,
@ -21,6 +22,7 @@ const submitContentChangesResolver = (
projectId,
username,
sourcePath,
targetBranch,
content,
images,
mergeRequestMeta,

View file

@ -111,6 +111,7 @@ export default {
project: this.appData.project,
username: this.appData.username,
sourcePath: this.appData.sourcePath,
targetBranch: this.appData.branch,
content: this.content,
formattedMarkdown: this.formattedMarkdown,
images: this.images,

View file

@ -1,8 +1,8 @@
import { BRANCH_SUFFIX_COUNT, DEFAULT_TARGET_BRANCH } from '../constants';
import { BRANCH_SUFFIX_COUNT } from '../constants';
const generateBranchSuffix = () => `${Date.now()}`.substr(BRANCH_SUFFIX_COUNT);
const generateBranchName = (username, targetBranch = DEFAULT_TARGET_BRANCH) =>
const generateBranchName = (username, targetBranch) =>
`${username}-${targetBranch}-patch-${generateBranchSuffix()}`;
export default generateBranchName;

View file

@ -4,7 +4,6 @@ import generateBranchName from '~/static_site_editor/services/generate_branch_na
import Tracking from '~/tracking';
import {
DEFAULT_TARGET_BRANCH,
SUBMIT_CHANGES_BRANCH_ERROR,
SUBMIT_CHANGES_COMMIT_ERROR,
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
@ -16,9 +15,9 @@ import {
DEFAULT_FORMATTING_CHANGES_COMMIT_DESCRIPTION,
} from '../constants';
const createBranch = (projectId, branch) =>
const createBranch = (projectId, branch, targetBranch) =>
Api.createBranch(projectId, {
ref: DEFAULT_TARGET_BRANCH,
ref: targetBranch,
branch,
}).catch(() => {
throw new Error(SUBMIT_CHANGES_BRANCH_ERROR);
@ -73,13 +72,7 @@ const commit = (projectId, message, branch, actions) => {
});
};
const createMergeRequest = (
projectId,
title,
description,
sourceBranch,
targetBranch = DEFAULT_TARGET_BRANCH,
) => {
const createMergeRequest = (projectId, title, description, sourceBranch, targetBranch) => {
Tracking.event(document.body.dataset.page, TRACKING_ACTION_CREATE_MERGE_REQUEST);
Api.trackRedisCounterEvent(USAGE_PING_TRACKING_ACTION_CREATE_MERGE_REQUEST);
@ -100,16 +93,17 @@ const submitContentChanges = ({
username,
projectId,
sourcePath,
targetBranch,
content,
images,
mergeRequestMeta,
formattedMarkdown,
}) => {
const branch = generateBranchName(username);
const branch = generateBranchName(username, targetBranch);
const { title: mergeRequestTitle, description: mergeRequestDescription } = mergeRequestMeta;
const meta = {};
return createBranch(projectId, branch)
return createBranch(projectId, branch, targetBranch)
.then(({ data: { web_url: url } }) => {
const message = `${DEFAULT_FORMATTING_CHANGES_COMMIT_MESSAGE}\n\n${DEFAULT_FORMATTING_CHANGES_COMMIT_DESCRIPTION}`;
@ -133,7 +127,13 @@ const submitContentChanges = ({
.then(({ data: { short_id: label, web_url: url } }) => {
Object.assign(meta, { commit: { label, url } });
return createMergeRequest(projectId, mergeRequestTitle, mergeRequestDescription, branch);
return createMergeRequest(
projectId,
mergeRequestTitle,
mergeRequestDescription,
branch,
targetBranch,
);
})
.then(({ data: { iid: label, web_url: url } }) => {
Object.assign(meta, { mergeRequest: { label: label.toString(), url } });

View file

@ -22,6 +22,7 @@ class ApplicationController < ActionController::Base
include Gitlab::Logging::CloudflareHelper
include Gitlab::Utils::StrongMemoize
include ::Gitlab::WithFeatureCategory
include FlocOptOut
before_action :authenticate_user!, except: [:route_not_found]
before_action :enforce_terms!, if: :should_enforce_terms?

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
module FlocOptOut
extend ActiveSupport::Concern
included do
after_action :set_floc_opt_out_header, unless: :floc_enabled?
end
def floc_enabled?
Gitlab::CurrentSettings.floc_enabled
end
def set_floc_opt_out_header
response.headers['Permissions-Policy'] = 'interest-cohort=()'
end
end

View file

@ -233,6 +233,7 @@ module ApplicationSettingsHelper
:external_pipeline_validation_service_token,
:external_pipeline_validation_service_url,
:first_day_of_week,
:floc_enabled,
:force_pages_access_control,
:gitaly_timeout_default,
:gitaly_timeout_medium,

View file

@ -504,6 +504,9 @@ class ApplicationSetting < ApplicationRecord
validates :whats_new_variant,
inclusion: { in: ApplicationSetting.whats_new_variants.keys }
validates :floc_enabled,
inclusion: { in: [true, false], message: _('must be a boolean value') }
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,

View file

@ -77,6 +77,7 @@ module ApplicationSettingImplementation
external_pipeline_validation_service_token: nil,
external_pipeline_validation_service_url: nil,
first_day_of_week: 0,
floc_enabled: false,
gitaly_timeout_default: 55,
gitaly_timeout_fast: 10,
gitaly_timeout_medium: 30,

View file

@ -0,0 +1,22 @@
- expanded = integration_expanded?('floc_')
%section.settings.no-animate#js-floc-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
= s_('FloC|Federated Learning of Cohorts')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= s_('FloC|Configure whether you want to participate in FloC.').html_safe
= link_to sprite_icon('question-o'), 'https://github.com/WICG/floc', target: '_blank', class: 'has-tooltip', title: _('More information')
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-floc-settings'), html: { class: 'fieldset-form', id: 'floc-settings' } do |f|
= form_errors(@application_setting)
%fieldset
.form-group
.form-check
= f.check_box :floc_enabled, class: 'form-check-input'
= f.label :floc_enabled, s_('FloC|Enable FloC (Federated Learning of Cohorts)'), class: 'form-check-label'
= f.submit s_('Save changes'), class: 'gl-button btn btn-confirm'

View file

@ -112,3 +112,4 @@
= render 'admin/application_settings/third_party_offers'
= render 'admin/application_settings/snowplow'
= render 'admin/application_settings/eks'
= render 'admin/application_settings/floc'

View file

@ -0,0 +1,5 @@
---
title: Add API endpoint for deleting a package file
merge_request: 60970
author:
type: added

View file

@ -0,0 +1,5 @@
---
title: Application setting for FloC participation (disabled by default)
merge_request: 60933
author:
type: added

View file

@ -0,0 +1,8 @@
---
name: track_epic_boards_activity
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60357
rollout_issue_url:
milestone: '13.12'
type: development
group: group::product planning
default_enabled: true

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddFlocApplicationSettings < ActiveRecord::Migration[6.0]
def change
add_column :application_settings, :floc_enabled, :boolean, default: false, null: false
end
end

View file

@ -0,0 +1 @@
9d1254393da80e0b1e387fba493f83f8775f0340f23c648e638a9983f965f5c9

View file

@ -9513,6 +9513,7 @@ CREATE TABLE application_settings (
whats_new_variant smallint DEFAULT 0,
encrypted_spam_check_api_key bytea,
encrypted_spam_check_api_key_iv bytea,
floc_enabled boolean DEFAULT false NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),

View file

@ -352,3 +352,33 @@ Can return the following status codes:
- `204 No Content`, if the package was deleted successfully.
- `404 Not Found`, if the package was not found.
## Delete a package file
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32107) in GitLab 13.12.
WARNING:
Deleting a package file may corrupt your package making it unusable or unpullable from your package
manager client. When deleting a package file, be sure that you understand what you're doing.
Delete a package file:
```plaintext
DELETE /projects/:id/packages/:package_id/package_files/:package_file_id
```
| Attribute | Type | Required | Description |
| ----------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
| `package_id` | integer | yes | ID of a package. |
| `package_file_id` | integer | yes | ID of a package file. |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages/:package_id/package_files/:package_file_id"
```
Can return the following status codes:
- `204 No Content`: The package was deleted successfully.
- `403 Forbidden`: The user does not have permission to delete the file.
- `404 Not Found`: The package or package file was not found.

View file

@ -88,6 +88,7 @@ Example response:
"rate_limiting_response_text": null,
"keep_latest_artifact": true,
"admin_mode": false,
"floc_enabled": false,
"external_pipeline_validation_service_timeout": null,
"external_pipeline_validation_service_token": null,
"external_pipeline_validation_service_url": null

View file

@ -10234,6 +10234,78 @@ Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_creating_epic_boards_monthly`
Count of MAU creating epic boards
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210428072511_g_project_management_users_creating_epic_boards_monthly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_creating_epic_boards_weekly`
Count of WAU creating epic boards
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210428072508_g_project_management_users_creating_epic_boards_weekly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_updating_epic_board_names_monthly`
Count of MAU updating epic board names
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210428073607_g_project_management_users_updating_epic_board_names_monthly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_updating_epic_board_names_weekly`
Count of WAU updating epic board names
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210428073604_g_project_management_users_updating_epic_board_names_weekly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_viewing_epic_boards_monthly`
Count of MAU viewing epic boards
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210428073329_g_project_management_users_viewing_epic_boards_monthly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epic_boards_usage.g_project_management_users_viewing_epic_boards_weekly`
Count of WAU viewing epic boards
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210428073327_g_project_management_users_viewing_epic_boards_weekly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epics_usage.epics_usage_total_unique_counts_monthly`
Total monthly users count for epics_usage

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -92,11 +92,11 @@ Please note that the certificate [fingerprint algorithm](../../../integration/sa
### SSO enforcement
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5291) in GitLab 11.8.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9255) in GitLab 11.11 with ongoing enforcement in the GitLab UI.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/292811) in GitLab 13.8, with an updated timeout experience.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/211962) in GitLab 13.8 with allowing group owners to not go through SSO.
- [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9152) in GitLab 13.11 with enforcing open SSO session to use Git if this setting is switched on.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5291) in GitLab 11.8.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9255) in GitLab 11.11 with ongoing enforcement in the GitLab UI.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/292811) in GitLab 13.8, with an updated timeout experience.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/211962) in GitLab 13.8 with allowing group owners to not go through SSO.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9152) in GitLab 13.11 with enforcing open SSO session to use Git if this setting is switched on.
With this option enabled, users (except owners) must go through your group's GitLab single sign-on URL if they wish to access group resources through the UI. Users can't be manually added as members.

View file

@ -30,6 +30,29 @@ module API
present paginate(package.package_files), with: ::API::Entities::PackageFile
end
desc 'Remove a package file' do
detail 'This feature was introduced in GitLab 13.12'
end
params do
requires :package_file_id, type: Integer, desc: 'The ID of a package file'
end
delete ':id/packages/:package_id/package_files/:package_file_id' do
authorize_destroy_package!(user_project)
# We want to make sure the file belongs to the declared package
# so we look up the package before looking up the file.
package = ::Packages::PackageFinder
.new(user_project, params[:package_id]).execute
not_found! unless package
package_file = package.package_files.find_by_id(params[:package_file_id])
not_found! unless package_file
destroy_conditionally!(package_file)
end
end
end
end

View file

@ -171,6 +171,7 @@ module API
optional :wiki_page_max_content_bytes, type: Integer, desc: "Maximum wiki page content size in bytes"
optional :require_admin_approval_after_user_signup, type: Boolean, desc: 'Require explicit admin approval for new signups'
optional :whats_new_variant, type: String, values: ApplicationSetting.whats_new_variants.keys, desc: "What's new variant, possible values: `all_tiers`, `current_tier`, and `disabled`."
optional :floc_enabled, type: Grape::API::Boolean, desc: 'Enable FloC (Federated Learning of Cohorts)'
ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
optional :"#{type}_key_restriction",

View file

@ -0,0 +1,22 @@
# Epic board events
#
# We are using the same slot of issue events 'project_management' for
# epic events to allow data aggregation.
# More information in: https://gitlab.com/gitlab-org/gitlab/-/issues/322405
- name: g_project_management_users_creating_epic_boards
category: epic_boards_usage
redis_slot: project_management
aggregation: daily
feature_flag: track_epic_boards_activity
- name: g_project_management_users_viewing_epic_boards
category: epic_boards_usage
redis_slot: project_management
aggregation: daily
feature_flag: track_epic_boards_activity
- name: g_project_management_users_updating_epic_board_names
category: epic_boards_usage
redis_slot: project_management
aggregation: daily
feature_flag: track_epic_boards_activity

View file

@ -11738,9 +11738,6 @@ msgstr ""
msgid "Duration"
msgstr ""
msgid "Duration for the last 30 commits"
msgstr ""
msgid "During this process, youll be asked for URLs from GitLabs side. Use the URLs shown below."
msgstr ""
@ -14097,6 +14094,15 @@ msgstr ""
msgid "Flags"
msgstr ""
msgid "FloC|Configure whether you want to participate in FloC."
msgstr ""
msgid "FloC|Enable FloC (Federated Learning of Cohorts)"
msgstr ""
msgid "FloC|Federated Learning of Cohorts"
msgstr ""
msgid "FlowdockService|1b609b52537..."
msgstr ""
@ -14856,10 +14862,10 @@ msgstr ""
msgid "Geo|Verification failed - %{error}"
msgstr ""
msgid "Geo|Verification status"
msgid "Geo|Verification information"
msgstr ""
msgid "Geo|Verificaton information"
msgid "Geo|Verification status"
msgstr ""
msgid "Geo|Waiting for scheduler"
@ -23668,6 +23674,9 @@ msgstr ""
msgid "Pipeline Schedules"
msgstr ""
msgid "Pipeline durations for the last 30 commits"
msgstr ""
msgid "Pipeline minutes quota"
msgstr ""

View file

@ -1027,4 +1027,44 @@ RSpec.describe ApplicationController do
get :index
end
end
describe 'setting permissions-policy header' do
controller do
skip_before_action :authenticate_user!
def index
render html: 'It is a flock of sheep, not a floc of sheep.'
end
end
before do
routes.draw do
get 'index' => 'anonymous#index'
end
end
context 'with FloC enabled' do
before do
stub_application_setting floc_enabled: true
end
it 'does not set the Permissions-Policy header' do
get :index
expect(response.headers['Permissions-Policy']).to eq(nil)
end
end
context 'with FloC disabled' do
before do
stub_application_setting floc_enabled: false
end
it 'sets the Permissions-Policy header' do
get :index
expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
end
end
end
end

View file

@ -75,7 +75,7 @@ RSpec.describe 'Project Graph', :js do
expect(page).to have_content 'Last week'
expect(page).to have_content 'Last month'
expect(page).to have_content 'Last year'
expect(page).to have_content 'Duration for the last 30 commits'
expect(page).to have_content 'Pipeline durations for the last 30 commits'
end
end
end

View file

@ -55,7 +55,7 @@ export const mergeRequestTemplates = [
export const submitChangesError = 'Could not save changes';
export const commitBranchResponse = {
web_url: '/tree/root-master-patch-88195',
web_url: '/tree/root-main-patch-88195',
};
export const commitMultipleResponse = {
short_id: 'ed899a2f4b5',
@ -84,8 +84,8 @@ export const mounts = [
},
];
export const branch = 'master';
export const branch = 'main';
export const baseUrl = '/user1/project1/-/sse/master%2Ftest.md';
export const baseUrl = '/user1/project1/-/sse/main%2Ftest.md';
export const imageRoot = 'source/images/';

View file

@ -275,6 +275,7 @@ describe('static_site_editor/pages/home', () => {
formattedMarkdown,
project,
sourcePath,
targetBranch: branch,
username,
images,
mergeRequestMeta,

View file

@ -1,7 +1,7 @@
import { DEFAULT_TARGET_BRANCH, BRANCH_SUFFIX_COUNT } from '~/static_site_editor/constants';
import { BRANCH_SUFFIX_COUNT } from '~/static_site_editor/constants';
import generateBranchName from '~/static_site_editor/services/generate_branch_name';
import { username } from '../mock_data';
import { username, branch as targetBranch } from '../mock_data';
describe('generateBranchName', () => {
const timestamp = 12345678901234;
@ -11,11 +11,11 @@ describe('generateBranchName', () => {
});
it('generates a name that includes the username and target branch', () => {
expect(generateBranchName(username)).toMatch(`${username}-${DEFAULT_TARGET_BRANCH}`);
expect(generateBranchName(username, targetBranch)).toMatch(`${username}-${targetBranch}`);
});
it(`adds the first ${BRANCH_SUFFIX_COUNT} numbers of the current timestamp`, () => {
expect(generateBranchName(username)).toMatch(
expect(generateBranchName(username, targetBranch)).toMatch(
timestamp.toString().substring(BRANCH_SUFFIX_COUNT),
);
});

View file

@ -47,11 +47,11 @@ describe('rich_content_editor/renderers/render_image', () => {
it.each`
destination | isAbsolute | src
${'http://test.host/absolute/path/to/image.png'} | ${true} | ${'http://test.host/absolute/path/to/image.png'}
${'/relative/path/to/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/master/default/source/relative/path/to/image.png'}
${'/target/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/master/source/with/target/image.png'}
${'relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/master/relative/to/current/image.png'}
${'./relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/master/./relative/to/current/image.png'}
${'../relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/master/../relative/to/current/image.png'}
${'/relative/path/to/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/main/default/source/relative/path/to/image.png'}
${'/target/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/main/source/with/target/image.png'}
${'relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/main/relative/to/current/image.png'}
${'./relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/main/./relative/to/current/image.png'}
${'../relative/to/current/image.png'} | ${false} | ${'http://test.host/user1/project1/-/raw/main/../relative/to/current/image.png'}
`('returns an image with the correct attributes', ({ destination, isAbsolute, src }) => {
node.destination = destination;

View file

@ -3,7 +3,6 @@ import Api from '~/api';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import {
DEFAULT_TARGET_BRANCH,
SUBMIT_CHANGES_BRANCH_ERROR,
SUBMIT_CHANGES_COMMIT_ERROR,
SUBMIT_CHANGES_MERGE_REQUEST_ERROR,
@ -25,6 +24,7 @@ import {
createMergeRequestResponse,
mergeRequestMeta,
sourcePath,
branch as targetBranch,
sourceContentYAML as content,
trackingCategory,
images,
@ -33,7 +33,7 @@ import {
jest.mock('~/static_site_editor/services/generate_branch_name');
describe('submitContentChanges', () => {
const branch = 'branch-name';
const sourceBranch = 'branch-name';
let trackingSpy;
let origPage;
@ -41,6 +41,7 @@ describe('submitContentChanges', () => {
username,
projectId,
sourcePath,
targetBranch,
content,
images,
mergeRequestMeta,
@ -54,7 +55,7 @@ describe('submitContentChanges', () => {
.spyOn(Api, 'createProjectMergeRequest')
.mockResolvedValue({ data: createMergeRequestResponse });
generateBranchName.mockReturnValue(branch);
generateBranchName.mockReturnValue(sourceBranch);
origPage = document.body.dataset.page;
document.body.dataset.page = trackingCategory;
@ -69,8 +70,8 @@ describe('submitContentChanges', () => {
it('creates a branch named after the username and target branch', () => {
return submitContentChanges(buildPayload()).then(() => {
expect(Api.createBranch).toHaveBeenCalledWith(projectId, {
ref: DEFAULT_TARGET_BRANCH,
branch,
ref: targetBranch,
branch: sourceBranch,
});
});
});
@ -86,7 +87,7 @@ describe('submitContentChanges', () => {
describe('committing markdown formatting changes', () => {
const formattedMarkdown = `formatted ${content}`;
const commitPayload = {
branch,
branch: sourceBranch,
commit_message: `${DEFAULT_FORMATTING_CHANGES_COMMIT_MESSAGE}\n\n${DEFAULT_FORMATTING_CHANGES_COMMIT_DESCRIPTION}`,
actions: [
{
@ -116,7 +117,7 @@ describe('submitContentChanges', () => {
it('commits the content changes to the branch when creating branch succeeds', () => {
return submitContentChanges(buildPayload()).then(() => {
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, {
branch,
branch: sourceBranch,
commit_message: mergeRequestMeta.title,
actions: [
{
@ -140,7 +141,7 @@ describe('submitContentChanges', () => {
const payload = buildPayload({ content: contentWithoutImages });
return submitContentChanges(payload).then(() => {
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, {
branch,
branch: sourceBranch,
commit_message: mergeRequestMeta.title,
actions: [
{
@ -169,8 +170,8 @@ describe('submitContentChanges', () => {
convertObjectPropsToSnakeCase({
title,
description,
targetBranch: DEFAULT_TARGET_BRANCH,
sourceBranch: branch,
targetBranch,
sourceBranch,
}),
);
});
@ -194,7 +195,7 @@ describe('submitContentChanges', () => {
});
it('returns the branch name', () => {
expect(result).toMatchObject({ branch: { label: branch } });
expect(result).toMatchObject({ branch: { label: sourceBranch } });
});
it('returns commit short id and web url', () => {

View file

@ -45,6 +45,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'quickactions',
'pipeline_authoring',
'epics_usage',
'epic_boards_usage',
'secure'
)
end

View file

@ -7,13 +7,13 @@ RSpec.describe API::PackageFiles do
let(:project) { create(:project, :public) }
let(:package) { create(:maven_package, project: project) }
before do
project.add_developer(user)
end
describe 'GET /projects/:id/packages/:package_id/package_files' do
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files" }
before do
project.add_developer(user)
end
context 'without the need for a license' do
context 'project is public' do
it 'returns 200' do
@ -78,4 +78,77 @@ RSpec.describe API::PackageFiles do
end
end
end
describe 'DELETE /projects/:id/packages/:package_id/package_files/:package_file_id' do
let(:package_file_id) { package.package_files.first.id }
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files/#{package_file_id}" }
subject(:api_request) { delete api(url, user) }
context 'project is public' do
context 'without user' do
let(:user) { nil }
it 'returns 403 for non authenticated user', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
it 'returns 403 for a user without access to the project', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'project is private' do
let_it_be_with_refind(:project) { create(:project, :private) }
it 'returns 404 for a user without access to the project', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns 403 for a user without enough permissions', :aggregate_failures do
project.add_developer(user)
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'returns 204', :aggregate_failures do
project.add_maintainer(user)
expect { api_request }.to change { package.package_files.count }.by(-1)
expect(response).to have_gitlab_http_status(:no_content)
end
context 'without user' do
let(:user) { nil }
it 'returns 404 for non authenticated user', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'invalid file' do
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files/999999" }
it 'returns 404 when the package file does not exist', :aggregate_failures do
project.add_maintainer(user)
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
end