Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
4714aa72e3
commit
953b58d061
30 changed files with 308 additions and 48 deletions
|
@ -176,6 +176,14 @@ export const trackSaasTrialGetStarted = () => {
|
|||
});
|
||||
};
|
||||
|
||||
export const trackTrialAcceptTerms = () => {
|
||||
if (!isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
pushEvent('saasTrialAcceptTerms');
|
||||
};
|
||||
|
||||
export const trackCheckout = (selectedPlan, quantity) => {
|
||||
if (!isSupported()) {
|
||||
return;
|
||||
|
|
|
@ -11,7 +11,7 @@ export default () => {
|
|||
// eslint-disable-next-line no-new
|
||||
new BlobLinePermalinkUpdater(
|
||||
document.querySelector('#blob-content-holder'),
|
||||
'.diff-line-num[data-line-number], .diff-line-num[data-line-number] *',
|
||||
'.file-line-num[data-line-number], .file-line-num[data-line-number] *',
|
||||
document.querySelectorAll('.js-data-file-blob-permalink-url, .js-blob-blame-link'),
|
||||
);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ query getBlobInfo(
|
|||
fileType
|
||||
language
|
||||
path
|
||||
blamePath
|
||||
editBlobPath
|
||||
gitpodBlobUrl
|
||||
ideEditPath
|
||||
|
|
|
@ -7,6 +7,7 @@ import { isLoggedIn } from '~/lib/utils/common_utils';
|
|||
import { __ } from '~/locale';
|
||||
import csrf from '~/lib/utils/csrf';
|
||||
import '~/behaviors/markdown/render_gfm';
|
||||
import { trackTrialAcceptTerms } from '~/google_tag_manager';
|
||||
|
||||
export default {
|
||||
name: 'TermsApp',
|
||||
|
@ -73,6 +74,7 @@ export default {
|
|||
this.setScrollableViewportHeight();
|
||||
event.target.removeEventListener(FLASH_CLOSED_EVENT, this.handleFlashClose);
|
||||
},
|
||||
trackTrialAcceptTerms,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -99,7 +101,13 @@ export default {
|
|||
<gl-button type="submit">{{ $options.i18n.decline }}</gl-button>
|
||||
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
|
||||
</form>
|
||||
<form v-if="permissions.canAccept" class="gl-ml-3" method="post" :action="paths.accept">
|
||||
<form
|
||||
v-if="permissions.canAccept"
|
||||
class="gl-ml-3"
|
||||
method="post"
|
||||
:action="paths.accept"
|
||||
@submit="trackTrialAcceptTerms"
|
||||
>
|
||||
<gl-button
|
||||
type="submit"
|
||||
variant="confirm"
|
||||
|
|
|
@ -51,6 +51,10 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
blamePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
lines() {
|
||||
|
@ -76,6 +80,7 @@ export default {
|
|||
:number="startingFrom + index + 1"
|
||||
:content="line"
|
||||
:language="language"
|
||||
:blame-path="blamePath"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="gl-display-flex">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
|
||||
import { GlLink, GlSafeHtmlDirective, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { setAttributes } from '~/lib/utils/dom_utils';
|
||||
import { BIDI_CHARS, BIDI_CHARS_CLASS_LIST, BIDI_CHAR_TOOLTIP } from '../constants';
|
||||
|
||||
|
@ -9,6 +9,7 @@ export default {
|
|||
},
|
||||
directives: {
|
||||
SafeHtml: GlSafeHtmlDirective,
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
props: {
|
||||
number: {
|
||||
|
@ -23,6 +24,10 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
blamePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
formattedContent() {
|
||||
|
@ -58,21 +63,35 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="gl-display-flex">
|
||||
<div class="gl-p-0! gl-absolute gl-z-index-3 gl-border-r diff-line-num line-numbers">
|
||||
<div class="gl-display-flex line-links-wrapper">
|
||||
<div
|
||||
class="gl-p-0! gl-absolute gl-z-index-3 diff-line-num gl-border-r gl-display-flex line-links line-numbers"
|
||||
:class="firstLineClass"
|
||||
>
|
||||
<gl-link
|
||||
v-gl-tooltip="__('View blame')"
|
||||
class="gl-user-select-none gl-ml-3 gl-shadow-none! file-line-blame"
|
||||
:href="`${blamePath}#L${number}`"
|
||||
data-track-action="click_link"
|
||||
data-track-label="file_line_action"
|
||||
data-track-property="blame"
|
||||
/>
|
||||
|
||||
<gl-link
|
||||
:id="`L${number}`"
|
||||
class="gl-user-select-none gl-ml-5 gl-pr-3 gl-shadow-none! file-line-num diff-line-num"
|
||||
:class="firstLineClass"
|
||||
class="gl-user-select-none gl-flex-grow-1 gl-justify-content-end gl-pr-3 gl-shadow-none! file-line-num"
|
||||
:to="`#L${number}`"
|
||||
:data-line-number="number"
|
||||
data-track-action="click_link"
|
||||
data-track-label="file_line_action"
|
||||
data-track-property="link"
|
||||
>
|
||||
{{ number }}
|
||||
</gl-link>
|
||||
</div>
|
||||
|
||||
<pre
|
||||
class="gl-p-0! gl-w-full gl-overflow-visible! gl-ml-11! gl-border-none! code highlight gl-line-height-normal"
|
||||
class="gl-p-0! gl-w-full gl-overflow-visible! gl-border-none! code highlight gl-line-height-normal"
|
||||
:class="firstLineClass"
|
||||
><code><span :id="`LC${number}`" v-safe-html="formattedContent" :lang="language" class="line" data-testid="content"></span></code></pre>
|
||||
</div>
|
||||
|
|
|
@ -199,6 +199,7 @@ export default {
|
|||
:starting-from="firstChunk.startingFrom"
|
||||
:is-highlighted="firstChunk.isHighlighted"
|
||||
:language="firstChunk.language"
|
||||
:blame-path="blob.blamePath"
|
||||
/>
|
||||
|
||||
<gl-loading-icon v-if="isLoading" size="sm" class="gl-my-5" />
|
||||
|
@ -213,6 +214,7 @@ export default {
|
|||
:is-highlighted="chunk.isHighlighted"
|
||||
:chunk-index="index"
|
||||
:language="chunk.language"
|
||||
:blame-path="blob.blamePath"
|
||||
@appear="highlightChunk"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -202,6 +202,10 @@
|
|||
float: none;
|
||||
border-left: 1px solid $gray-100;
|
||||
|
||||
.file-line-num {
|
||||
@include gl-min-w-9;
|
||||
}
|
||||
|
||||
i {
|
||||
float: none;
|
||||
margin-right: 0;
|
||||
|
|
|
@ -48,8 +48,9 @@
|
|||
|
||||
a {
|
||||
font-family: $monospace-font;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
@include gl-display-flex;
|
||||
@include gl-justify-content-end;
|
||||
|
||||
i,
|
||||
svg {
|
||||
|
@ -90,3 +91,44 @@ td.line-numbers {
|
|||
cursor: pointer;
|
||||
text-decoration: underline wavy $red-500;
|
||||
}
|
||||
|
||||
.blob-viewer {
|
||||
.line-numbers {
|
||||
// for server-side-rendering
|
||||
.line-links {
|
||||
min-width: 6.5rem;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// for client
|
||||
&.line-links {
|
||||
min-width: 6.5rem;
|
||||
border-bottom-left-radius: 0;
|
||||
|
||||
+ pre {
|
||||
margin-left: 6.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line-links {
|
||||
&:hover .file-line-blame::before,
|
||||
&:hover .file-line-num::before,
|
||||
&:focus-within .file-line-blame::before,
|
||||
&:focus-within .file-line-num::before {
|
||||
@include gl-visibility-visible;
|
||||
}
|
||||
}
|
||||
|
||||
.file-line-num,
|
||||
.file-line-blame {
|
||||
@include gl-align-items-center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,32 +98,50 @@
|
|||
}
|
||||
}
|
||||
|
||||
@mixin line-number-link($color) {
|
||||
min-width: $gl-spacing-scale-9;
|
||||
|
||||
@mixin line-link($color, $icon) {
|
||||
&::before {
|
||||
@include gl-display-none;
|
||||
@include gl-visibility-hidden;
|
||||
@include gl-align-self-center;
|
||||
@include gl-mt-2;
|
||||
@include gl-mr-2;
|
||||
@include gl-w-4;
|
||||
@include gl-h-4;
|
||||
@include gl-absolute;
|
||||
@include gl-left-3;
|
||||
background-color: $color;
|
||||
mask-image: asset_url('icons-stacked.svg#link');
|
||||
@include gl-mr-1;
|
||||
@include gl-w-5;
|
||||
@include gl-h-5;
|
||||
background-color: rgba($color, 0.3);
|
||||
mask-image: asset_url('icons-stacked.svg##{$icon}');
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: cover;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
@include gl-display-inline-block;
|
||||
&:hover {
|
||||
&::before {
|
||||
background-color: rgba($color, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus::before {
|
||||
@include gl-display-inline-block;
|
||||
@mixin line-hover-bg($color: $white-normal) {
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
background-color: darken($color, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin first-line-top-space($bg-color: $gray-light, $border-color: $white-normal) {
|
||||
&:first-child {
|
||||
.line-links {
|
||||
&::before {
|
||||
@include gl-absolute;
|
||||
@include gl-h-3;
|
||||
content: '';
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
width: 6.5rem;
|
||||
background-color: $bg-color;
|
||||
border-right: 1px solid $border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,19 @@ $dark-il: #de935f;
|
|||
.code.dark {
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($dark-line-num-color);
|
||||
@include line-link($white, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($white, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg($dark-main-bg);
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space($dark-main-bg, $dark-code-border);
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
|
|
@ -119,7 +119,19 @@ $monokai-gh: #75715e;
|
|||
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($monokai-line-num-color);
|
||||
@include line-link($white, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($white, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg($monokai-bg);
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space($monokai-bg, $monokai-border);
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
|
|
@ -25,7 +25,19 @@
|
|||
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($black-transparent);
|
||||
@include line-link($black, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($black, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg;
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space;
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
|
|
@ -122,7 +122,19 @@ $solarized-dark-il: #2aa198;
|
|||
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($solarized-dark-line-color);
|
||||
@include line-link($white, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($white, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg($solarized-dark-pre-bg);
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space($solarized-dark-pre-bg, $solarized-dark-pre-border);
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
|
|
@ -108,7 +108,19 @@ $solarized-light-il: #2aa198;
|
|||
.code.solarized-light {
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($solarized-light-line-color);
|
||||
@include line-link($black, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($black, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg($solarized-light-pre-bg);
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space($solarized-light-pre-bg, $solarized-light-border);
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
|
|
@ -95,7 +95,15 @@ $white-gc-bg: #eaf2f5;
|
|||
|
||||
// Line numbers
|
||||
.file-line-num {
|
||||
@include line-number-link($black-transparent);
|
||||
@include line-link($black, 'link');
|
||||
}
|
||||
|
||||
.file-line-blame {
|
||||
@include line-link($black, 'git');
|
||||
}
|
||||
|
||||
.line-links {
|
||||
@include line-hover-bg;
|
||||
}
|
||||
|
||||
.line-numbers,
|
||||
|
@ -126,6 +134,10 @@ pre.code,
|
|||
border-color: $white-normal;
|
||||
}
|
||||
|
||||
.line-links-wrapper {
|
||||
@include first-line-top-space;
|
||||
}
|
||||
|
||||
&,
|
||||
pre.code,
|
||||
.line_holder .line_content {
|
||||
|
|
|
@ -14,6 +14,10 @@ module Users
|
|||
|
||||
before_action :terms
|
||||
|
||||
before_action only: [:index] do
|
||||
push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)
|
||||
end
|
||||
|
||||
layout 'terms'
|
||||
|
||||
feature_category :user_management
|
||||
|
|
|
@ -128,13 +128,8 @@ module MergeRequests
|
|||
if draft_event = params.delete(:wip_event)
|
||||
# We update the title that is provided in the params or we use the mr title
|
||||
title = params[:title] || merge_request.title
|
||||
# Supports both `wip` and `draft` permutations of draft_event
|
||||
# This support can be removed >= %15.2
|
||||
#
|
||||
params[:title] = case draft_event
|
||||
when 'wip' then MergeRequest.draft_title(title)
|
||||
when 'draft' then MergeRequest.draft_title(title)
|
||||
when 'unwip' then MergeRequest.draftless_title(title)
|
||||
when 'ready' then MergeRequest.draftless_title(title)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#blob-content.file-content.code.js-syntax-highlight
|
||||
- offset = defined?(first_line_number) ? first_line_number : 1
|
||||
.line-numbers
|
||||
.line-numbers{ class: "gl-p-0\!" }
|
||||
- if blob.data.present?
|
||||
- link = blob_link if defined?(blob_link)
|
||||
- blame_link = project_blame_path(@project, tree_join(@ref, blob.path))
|
||||
- blob.data.each_line.each_with_index do |_, index|
|
||||
- i = index + offset
|
||||
-# We're not using `link_to` because it is too slow once we get to thousands of lines.
|
||||
%a.file-line-num.diff-line-num{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i }
|
||||
= i
|
||||
.gl-display-flex.line-links.diff-line-num
|
||||
%a.file-line-blame.gl-display-flex.has-tooltip.gl-ml-3{ href: "#{blame_link}#L#{i}", title: _('View blame'), data: { track_action: "click_link", track_label: "file_line_action", track_property: "blame" } }
|
||||
%a.file-line-num.gl-display-flex.gl-justify-content-end.flex-grow-1.gl-pr-3{ href: "#{link}#L#{i}", id: "L#{i}", 'data-line-number' => i, data: { track_action: "click_link", track_label: "file_line_action", track_property: "link" } }
|
||||
= i
|
||||
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
|
||||
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
|
||||
%pre.code.highlight
|
||||
|
|
|
@ -138,9 +138,8 @@ module Gitlab
|
|||
def self.allow_sentry(directives)
|
||||
sentry_dsn = Gitlab.config.sentry.clientside_dsn
|
||||
sentry_uri = URI(sentry_dsn)
|
||||
sentry_uri.user = nil
|
||||
|
||||
append_to_directive(directives, 'connect_src', sentry_uri.to_s)
|
||||
append_to_directive(directives, 'connect_src', "#{sentry_uri.scheme}://#{sentry_uri.host}")
|
||||
end
|
||||
|
||||
def self.allow_letter_opener(directives)
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
trackSaasTrialGroup,
|
||||
trackSaasTrialProject,
|
||||
trackSaasTrialGetStarted,
|
||||
trackTrialAcceptTerms,
|
||||
trackCheckout,
|
||||
trackTransaction,
|
||||
trackAddToCartUsageTab,
|
||||
|
@ -255,6 +256,16 @@ describe('~/google_tag_manager/index', () => {
|
|||
expect(logError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('when trackTrialAcceptTerms is invoked', () => {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
|
||||
trackTrialAcceptTerms();
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
expect(spy).toHaveBeenCalledWith({ event: 'saasTrialAcceptTerms' });
|
||||
expect(logError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when trackCheckout is invoked', () => {
|
||||
it('with selectedPlan: 2c92a00d76f0d5060176f2fb0a5029ff', () => {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
|
|
|
@ -8,6 +8,7 @@ export const simpleViewerMock = {
|
|||
language: 'javascript',
|
||||
path: 'some_file.js',
|
||||
webPath: 'some_file.js',
|
||||
blamePath: 'blame/file.js',
|
||||
editBlobPath: 'some_file.js/edit',
|
||||
gitpodBlobUrl: 'https://gitpod.io#path/to/blob.js',
|
||||
ideEditPath: 'some_file.js/ide/edit',
|
||||
|
|
|
@ -11,6 +11,7 @@ const DEFAULT_PROPS = {
|
|||
number: 2,
|
||||
content: '// Line content',
|
||||
language: 'javascript',
|
||||
blamePath: 'blame/file.js',
|
||||
};
|
||||
|
||||
describe('Chunk Line component', () => {
|
||||
|
@ -20,7 +21,7 @@ describe('Chunk Line component', () => {
|
|||
wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
|
||||
};
|
||||
|
||||
const findLink = () => wrapper.findComponent(GlLink);
|
||||
const findLinks = () => wrapper.findAllComponents(GlLink);
|
||||
const findContent = () => wrapper.findByTestId('content');
|
||||
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
|
||||
|
||||
|
@ -47,14 +48,22 @@ describe('Chunk Line component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('renders a blame link', () => {
|
||||
expect(findLinks().at(0).attributes()).toMatchObject({
|
||||
href: `${DEFAULT_PROPS.blamePath}#L${DEFAULT_PROPS.number}`,
|
||||
});
|
||||
|
||||
expect(findLinks().at(0).text()).toBe('');
|
||||
});
|
||||
|
||||
it('renders a line number', () => {
|
||||
expect(findLink().attributes()).toMatchObject({
|
||||
expect(findLinks().at(1).attributes()).toMatchObject({
|
||||
'data-line-number': `${DEFAULT_PROPS.number}`,
|
||||
to: `#L${DEFAULT_PROPS.number}`,
|
||||
id: `L${DEFAULT_PROPS.number}`,
|
||||
});
|
||||
|
||||
expect(findLink().text()).toBe(DEFAULT_PROPS.number.toString());
|
||||
expect(findLinks().at(1).text()).toBe(DEFAULT_PROPS.number.toString());
|
||||
});
|
||||
|
||||
it('renders content', () => {
|
||||
|
|
|
@ -10,6 +10,7 @@ const DEFAULT_PROPS = {
|
|||
startingFrom: 140,
|
||||
totalLines: 50,
|
||||
language: 'javascript',
|
||||
blamePath: 'blame/file.js',
|
||||
};
|
||||
|
||||
describe('Chunk component', () => {
|
||||
|
@ -76,6 +77,7 @@ describe('Chunk component', () => {
|
|||
number: DEFAULT_PROPS.startingFrom + 1,
|
||||
content: splitContent[0],
|
||||
language: DEFAULT_PROPS.language,
|
||||
blamePath: DEFAULT_PROPS.blamePath,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,7 +40,8 @@ describe('Source Viewer component', () => {
|
|||
const chunk2 = generateContent('// Some source code 2', 70);
|
||||
const content = chunk1 + chunk2;
|
||||
const path = 'some/path.js';
|
||||
const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path };
|
||||
const blamePath = 'some/blame/path.js';
|
||||
const DEFAULT_BLOB_DATA = { language, rawTextBlob: content, path, blamePath };
|
||||
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
|
||||
|
||||
const createComponent = async (blob = {}) => {
|
||||
|
|
|
@ -92,11 +92,11 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
|
|||
context 'when sentry is configured' do
|
||||
before do
|
||||
stub_sentry_settings
|
||||
stub_config_setting(host: 'example.com')
|
||||
stub_config_setting(host: 'gitlab.example.com')
|
||||
end
|
||||
|
||||
it 'adds sentry path to CSP without user' do
|
||||
expect(directives['connect_src']).to eq("'self' ws://example.com dummy://example.com/43")
|
||||
expect(directives['connect_src']).to eq("'self' ws://gitlab.example.com dummy://example.com")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -126,4 +126,34 @@ RSpec.describe DeviseMailer do
|
|||
is_expected.to have_link("Reset password", href: "#{Gitlab.config.gitlab.url}/users/password/edit?reset_password_token=faketoken")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#email_changed' do
|
||||
subject { described_class.email_changed(user, {}) }
|
||||
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
it_behaves_like 'an email sent from GitLab'
|
||||
|
||||
it 'is sent to the user' do
|
||||
is_expected.to deliver_to user.email
|
||||
end
|
||||
|
||||
it 'has the correct subject' do
|
||||
is_expected.to have_subject 'Email Changed'
|
||||
end
|
||||
|
||||
it 'greets the user' do
|
||||
is_expected.to have_body_text /Hello, #{user.name}!/
|
||||
end
|
||||
|
||||
context "email contains updated id" do
|
||||
before do
|
||||
user.update!(email: "new_email@test.com")
|
||||
end
|
||||
|
||||
it 'includes changed email id' do
|
||||
is_expected.to have_body_text /email is being changed to new_email@test.com./
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -845,6 +845,8 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
|||
end
|
||||
|
||||
context 'when the draft status is changed' do
|
||||
let(:title) { 'New Title' }
|
||||
let(:draft_title) { "Draft: #{title}" }
|
||||
let!(:non_subscriber) { create(:user) }
|
||||
let!(:subscriber) do
|
||||
create(:user) { |u| merge_request.toggle_subscription(u, project) }
|
||||
|
@ -857,7 +859,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
|||
|
||||
context 'removing draft status' do
|
||||
before do
|
||||
merge_request.update_attribute(:title, 'Draft: New Title')
|
||||
merge_request.update_attribute(:title, draft_title)
|
||||
end
|
||||
|
||||
it 'sends notifications for subscribers', :sidekiq_might_not_need_inline do
|
||||
|
@ -870,9 +872,22 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
|||
should_email(subscriber)
|
||||
should_not_email(non_subscriber)
|
||||
end
|
||||
|
||||
context 'when removing through wip_event param' do
|
||||
it 'removes Draft from the title' do
|
||||
expect { update_merge_request({ wip_event: "ready" }) }
|
||||
.to change { merge_request.title }
|
||||
.from(draft_title)
|
||||
.to(title)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'adding draft status' do
|
||||
before do
|
||||
merge_request.update_attribute(:title, title)
|
||||
end
|
||||
|
||||
it 'does not send notifications', :sidekiq_might_not_need_inline do
|
||||
opts = { title: 'Draft: New title' }
|
||||
|
||||
|
@ -883,6 +898,15 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
|
|||
should_not_email(subscriber)
|
||||
should_not_email(non_subscriber)
|
||||
end
|
||||
|
||||
context 'when adding through wip_event param' do
|
||||
it 'adds Draft to the title' do
|
||||
expect { update_merge_request({ wip_event: "draft" }) }
|
||||
.to change { merge_request.title }
|
||||
.from(title)
|
||||
.to(draft_title)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ RSpec.shared_context 'ProjectPolicy context' do
|
|||
let_it_be_with_refind(:private_project) { create(:project, :private, namespace: owner.namespace) }
|
||||
let_it_be_with_refind(:internal_project) { create(:project, :internal, namespace: owner.namespace) }
|
||||
let_it_be_with_refind(:public_project) { create(:project, :public, namespace: owner.namespace) }
|
||||
let_it_be_with_refind(:public_project_in_group) { create(:project, :public, namespace: create(:group, :public)) }
|
||||
|
||||
let(:base_guest_permissions) do
|
||||
%i[
|
||||
|
@ -93,7 +94,7 @@ RSpec.shared_context 'ProjectPolicy context' do
|
|||
let(:owner_permissions) { base_owner_permissions + additional_owner_permissions }
|
||||
|
||||
before_all do
|
||||
[private_project, internal_project, public_project].each do |project|
|
||||
[private_project, internal_project, public_project, public_project_in_group].each do |project|
|
||||
project.add_guest(guest)
|
||||
project.add_reporter(reporter)
|
||||
project.add_developer(developer)
|
||||
|
|
|
@ -24,6 +24,7 @@ RSpec.describe 'projects/blob/_viewer.html.haml' do
|
|||
before do
|
||||
assign(:project, project)
|
||||
assign(:blob, blob)
|
||||
assign(:ref, 'master')
|
||||
assign(:id, File.join('master', blob.path))
|
||||
|
||||
controller.params[:controller] = 'projects/blob'
|
||||
|
|
Loading…
Reference in a new issue