提交 04edf654 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 ada214dc
......@@ -47,7 +47,7 @@ https://about.gitlab.com/handbook/engineering/ux/ux-research-training/user-story
### Documentation
<!-- See the Feature Change Documentation Workflow https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html
<!-- See the Feature Change Documentation Workflow https://docs.gitlab.com/ee/development/documentation/workflow.html#for-a-product-change
* Add all known Documentation Requirements in this section. See https://docs.gitlab.com/ee/development/documentation/feature-change-workflow.html#documentation-requirements
* If this feature requires changing permissions, update the permissions document. See https://docs.gitlab.com/ee/user/permissions.html -->
......
<script>
import { GlEmptyState, GlDeprecatedButton, GlLoadingIcon, GlTable, GlAlert } from '@gitlab/ui';
import { s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import getAlerts from '../graphql/queries/getAlerts.query.graphql';
const tdClass = 'table-col d-flex';
export default {
i18n: {
noAlertsMsg: s__(
......@@ -18,33 +17,29 @@ export default {
{
key: 'severity',
label: s__('AlertManagement|Severity'),
tdClass,
},
{
key: 'start_time',
label: s__('AlertManagement|Start Time'),
tdClass,
key: 'startedAt',
label: s__('AlertManagement|Start time'),
},
{
key: 'end_time',
label: s__('AlertManagement|End Time'),
tdClass,
key: 'endedAt',
label: s__('AlertManagement|End time'),
},
{
key: 'alert',
key: 'title',
label: s__('AlertManagement|Alert'),
thClass: 'w-30p',
tdClass,
},
{
key: 'events',
key: 'eventCount',
label: s__('AlertManagement|Events'),
tdClass,
thClass: 'text-right event-count',
tdClass: 'text-right event-count',
},
{
key: 'status',
label: s__('AlertManagement|Status'),
tdClass,
},
],
components: {
......@@ -53,9 +48,10 @@ export default {
GlTable,
GlAlert,
GlDeprecatedButton,
TimeAgo,
},
props: {
indexPath: {
projectPath: {
type: String,
required: true,
},
......@@ -81,9 +77,12 @@ export default {
query: getAlerts,
variables() {
return {
projectPath: this.indexPath,
projectPath: this.projectPath,
};
},
update(data) {
return data.project.alertManagementAlerts.nodes;
},
error() {
this.errored = true;
},
......@@ -128,18 +127,34 @@ export default {
:show-empty="true"
:busy="loading"
fixed
stacked="sm"
tbody-tr-class="table-row mb-4"
stacked="md"
>
<template #cell(startedAt)="{ item }">
<time-ago :time="item.startedAt" />
</template>
<template #cell(endedAt)="{ item }">
<time-ago :time="item.endedAt" />
</template>
<template #cell(title)="{ item }">
<div class="gl-max-w-full text-truncate">{{ item.title }}</div>
</template>
<template #empty>
{{ s__('AlertManagement|No alerts to display.') }}
</template>
<template #table-busy>
<gl-loading-icon size="lg" color="dark" class="mt-3" />
</template>
</gl-table>
</div>
<gl-empty-state v-else :title="__('Surface alerts in GitLab')" :svg-path="emptyAlertSvgPath">
<gl-empty-state
v-else
:title="__('AlertManagement|Surface alerts in GitLab')"
:svg-path="emptyAlertSvgPath"
>
<template #description>
<div class="d-block">
<span>{{
......
fragment AlertListItem on Alert {
fragment AlertListItem on AlertManagementAlert {
iid
title
severity
status
started_at
ended_at
event_count
startedAt
endedAt
eventCount
}
#import "../fragments/listItem.fragment.graphql"
query getAlerts(
$projectPath: ID!
) {
query getAlerts($projectPath: ID!) {
project(fullPath: $projectPath) {
alerts {
...AlertListItem
alertManagementAlerts {
nodes {
...AlertListItem
}
}
}
}
......@@ -10,7 +10,7 @@ export default () => {
const selector = '#js-alert_management';
const domEl = document.querySelector(selector);
const { indexPath, enableAlertManagementPath, emptyAlertSvgPath } = domEl.dataset;
const { projectPath, enableAlertManagementPath, emptyAlertSvgPath } = domEl.dataset;
let { alertManagementEnabled, userCanEnableAlertManagement } = domEl.dataset;
alertManagementEnabled = parseBoolean(alertManagementEnabled);
......@@ -29,7 +29,7 @@ export default () => {
render(createElement) {
return createElement('alert-management-list', {
props: {
indexPath,
projectPath,
enableAlertManagementPath,
emptyAlertSvgPath,
alertManagementEnabled,
......
......@@ -41,6 +41,8 @@ export const SET_CURRENT_VIEW_DIFF_FILE_LINES = 'SET_CURRENT_VIEW_DIFF_FILE_LINE
export const ADD_CURRENT_VIEW_DIFF_FILE_LINES = 'ADD_CURRENT_VIEW_DIFF_FILE_LINES';
export const TOGGLE_DIFF_FILE_RENDERING_MORE = 'TOGGLE_DIFF_FILE_RENDERING_MORE';
export const SET_DIFF_FILE_VIEWER = 'SET_DIFF_FILE_VIEWER';
export const SET_SHOW_SUGGEST_POPOVER = 'SET_SHOW_SUGGEST_POPOVER';
export const TOGGLE_LINE_DISCUSSIONS = 'TOGGLE_LINE_DISCUSSIONS';
......@@ -383,6 +383,11 @@ export default {
file.renderingLines = !file.renderingLines;
},
[types.SET_DIFF_FILE_VIEWER](state, { filePath, viewer }) {
const file = findDiffFile(state.diffFiles, filePath, 'file_path');
file.viewer = viewer;
},
[types.SET_SHOW_SUGGEST_POPOVER](state) {
state.showSuggestPopover = false;
},
......
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
.alert-management-list {
// these styles need to be deleted once GlTable component looks in GitLab same as in @gitlab/ui
table {
color: $gray-700;
tr {
td,
th {
@include gl-p-4;
@include gl-p-5;
&.event-count {
@include gl-pr-9;
}
}
th {
......@@ -18,8 +22,10 @@
border-color: $gray-100;
}
td {
@include gl-border-0;
&:last-child {
td {
@include gl-border-0;
}
}
}
}
......
# frozen_string_literal: true
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
# frozen_string_literal: true
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_user_from_session_store
end
private
def find_user_from_session_store
session = ActiveSession.sessions_from_ids([session_id]).first
Warden::SessionSerializer.new('rack.session' => session).fetch(:user)
end
def session_id
Rack::Session::SessionId.new(cookies[Gitlab::Application.config.session_options[:key]])
end
end
end
# frozen_string_literal: true
class IssuesChannel < ApplicationCable::Channel
def subscribed
project = Project.find_by_full_path(params[:project_path])
return reject unless project
issue = project.issues.find_by_iid(params[:iid])
return reject unless issue && Ability.allowed?(current_user, :read_issue, issue)
stream_for issue
end
end
......@@ -3,8 +3,7 @@
module Projects::AlertManagementHelper
def alert_management_data(current_user, project)
{
'index-path' => project_alert_management_index_path(project,
format: :json),
'project-path' => project.full_path,
'enable-alert-management-path' => project_settings_operations_path(project),
'empty-alert-svg-path' => image_path('illustrations/alert-management-empty-state.svg'),
'user-can-enable-alert-management' => 'false',
......
......@@ -124,7 +124,7 @@ class ActiveSession
end
end
# Lists the ActiveSession objects for the given session IDs.
# Lists the session Hash objects for the given session IDs.
#
# session_ids - An array of Rack::Session::SessionId objects
#
......@@ -143,7 +143,7 @@ class ActiveSession
end
end
# Deserializes an ActiveSession object from Redis.
# Deserializes a session Hash object from Redis.
#
# raw_session - Raw bytes from Redis
#
......
......@@ -5,10 +5,13 @@ class ApplicationSetting < ApplicationRecord
include CacheMarkdownField
include TokenAuthenticatable
include ChronicDurationAttribute
include IgnorableColumns
GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \
'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
ignore_column :elasticsearch_experimental_indexer, remove_with: '13.1', remove_after: '2020-05-22'
add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption, default_enabled: true) ? :optional : :required }
add_authentication_token_field :health_check_access_token
add_authentication_token_field :static_objects_external_storage_auth_token
......
......@@ -224,6 +224,7 @@ class ProjectPolicy < BasePolicy
enable :read_build
enable :read_container_image
enable :read_pipeline
enable :read_pipeline_schedule
enable :read_environment
enable :read_deployment
enable :read_merge_request
......@@ -281,7 +282,6 @@ class ProjectPolicy < BasePolicy
enable :update_commit_status
enable :create_build
enable :update_build
enable :read_pipeline_schedule
enable :create_merge_request_from
enable :create_wiki
enable :push_code
......@@ -422,6 +422,7 @@ class ProjectPolicy < BasePolicy
prevent :fork_project
prevent :read_commit_status
prevent :read_pipeline
prevent :read_pipeline_schedule
prevent(*create_read_update_admin_destroy(:release))
end
......@@ -448,6 +449,7 @@ class ProjectPolicy < BasePolicy
enable :read_merge_request
enable :read_note
enable :read_pipeline
enable :read_pipeline_schedule
enable :read_commit_status
enable :read_container_image
enable :download_code
......@@ -466,6 +468,7 @@ class ProjectPolicy < BasePolicy
rule { public_builds & can?(:guest_access) }.policy do
enable :read_pipeline
enable :read_pipeline_schedule
end
# These rules are included to allow maintainers of projects to push to certain
......
......@@ -21,6 +21,10 @@ module Issues
spam_check(issue, current_user) unless skip_spam_check
end
def after_update(issue)
IssuesChannel.broadcast_to(issue, event: 'updated') if Feature.enabled?(:broadcast_issue_updates, issue.project)
end
def handle_changes(issue, options)
old_associations = options.fetch(:old_associations, {})
old_labels = old_associations.fetch(:labels, [])
......
---
title: Allow public access to pipeline schedules
merge_request: 20806
author: Lee Tickett
type: fixed
---
title: Disable schema dumping after migrations in production
merge_request: 30812
author:
type: fixed
# This file is used for configuring ActionCable in our CI environment
# When using GDK or Omnibus, cable.yml is generated from a different template
development:
adapter: redis
url: redis://localhost:6379
channel_prefix: gitlab_development
test:
adapter: redis
url: redis://localhost:6379
channel_prefix: gitlab_test
production:
adapter: redis
url: unix:/var/run/redis/redis.sock
channel_prefix: gitlab_production
......@@ -52,6 +52,9 @@ Rails.application.configure do
# Enable serving of images, stylesheets, and JavaScripts from an asset server
config.action_controller.asset_host = ENV['GITLAB_CDN_HOST'] if ENV['GITLAB_CDN_HOST'].present?
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js )
......
......@@ -77,6 +77,24 @@ CSS classes should use the `lowercase-hyphenated` format rather than
}
```
Class names should be used instead of tag name selectors.
Using tag name selectors are discouraged in CSS because
they can affect unintended elements in the hierarchy.
Also, since they are not meaningful names, they do not
add meaning to the code.
```scss
// Bad
ul {
color: #fff;
}
// Good
.class-name {
color: #fff;
}
```
### Formatting
You should always use a space before a brace, braces should be on the same
......
......@@ -27,12 +27,18 @@ The following resources will help you get started with Git:
- [Git on the Server - GitLab](https://git-scm.com/book/en/v2/Git-on-the-Server-GitLab)
- [How to install Git](how_to_install_git/index.md)
- [Start using Git on the command line](../../gitlab-basics/start-using-git.md)
- [Command Line basic commands](../../gitlab-basics/command-line-commands.md)
- [Command line file editing basic commands](../../gitlab-basics/command-line-commands.md)
- [GitLab Git Cheat Sheet (download)](https://about.gitlab.com/images/press/git-cheat-sheet.pdf)
- Commits:
- [Revert a commit](../../user/project/merge_requests/revert_changes.md#reverting-a-commit)
- [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
- [Squashing commits](../gitlab_flow.md#squashing-commits-with-rebase)
- [Squash-and-merge](../../user/project/merge_requests/squash_and_merge.md)
- [Signing commits](../../user/project/repository/gpg_signed_commits/index.md)
- [Git stash](../../university/training/topics/stash.md)
- [Git file blame](../../user/project/repository/git_blame.md)
- [Git file history](../../user/project/repository/git_history.md)
- [Git tags](../../university/training/user_training.md#tags)
### Concepts
......@@ -61,9 +67,10 @@ If you have problems with Git, the following may help:
## Branching strategies
- [Feature branch workflow](../../gitlab-basics/feature_branch_workflow.md)
- [GitLab Flow](../gitlab_flow.md)
- [Git Branching - Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)
- [Git Branching - Branching Workflows](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows)
- [GitLab Flow](https://about.gitlab.com/blog/2014/09/29/gitlab-flow/)
## Advanced use
......@@ -88,5 +95,5 @@ The following relate to Git Large File Storage:
- [Removing objects from LFS](lfs/index.md#removing-objects-from-lfs)
- [GitLab Git LFS user documentation](lfs/index.md)
- [GitLab Git LFS admin documentation](../../administration/lfs/index.md)
- [git-annex to Git-LFS migration guide](lfs/migrate_from_git_annex_to_git_lfs.md)
- [Git Annex to Git LFS migration guide](lfs/migrate_from_git_annex_to_git_lfs.md)
- [Towards a production quality open source Git LFS server](https://about.gitlab.com/blog/2015/08/13/towards-a-production-quality-open-source-git-lfs-server/)
......@@ -25,9 +25,6 @@ module Gitlab
signup_flow: {
tracking_category: 'Growth::Acquisition::Experiment::SignUpFlow'
},
paid_signup_flow: {
tracking_category: 'Growth::Acquisition::Experiment::PaidSignUpFlow'
},
suggest_pipeline: {
tracking_category: 'Growth::Expansion::Experiment::SuggestPipeline'
},
......
......@@ -14,6 +14,7 @@ module Quality
],
unit: %w[
bin
channels
config
db
dependencies
......
......@@ -1701,7 +1701,7 @@ msgstr ""
msgid "AlertManagement|Display alerts from all your monitoring tools directly within GitLab. Streamline the investigation of your alerts and the escalation of alerts to incidents."
msgstr ""
msgid "AlertManagement|End Time"
msgid "AlertManagement|End time"
msgstr ""
msgid "AlertManagement|Events"
......@@ -1719,12 +1719,15 @@ msgstr ""
msgid "AlertManagement|Severity"
msgstr ""
msgid "AlertManagement|Start Time"
msgid "AlertManagement|Start time"
msgstr ""
msgid "AlertManagement|Status"
msgstr ""
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
......@@ -20174,9 +20177,6 @@ msgstr ""
msgid "Support page URL"
msgstr ""
msgid "Surface alerts in GitLab"
msgstr ""
msgid "Switch branch/tag"
msgstr ""
......
......@@ -33,6 +33,9 @@ if [ -f config/database_geo.yml ]; then
sed -i 's/username: git/username: postgres/g' config/database_geo.yml
fi
cp config/cable.yml.example config/cable.yml
sed -i 's|url:.*$|url: redis://redis:6379|g' config/cable.yml
cp config/resque.yml.example config/resque.yml
sed -i 's|url:.*$|url: redis://redis:6379|g' config/resque.yml
......
# frozen_string_literal: true
require 'spec_helper'
describe ApplicationCable::Connection, :clean_gitlab_redis_shared_state do
let(:session_id) { Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d') }
before do
Gitlab::Redis::SharedState.with do |redis|
redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
end
cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
end
context 'when user is logged in' do
let(:user) { create(:user) }
let(:session_hash) { { 'warden.user.user.key' => [[user.id], user.encrypted_password[0, 29]] } }
it 'sets current_user' do
connect
expect(connection.current_user).to eq(user)
end
context 'with a stale password' do
let(:partial_password_hash) { build(:user, password: 'some_old_password').encrypted_password[0, 29] }
let(:session_hash) { { 'warden.user.user.key' => [[user.id], partial_password_hash] } }
it 'sets current_user to nil' do
connect
expect(connection.current_user).to be_nil
end
end
end
context 'when user is not logged in' do
let(:session_hash) { {} }
it 'sets current_user to nil' do
connect
expect(connection.current_user).to be_nil
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe IssuesChannel do
let_it_be(:issue) { create(:issue) }
it 'rejects when project path is invalid' do
subscribe(project_path: 'invalid_project_path', iid: issue.iid)
expect(subscription).to be_rejected
end
it 'rejects when iid is invalid' do
subscribe(project_path: issue.project.full_path, iid: non_existing_record_iid)
expect(subscription).to be_rejected
end
it 'rejects when the user does not have access' do
stub_connection current_user: nil
subscribe(project_path: issue.project.full_path, iid: issue.iid)
expect(subscription).to be_rejected
end
it 'subscribes to a stream when the user has access' do
stub_connection current_user: issue.author
subscribe(project_path: issue.project.full_path, iid: issue.iid)
expect(subscription).to be_confirmed
expect(subscription).to have_stream_for(issue)
end
end
......@@ -464,9 +464,9 @@ describe "Internal Project Access" do
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
it { is_expected.to be_denied_for(:reporter).of(project) }
it { is_expected.to be_denied_for(:guest).of(project) }
it { is_expected.to be_denied_for(:user) }
it { is_expected.to be_allowed_for(:reporter).of(project) }
it { is_expected.to be_allowed_for(:guest).of(project) }
it { is_expected.to be_allowed_for(:user) }
it { is_expected.to be_denied_for(:external) }
it { is_expected.to be_denied_for(:visitor) }
end
......
......@@ -499,7 +499,7 @@ describe "Private Project Access" do
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
it { is_expected.to be_denied_for(:reporter).of(project) }
it { is_expected.to be_allowed_for(:reporter).of(project) }
it { is_expected.to be_denied_for(:guest).of(project) }
it { is_expected.to be_denied_for(:user) }
it { is_expected.to be_denied_for(:external) }
......
......@@ -278,11 +278,11 @@ describe "Public Project Access" do
it { is_expected.to be_allowed_for(:owner).of(project) }
it { is_expected.to be_allowed_for(:maintainer).of(project) }
it { is_expected.to be_allowed_for(:developer).of(project) }
it { is_expected.to be_denied_for(:reporter).of(project) }
it { is_expected.to be_denied_for(:guest).of(project) }
it { is_expected.to be_denied_for(:user) }
it { is_expected.to be_denied_for(:external) }
it { is_expected.to be_denied_for(:visitor) }
it { is_expected.to be_allowed_for(:reporter).of(project) }
it { is_expected.to be_allowed_for(:guest).of(project) }
it { is_expected.to be_allowed_for(:user) }
it { is_expected.to be_allowed_for(:external) }
it { is_expected.to be_allowed_for(:visitor) }
end
describe "GET /:project_path/-/environments" do
......
......@@ -470,8 +470,8 @@ end
describe 'With experimental flow' do
before do
stub_experiment(signup_flow: true, paid_signup_flow: false)
stub_experiment_for_user(signup_flow: true, paid_signup_flow: false)
stub_experiment(signup_flow: true)
stub_experiment_for_user(signup_flow: true)
end
it_behaves_like 'Signup'
......
import { mount } from '@vue/test-utils';
import { GlEmptyState, GlTable, GlAlert, GlLoadingIcon } from '@gitlab/ui';
import stubChildren from 'helpers/stub_children';
import AlertManagementList from '~/alert_management/components/alert_management_list.vue';
import mockAlerts from '../mocks/alerts.json';
describe('AlertManagementList', () => {
let wrapper;
const findAlertsTable = () => wrapper.find(GlTable);
const findAlerts = () => wrapper.findAll('table tbody tr');
const findAlert = () => wrapper.find(GlAlert);
const findLoader = () => wrapper.find(GlLoadingIcon);
function mountComponent({
stubs = {},
props = {
alertManagementEnabled: false,
userCanEnableAlertManagement: false,
......@@ -21,7 +22,7 @@ describe('AlertManagementList', () => {
} = {}) {
wrapper = mount(AlertManagementList, {
propsData: {
indexPath: '/path',
projectPath: 'gitlab-org/gitlab',
enableAlertManagementPath: '/link',
emptyAlertSvgPath: 'illustration/path',
...props,
......@@ -38,10 +39,6 @@ describe('AlertManagementList', () => {
},
},
},
stubs: {
...stubChildren(AlertManagementList),
...stubs,
},
});
}
......@@ -64,7 +61,6 @@ describe('AlertManagementList', () => {
describe('Alerts table', () => {
it('loading state', () => {
mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: null },
loading: true,
......@@ -75,7 +71,6 @@ describe('AlertManagementList', () => {
it('error state', () => {
mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: null, errored: true },
loading: false,
......@@ -88,7 +83,6 @@ describe('AlertManagementList', () => {
it('empty state', () => {
mountComponent({
stubs: { GlTable },
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: [], errored: false },
loading: false,
......@@ -98,5 +92,16 @@ describe('AlertManagementList', () => {
expect(findLoader().exists()).toBe(false);
expect(findAlert().props().variant).toBe('info');
});
it('has data state', () => {
mountComponent({
props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
data: { alerts: mockAlerts, errored: false },
loading: false,
});
expect(findLoader().exists()).toBe(false);
expect(findAlertsTable().exists()).toBe(true);
expect(findAlerts()).toHaveLength(mockAlerts.length);
});
});
});
[
{
"iid": "1527542",
"title": "SyntaxError: Invalid or unexpected token",
"severity": "Critical",
"eventCount": 7,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "triggered"
},
{
"iid": "1527542",
"title": "Some otherr alert Some otherr alert Some otherr alert Some otherr alert Some otherr alert Some otherr alert",
"severity": "Medium",
"eventCount": 1,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "acknowledged"
},
{
"iid": "1527542",
"title": "SyntaxError: Invalid or unexpected token",
"severity": "Low",
"eventCount": 4,
"startedAt": "2020-04-17T23:18:14.996Z",
"endedAt": "2020-04-17T23:18:14.996Z",
"status": "resolved"
}
]
......@@ -1041,6 +1041,36 @@ describe('DiffsStoreMutations', () => {
});
});
describe('SET_DIFF_FILE_VIEWER', () => {
it("should update the correct diffFile's viewer property", () => {
const state = {
diffFiles: [
{ file_path: 'SearchString', viewer: 'OLD VIEWER' },
{ file_path: 'OtherSearchString' },
{ file_path: 'SomeOtherString' },
],
};
mutations[types.SET_DIFF_FILE_VIEWER](state, {
filePath: 'SearchString',
viewer: 'NEW VIEWER',
});
expect(state.diffFiles[0].viewer).toEqual('NEW VIEWER');
expect(state.diffFiles[1].viewer).not.toBeDefined();
expect(state.diffFiles[2].viewer).not.toBeDefined();
mutations[types.SET_DIFF_FILE_VIEWER](state, {
filePath: 'OtherSearchString',
viewer: 'NEW VIEWER',
});
expect(state.diffFiles[0].viewer).toEqual('NEW VIEWER');
expect(state.diffFiles[1].viewer).toEqual('NEW VIEWER');
expect(state.diffFiles[2].viewer).not.toBeDefined();
});
});
describe('SET_SHOW_SUGGEST_POPOVER', () => {
it('sets showSuggestPopover to false', () => {
const state = { showSuggestPopover: true };
......
......@@ -11,10 +11,7 @@ describe Projects::AlertManagementHelper do
describe '#alert_management_data' do
let(:user_can_enable_alert_management) { false }
let(:setting_path) { project_settings_operations_path(project) }
let(:index_path) do
project_alert_management_index_path(project, format: :json)
end
let(:project_path) { project.full_path }
before do
allow(helper)
......@@ -26,9 +23,9 @@ describe Projects::AlertManagementHelper do
context 'without alert_managements_setting' do
it 'returns frontend configuration' do
expect(alert_management_data(current_user, project)).to eq(
'index-path' => index_path,
'project-path' => project_path,
'enable-alert-management-path' => setting_path,
"empty-alert-svg-path" => "/images/illustrations/alert-management-empty-state.svg",
'empty-alert-svg-path' => '/images/illustrations/alert-management-empty-state.svg',
'user-can-enable-alert-management' => 'false',
'alert-management-enabled' => 'true'
)
......
......@@ -21,7 +21,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a pattern' do
expect(subject.pattern(:unit))
.to eq("spec/{bin,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,replicators,routing,rubocop,serializers,services,sidekiq,support_specs,tasks,uploaders,validators,views,workers,elastic_integration}{,/**/}*_spec.rb")
.to eq("spec/{bin,channels,config,db,dependencies,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,models,policies,presenters,rack_servers,replicators,routing,rubocop,serializers,services,sidekiq,support_specs,tasks,uploaders,validators,views,workers,elastic_integration}{,/**/}*_spec.rb")
end
end
......@@ -89,7 +89,7 @@ RSpec.describe Quality::TestLevel do
context 'when level is unit' do
it 'returns a regexp' do
expect(subject.regexp(:unit))
.to eq(%r{spec/(bin|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|replicators|routing|rubocop|serializers|services|sidekiq|support_specs|tasks|uploaders|validators|views|workers|elastic_integration)})
.to eq(%r{spec/(bin|channels|config|db|dependencies|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|models|policies|presenters|rack_servers|replicators|routing|rubocop|serializers|services|sidekiq|support_specs|tasks|uploaders|validators|views|workers|elastic_integration)})
end
end
......
......@@ -842,5 +842,33 @@ describe Issues::UpdateService, :mailer do
let(:open_issuable) { issue }
let(:closed_issuable) { create(:closed_issue, project: project) }
end
context 'real-time updates' do
let(:update_params) { { assignee_ids: [user2.id] } }
context 'when broadcast_issue_updates is enabled' do
before do
stub_feature_flags(broadcast_issue_updates: true)
end
it 'broadcasts to the issues channel' do
expect(IssuesChannel).to receive(:broadcast_to).with(issue, event: 'updated')
update_issue(update_params)
end
end
context 'when broadcast_issue_updates is disabled' do
before do
stub_feature_flags(broadcast_issue_updates: false)
end
it 'does not broadcast to the issues channel' do
expect(IssuesChannel).not_to receive(:broadcast_to)
update_issue(update_params)
end
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册