Add latest changes from gitlab-org/gitlab@master
|
@ -0,0 +1,48 @@
|
|||
import { __ } from '~/locale';
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
inputEnabled: false,
|
||||
urlOrRequestId: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleInput() {
|
||||
this.inputEnabled = !this.inputEnabled;
|
||||
},
|
||||
addRequest() {
|
||||
this.$emit('add-request', this.urlOrRequestId);
|
||||
this.clearForm();
|
||||
},
|
||||
clearForm() {
|
||||
this.urlOrRequestId = '';
|
||||
this.toggleInput();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div id="peek-view-add-request" class="view">
|
||||
<form class="form-inline" @submit.prevent>
|
||||
<button
|
||||
class="btn-blank btn-link bold"
|
||||
type="button"
|
||||
:title="__(`Add request manually`)"
|
||||
@click="toggleInput"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<input
|
||||
v-if="inputEnabled"
|
||||
v-model="urlOrRequestId"
|
||||
type="text"
|
||||
:placeholder="__(`URL or request ID`)"
|
||||
class="form-control form-control-sm d-inline-block ml-1"
|
||||
@keyup.enter="addRequest"
|
||||
@keyup.esc="clearForm"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
|
@ -1,12 +1,14 @@
|
|||
<script>
|
||||
import { glEmojiTag } from '~/emoji';
|
||||
|
||||
import AddRequest from './add_request.vue';
|
||||
import DetailedMetric from './detailed_metric.vue';
|
||||
import RequestSelector from './request_selector.vue';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddRequest,
|
||||
DetailedMetric,
|
||||
RequestSelector,
|
||||
},
|
||||
|
@ -118,6 +120,7 @@ export default {
|
|||
>
|
||||
<a :href="currentRequest.details.tracing.tracing_url">{{ s__('PerformanceBar|trace') }}</a>
|
||||
</div>
|
||||
<add-request v-on="$listeners" />
|
||||
<request-selector
|
||||
v-if="currentRequest"
|
||||
:current-request="currentRequest"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
|
||||
import PerformanceBarService from './services/performance_bar_service';
|
||||
import PerformanceBarStore from './stores/performance_bar_store';
|
||||
|
||||
|
@ -32,6 +34,15 @@ export default ({ container }) =>
|
|||
PerformanceBarService.removeInterceptor(this.interceptor);
|
||||
},
|
||||
methods: {
|
||||
addRequestManually(urlOrRequestId) {
|
||||
if (urlOrRequestId.startsWith('https://') || urlOrRequestId.startsWith('http://')) {
|
||||
// We don't need to do anything with the response, we just
|
||||
// want to trace the request.
|
||||
axios.get(urlOrRequestId);
|
||||
} else {
|
||||
this.loadRequestDetails(urlOrRequestId, urlOrRequestId);
|
||||
}
|
||||
},
|
||||
loadRequestDetails(requestId, requestUrl) {
|
||||
if (!this.store.canTrackRequest(requestUrl)) {
|
||||
return;
|
||||
|
@ -58,6 +69,9 @@ export default ({ container }) =>
|
|||
peekUrl: this.peekUrl,
|
||||
profileUrl: this.profileUrl,
|
||||
},
|
||||
on: {
|
||||
'add-request': this.addRequestManually,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@import 'framework/variables_overrides';
|
||||
@import 'framework/mixins';
|
||||
|
||||
@import '@gitlab/ui/scss/gitlab_ui';
|
||||
@import '@gitlab/ui/src/scss/gitlab_ui';
|
||||
|
||||
@import 'bootstrap_migration';
|
||||
@import 'framework/layout';
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
width: 200px;
|
||||
}
|
||||
|
||||
input {
|
||||
color: $gl-gray-400;
|
||||
width: $input-short-width - 60px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
display: none;
|
||||
}
|
||||
|
@ -25,7 +30,8 @@
|
|||
&.production {
|
||||
background-color: $perf-bar-production;
|
||||
|
||||
select {
|
||||
select,
|
||||
input {
|
||||
background: $perf-bar-production;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +39,8 @@
|
|||
&.staging {
|
||||
background-color: $perf-bar-staging;
|
||||
|
||||
select {
|
||||
select,
|
||||
input {
|
||||
background: $perf-bar-staging;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +48,8 @@
|
|||
&.development {
|
||||
background-color: $perf-bar-development;
|
||||
|
||||
select {
|
||||
select,
|
||||
input {
|
||||
background: $perf-bar-development;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ class ApplicationController < ActionController::Base
|
|||
include EnforcesTwoFactorAuthentication
|
||||
include WithPerformanceBar
|
||||
include SessionlessAuthentication
|
||||
include SessionsHelper
|
||||
include ConfirmEmailWarning
|
||||
include Gitlab::Tracking::ControllerConcern
|
||||
include Gitlab::Experimentation::ControllerConcern
|
||||
|
@ -35,7 +36,7 @@ class ApplicationController < ActionController::Base
|
|||
around_action :set_session_storage
|
||||
|
||||
after_action :set_page_title_header, if: :json_request?
|
||||
after_action :limit_unauthenticated_session_times
|
||||
after_action :limit_session_time, if: -> { !current_user }
|
||||
|
||||
protect_from_forgery with: :exception, prepend: true
|
||||
|
||||
|
@ -101,24 +102,6 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
# By default, all sessions are given the same expiration time configured in
|
||||
# the session store (e.g. 1 week). However, unauthenticated users can
|
||||
# generate a lot of sessions, primarily for CSRF verification. It makes
|
||||
# sense to reduce the TTL for unauthenticated to something much lower than
|
||||
# the default (e.g. 1 hour) to limit Redis memory. In addition, Rails
|
||||
# creates a new session after login, so the short TTL doesn't even need to
|
||||
# be extended.
|
||||
def limit_unauthenticated_session_times
|
||||
return if current_user
|
||||
|
||||
# Rack sets this header, but not all tests may have it: https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L251-L259
|
||||
return unless request.env['rack.session.options']
|
||||
|
||||
# This works because Rack uses these options every time a request is handled:
|
||||
# https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
|
||||
request.env['rack.session.options'][:expire_after] = Settings.gitlab['unauthenticated_session_expire_delay']
|
||||
end
|
||||
|
||||
def render(*args)
|
||||
super.tap do
|
||||
# Set a header for custom error pages to prevent them from being intercepted by gitlab-workhorse
|
||||
|
|
|
@ -16,7 +16,7 @@ module Groups
|
|||
|
||||
render json: ContainerRepositoriesSerializer
|
||||
.new(current_user: current_user)
|
||||
.represent(@images)
|
||||
.represent_read_only(@images)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,4 +4,20 @@ module SessionsHelper
|
|||
def unconfirmed_email?
|
||||
flash[:alert] == t(:unconfirmed, scope: [:devise, :failure])
|
||||
end
|
||||
|
||||
# By default, all sessions are given the same expiration time configured in
|
||||
# the session store (e.g. 1 week). However, unauthenticated users can
|
||||
# generate a lot of sessions, primarily for CSRF verification. It makes
|
||||
# sense to reduce the TTL for unauthenticated to something much lower than
|
||||
# the default (e.g. 1 hour) to limit Redis memory. In addition, Rails
|
||||
# creates a new session after login, so the short TTL doesn't even need to
|
||||
# be extended.
|
||||
def limit_session_time
|
||||
# Rack sets this header, but not all tests may have it: https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L251-L259
|
||||
return unless request.env['rack.session.options']
|
||||
|
||||
# This works because Rack uses these options every time a request is handled:
|
||||
# https://github.com/rack/rack/blob/fdcd03a3c5a1c51d1f96fc97f9dfa1a9deac0c77/lib/rack/session/abstract/id.rb#L342
|
||||
request.env['rack.session.options'][:expire_after] = Settings.gitlab['unauthenticated_session_expire_delay']
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ class ContainerRepository < ApplicationRecord
|
|||
delegate :client, to: :registry
|
||||
|
||||
scope :ordered, -> { order(:name) }
|
||||
scope :with_api_entity_associations, -> { preload(:project) }
|
||||
scope :with_api_entity_associations, -> { preload(project: [:route, { namespace: :route }]) }
|
||||
|
||||
# rubocop: disable CodeReuse/ServiceClass
|
||||
def registry
|
||||
|
|
|
@ -2,4 +2,8 @@
|
|||
|
||||
class ContainerRepositoriesSerializer < BaseSerializer
|
||||
entity ContainerRepositoryEntity
|
||||
|
||||
def represent_read_only(resource)
|
||||
represent(resource, except: [:destroy_path])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow adding requests to performance bar manually
|
||||
merge_request: 18464
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix N+1 for group container repositories view
|
||||
merge_request: 18979
|
||||
author:
|
||||
type: performance
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Set shorter TTL for all unauthenticated requests
|
||||
merge_request: 19064
|
||||
author:
|
||||
type: fixed
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 70 KiB |
|
@ -8,14 +8,17 @@ activated, it looks as follows:
|
|||
It allows you to see (from left to right):
|
||||
|
||||
- the current host serving the page
|
||||
- time taken and number of DB queries, click through for details of these queries
|
||||
- time taken and number of DB queries; click through for details of these queries
|
||||
![SQL profiling using the Performance Bar](img/performance_bar_sql_queries.png)
|
||||
- time taken and number of [Gitaly] calls, click through for details of these calls
|
||||
- time taken and number of [Gitaly] calls; click through for details of these calls
|
||||
![Gitaly profiling using the Performance Bar](img/performance_bar_gitaly_calls.png)
|
||||
- time taken and number of [Rugged] calls, click through for details of these calls
|
||||
- time taken and number of [Rugged] calls; click through for details of these calls
|
||||
![Rugged profiling using the Performance Bar](img/performance_bar_rugged_calls.png)
|
||||
- time taken and number of Redis calls, click through for details of these calls
|
||||
- time taken and number of Redis calls; click through for details of these calls
|
||||
![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png)
|
||||
- a link to add a request's details to the performance bar; the request can be
|
||||
added by its full URL (authenticated as the current user), or by the value of
|
||||
its `X-Request-Id` header
|
||||
|
||||
On the far right is a request selector that allows you to view the same metrics
|
||||
(excluding the page timing and line profiler) for any requests made while the
|
||||
|
|
|
@ -25,6 +25,7 @@ See the documentation below for details on how to configure these services.
|
|||
- [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents.
|
||||
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users
|
||||
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
|
||||
- [Sentry](../user/project/operations/error_tracking.md#sentry-error-tracking) Enable issue linking from Sentry and view Sentry crash reports in GitLab
|
||||
- [Trello](trello_power_up.md) Integrate Trello with GitLab
|
||||
|
||||
> GitLab Enterprise Edition contains [advanced Jenkins support](jenkins.md).
|
||||
|
|
0
doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.png
Executable file → Normal file
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 138 KiB |
0
doc/user/project/img/code_owners_approval_protected_branch_v12_4.png
Executable file → Normal file
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
0
doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.png
Executable file → Normal file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -6,7 +6,7 @@ Error tracking allows developers to easily discover and view the errors that the
|
|||
|
||||
## Sentry error tracking
|
||||
|
||||
[Sentry](https://sentry.io/) is an open source error tracking system. GitLab allows administrators to connect Sentry to GitLab, to allow users to view a list of Sentry errors in GitLab itself.
|
||||
[Sentry](https://sentry.io/) is an open source error tracking system. GitLab allows administrators to connect Sentry to GitLab, to allow users to view a list of Sentry errors in GitLab.
|
||||
|
||||
### Deploying Sentry
|
||||
|
||||
|
@ -31,6 +31,10 @@ GitLab provides an easy way to connect Sentry to your project:
|
|||
1. Click **Save changes** for the changes to take effect.
|
||||
1. You can now visit **Operations > Error Tracking** in your project's sidebar to [view a list](#error-tracking-list) of Sentry errors.
|
||||
|
||||
### Enabling Gitlab issues links
|
||||
|
||||
You may also want to enable Sentry's GitLab integration by following the steps in the [Sentry documentation](https://docs.sentry.io/workflow/integrations/global-integrations/#gitlab)
|
||||
|
||||
## Error Tracking List
|
||||
|
||||
NOTE: **Note:**
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
module Gitlab
|
||||
class DeviseFailure < Devise::FailureApp
|
||||
include ::SessionsHelper
|
||||
|
||||
# If the request format is not known, send a redirect instead of a 401
|
||||
# response, since this is the outcome we're most likely to want
|
||||
def http_auth?
|
||||
|
@ -9,5 +11,11 @@ module Gitlab
|
|||
|
||||
request_format && super
|
||||
end
|
||||
|
||||
def respond
|
||||
limit_session_time
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -988,6 +988,9 @@ msgstr ""
|
|||
msgid "Add reaction"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add request manually"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add to Slack"
|
||||
msgstr ""
|
||||
|
||||
|
@ -17629,6 +17632,9 @@ msgstr ""
|
|||
msgid "URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...)."
|
||||
msgstr ""
|
||||
|
||||
msgid "URL or request ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unable to apply suggestions to a deleted line."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
"@babel/plugin-syntax-import-meta": "^7.2.0",
|
||||
"@babel/preset-env": "^7.6.2",
|
||||
"@gitlab/svgs": "^1.79.0",
|
||||
"@gitlab/ui": "6.0.0",
|
||||
"@gitlab/ui": "7.0.0",
|
||||
"@gitlab/visual-review-tools": "1.0.3",
|
||||
"apollo-cache-inmemory": "^1.5.1",
|
||||
"apollo-client": "^2.5.1",
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'Session TTLs', :clean_gitlab_redis_shared_state do
|
||||
it 'creates a session with a short TTL when login fails' do
|
||||
visit new_user_session_path
|
||||
# The session key only gets created after a post
|
||||
fill_in 'user_login', with: 'non-existant@gitlab.org'
|
||||
fill_in 'user_password', with: '12345678'
|
||||
click_button 'Sign in'
|
||||
|
||||
expect(page).to have_content('Invalid Login or password')
|
||||
|
||||
expect_single_session_with_expiration(Settings.gitlab['unauthenticated_session_expire_delay'])
|
||||
end
|
||||
|
||||
it 'increases the TTL when the login succeeds' do
|
||||
user = create(:user)
|
||||
gitlab_sign_in(user)
|
||||
|
||||
expect(page).to have_content(user.name)
|
||||
|
||||
expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
|
||||
end
|
||||
|
||||
def expect_single_session_with_expiration(expiration)
|
||||
session_keys = get_session_keys
|
||||
|
||||
expect(session_keys.size).to eq(1)
|
||||
expect(get_ttl(session_keys.first)).to eq expiration
|
||||
end
|
||||
|
||||
def get_session_keys
|
||||
Gitlab::Redis::SharedState.with { |redis| redis.scan_each(match: 'session:gitlab:*').to_a }
|
||||
end
|
||||
|
||||
def get_ttl(key)
|
||||
Gitlab::Redis::SharedState.with { |redis| redis.ttl(key) }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,62 @@
|
|||
import AddRequest from '~/performance_bar/components/add_request.vue';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
|
||||
describe('add request form', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallowMount(AddRequest);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
it('hides the input on load', () => {
|
||||
expect(wrapper.find('input').exists()).toBe(false);
|
||||
});
|
||||
|
||||
describe('when clicking the button', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('button').trigger('click');
|
||||
});
|
||||
|
||||
it('shows the form', () => {
|
||||
expect(wrapper.find('input').exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('when pressing escape', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('input').trigger('keyup.esc');
|
||||
});
|
||||
|
||||
it('hides the input', () => {
|
||||
expect(wrapper.find('input').exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when submitting the form', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('input').setValue('http://gitlab.example.com/users/root/calendar.json');
|
||||
wrapper.find('input').trigger('keyup.enter');
|
||||
});
|
||||
|
||||
it('emits an event to add the request', () => {
|
||||
expect(wrapper.emitted()['add-request']).toBeTruthy();
|
||||
expect(wrapper.emitted()['add-request'][0]).toEqual([
|
||||
'http://gitlab.example.com/users/root/calendar.json',
|
||||
]);
|
||||
});
|
||||
|
||||
it('hides the input', () => {
|
||||
expect(wrapper.find('input').exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('clears the value for next time', () => {
|
||||
wrapper.find('button').trigger('click');
|
||||
|
||||
expect(wrapper.find('input').text()).toEqual('');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -70,7 +70,8 @@ describe('MergeRequest', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('shows an error notification when tasklist update failed', done => {
|
||||
// eslint-disable-next-line jasmine/no-disabled-tests
|
||||
xit('shows an error notification when tasklist update failed', done => {
|
||||
mock
|
||||
.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
|
||||
.reply(409, {});
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::DeviseFailure do
|
||||
let(:env) do
|
||||
{
|
||||
'REQUEST_URI' => 'http://test.host/',
|
||||
'HTTP_HOST' => 'test.host',
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'warden.options' => { scope: :user },
|
||||
'rack.session' => {},
|
||||
'rack.session.options' => {},
|
||||
'rack.input' => "",
|
||||
'warden' => OpenStruct.new(message: nil)
|
||||
}
|
||||
end
|
||||
|
||||
let(:response) { described_class.call(env).to_a }
|
||||
let(:request) { ActionDispatch::Request.new(env) }
|
||||
|
||||
context 'When redirecting' do
|
||||
it 'sets the expire_after key' do
|
||||
response
|
||||
|
||||
expect(env['rack.session.options']).to have_key(:expire_after)
|
||||
end
|
||||
|
||||
it 'returns to the default redirect location' do
|
||||
expect(response.first).to eq(302)
|
||||
expect(request.flash[:alert]).to eq('You need to sign in or sign up before continuing.')
|
||||
expect(response.second['Location']).to eq('http://test.host/users/sign_in')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ApplicationSetting::TermPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe BasePolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Ci::BuildPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Ci::PipelinePolicy, :models do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Ci::PipelineSchedulePolicy, :models do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Ci::TriggerPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Clusters::ClusterPolicy, :models do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe DeployKeyPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe DeployTokenPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe EnvironmentPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe GlobalPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe GroupPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe IssuablePolicy, models: true do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe IssuePolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe MergeRequestPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe NamespacePolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe NotePolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
# Snippet visibility scenarios are included in more details in spec/support/snippet_visibility.rb
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProjectPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
# Snippet visibility scenarios are included in more details in spec/support/snippet_visibility.rb
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ProtectedBranchPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe ResourceLabelEventPolicy do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe UserPolicy do
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Groups::Registry::RepositoriesController do
|
||||
let_it_be(:group, reload: true) { create(:group) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
stub_container_registry_config(enabled: true)
|
||||
|
||||
group.add_reporter(user)
|
||||
login_as(user)
|
||||
end
|
||||
|
||||
describe 'GET groups/:group_id/-/container_registries.json' do
|
||||
it 'avoids N+1 queries' do
|
||||
project = create(:project, group: group)
|
||||
create(:container_repository, project: project)
|
||||
endpoint = group_container_registries_path(group, format: :json)
|
||||
|
||||
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { get(endpoint) }.count
|
||||
|
||||
create_list(:project, 2, group: group).each do |project|
|
||||
create_list(:container_repository, 2, project: project)
|
||||
end
|
||||
|
||||
expect { get(endpoint) }.not_to exceed_all_query_limit(control_count)
|
||||
|
||||
# sanity check that response is 200
|
||||
expect(response).to have_http_status(200)
|
||||
repositories = json_response
|
||||
expect(repositories.count).to eq(5)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -995,10 +995,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.79.0.tgz#7e79666118d6adc0247bdb3b3b6b2b299aa5a439"
|
||||
integrity sha512-0pTUviQqwyaKBOB6OL7Mmr2dQn/dGB03XslBMtL9lFZz1baB7d6xf+zxFU0GBAJUJan397IbBddE1jjUAQT8Fw==
|
||||
|
||||
"@gitlab/ui@6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-6.0.0.tgz#1d347fca1752732226f9b61b9fcbd8b60982b7cf"
|
||||
integrity sha512-d37M+4MJen2dLp/svPDBcPVYZi4mgl5Gj01SPM7TeqtBl6gnps9KSjRiYd4P0FBPTbt3QQ8k2qkQ8uTi2q/o3w==
|
||||
"@gitlab/ui@7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-7.0.0.tgz#74ca106856a47e7793df0b7448cbf2903634709c"
|
||||
integrity sha512-uiRV2VuGpWcCpj+d4M6VA8ItyLkTxfzGnaNbyX8UcswInAKjMMDO7KspF9DWlFDJVH5qzDguOSgons9NQJy53g==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.2.1"
|
||||
|
|