summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/performance_bar/components/add_request.vue48
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue3
-rw-r--r--app/assets/javascripts/performance_bar/index.js14
-rw-r--r--app/assets/stylesheets/framework.scss2
-rw-r--r--app/assets/stylesheets/performance_bar.scss14
-rw-r--r--app/controllers/application_controller.rb21
-rw-r--r--app/controllers/groups/registry/repositories_controller.rb2
-rw-r--r--app/helpers/sessions_helper.rb16
-rw-r--r--app/models/container_repository.rb2
-rw-r--r--app/serializers/container_repositories_serializer.rb4
-rw-r--r--changelogs/unreleased/allow-adding-requests-to-performance-bar-manually.yml5
-rw-r--r--changelogs/unreleased/fix_group_container_repositories_n_1.yml5
-rw-r--r--changelogs/unreleased/sh-ensure-short-ttl-sessions.yml5
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar.pngbin33642 -> 71317 bytes
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md11
-rw-r--r--doc/integration/README.md1
-rw-r--r--[-rwxr-xr-x]doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.pngbin141341 -> 141341 bytes
-rw-r--r--[-rwxr-xr-x]doc/user/project/img/code_owners_approval_protected_branch_v12_4.pngbin16195 -> 16195 bytes
-rw-r--r--[-rwxr-xr-x]doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.pngbin26902 -> 26902 bytes
-rw-r--r--doc/user/project/operations/error_tracking.md6
-rw-r--r--lib/gitlab/devise_failure.rb8
-rw-r--r--locale/gitlab.pot6
-rw-r--r--package.json2
-rw-r--r--spec/features/users/anonymous_sessions_spec.rb41
-rw-r--r--spec/frontend/performance_bar/components/add_request_spec.js62
-rw-r--r--spec/javascripts/merge_request_spec.js3
-rw-r--r--spec/lib/gitlab/devise_failure_spec.rb35
-rw-r--r--spec/policies/application_setting/term_policy_spec.rb2
-rw-r--r--spec/policies/base_policy_spec.rb2
-rw-r--r--spec/policies/ci/build_policy_spec.rb2
-rw-r--r--spec/policies/ci/pipeline_policy_spec.rb2
-rw-r--r--spec/policies/ci/pipeline_schedule_policy_spec.rb2
-rw-r--r--spec/policies/ci/trigger_policy_spec.rb2
-rw-r--r--spec/policies/clusters/cluster_policy_spec.rb2
-rw-r--r--spec/policies/deploy_key_policy_spec.rb2
-rw-r--r--spec/policies/deploy_token_policy_spec.rb2
-rw-r--r--spec/policies/environment_policy_spec.rb2
-rw-r--r--spec/policies/global_policy_spec.rb2
-rw-r--r--spec/policies/group_policy_spec.rb2
-rw-r--r--spec/policies/issuable_policy_spec.rb2
-rw-r--r--spec/policies/issue_policy_spec.rb2
-rw-r--r--spec/policies/merge_request_policy_spec.rb2
-rw-r--r--spec/policies/namespace_policy_spec.rb2
-rw-r--r--spec/policies/note_policy_spec.rb2
-rw-r--r--spec/policies/personal_snippet_policy_spec.rb2
-rw-r--r--spec/policies/project_policy_spec.rb2
-rw-r--r--spec/policies/project_snippet_policy_spec.rb2
-rw-r--r--spec/policies/protected_branch_policy_spec.rb2
-rw-r--r--spec/policies/resource_label_event_policy_spec.rb2
-rw-r--r--spec/policies/user_policy_spec.rb2
-rw-r--r--spec/requests/groups/registry/repositories_controller_spec.rb36
-rw-r--r--yarn.lock8
52 files changed, 370 insertions, 36 deletions
diff --git a/app/assets/javascripts/performance_bar/components/add_request.vue b/app/assets/javascripts/performance_bar/components/add_request.vue
new file mode 100644
index 00000000000..54bca8a1b67
--- /dev/null
+++ b/app/assets/javascripts/performance_bar/components/add_request.vue
@@ -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>
diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
index 3b07eba02b7..8ce653bf1fb 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -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"
diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js
index 1ae9487f391..735c9d804ee 100644
--- a/app/assets/javascripts/performance_bar/index.js
+++ b/app/assets/javascripts/performance_bar/index.js
@@ -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,
+ },
});
},
});
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 56a88ca44db..249e9a24b17 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -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';
diff --git a/app/assets/stylesheets/performance_bar.scss b/app/assets/stylesheets/performance_bar.scss
index ad7d87f0bf6..87e650c7659 100644
--- a/app/assets/stylesheets/performance_bar.scss
+++ b/app/assets/stylesheets/performance_bar.scss
@@ -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;
}
}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1443a71f6b1..c600b45c8b7 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -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
diff --git a/app/controllers/groups/registry/repositories_controller.rb b/app/controllers/groups/registry/repositories_controller.rb
index e09a9e6eb21..cfddd8a3ba9 100644
--- a/app/controllers/groups/registry/repositories_controller.rb
+++ b/app/controllers/groups/registry/repositories_controller.rb
@@ -16,7 +16,7 @@ module Groups
render json: ContainerRepositoriesSerializer
.new(current_user: current_user)
- .represent(@images)
+ .represent_read_only(@images)
end
end
end
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index af98a611b8b..ef737b25bc7 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -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
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index 27bb76835c7..7a3a79cead0 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -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
diff --git a/app/serializers/container_repositories_serializer.rb b/app/serializers/container_repositories_serializer.rb
index e1ce3c7b3ae..bc35a67ff24 100644
--- a/app/serializers/container_repositories_serializer.rb
+++ b/app/serializers/container_repositories_serializer.rb
@@ -2,4 +2,8 @@
class ContainerRepositoriesSerializer < BaseSerializer
entity ContainerRepositoryEntity
+
+ def represent_read_only(resource)
+ represent(resource, except: [:destroy_path])
+ end
end
diff --git a/changelogs/unreleased/allow-adding-requests-to-performance-bar-manually.yml b/changelogs/unreleased/allow-adding-requests-to-performance-bar-manually.yml
new file mode 100644
index 00000000000..0ec1167d9eb
--- /dev/null
+++ b/changelogs/unreleased/allow-adding-requests-to-performance-bar-manually.yml
@@ -0,0 +1,5 @@
+---
+title: Allow adding requests to performance bar manually
+merge_request: 18464
+author:
+type: other
diff --git a/changelogs/unreleased/fix_group_container_repositories_n_1.yml b/changelogs/unreleased/fix_group_container_repositories_n_1.yml
new file mode 100644
index 00000000000..1ec2148b274
--- /dev/null
+++ b/changelogs/unreleased/fix_group_container_repositories_n_1.yml
@@ -0,0 +1,5 @@
+---
+title: Fix N+1 for group container repositories view
+merge_request: 18979
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-ensure-short-ttl-sessions.yml b/changelogs/unreleased/sh-ensure-short-ttl-sessions.yml
new file mode 100644
index 00000000000..86c8fb74e21
--- /dev/null
+++ b/changelogs/unreleased/sh-ensure-short-ttl-sessions.yml
@@ -0,0 +1,5 @@
+---
+title: Set shorter TTL for all unauthenticated requests
+merge_request: 19064
+author:
+type: fixed
diff --git a/doc/administration/monitoring/performance/img/performance_bar.png b/doc/administration/monitoring/performance/img/performance_bar.png
index d1187fd879a..acad60f863e 100644
--- a/doc/administration/monitoring/performance/img/performance_bar.png
+++ b/doc/administration/monitoring/performance/img/performance_bar.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index 53c08e32cb2..a0b77c38205 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -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
diff --git a/doc/integration/README.md b/doc/integration/README.md
index 3a08303bf20..da00cc0ffa0 100644
--- a/doc/integration/README.md
+++ b/doc/integration/README.md
@@ -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).
diff --git a/doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.png b/doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.png
index f813b60dcd9..f813b60dcd9 100755..100644
--- a/doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.png
+++ b/doc/user/project/img/code_owners_approval_new_protected_branch_v12_4.png
Binary files differ
diff --git a/doc/user/project/img/code_owners_approval_protected_branch_v12_4.png b/doc/user/project/img/code_owners_approval_protected_branch_v12_4.png
index 59da6874d14..59da6874d14 100755..100644
--- a/doc/user/project/img/code_owners_approval_protected_branch_v12_4.png
+++ b/doc/user/project/img/code_owners_approval_protected_branch_v12_4.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.png b/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.png
index c704129685f..c704129685f 100755..100644
--- a/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.png
+++ b/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_4.png
Binary files differ
diff --git a/doc/user/project/operations/error_tracking.md b/doc/user/project/operations/error_tracking.md
index 1b319c5641c..f93c98f0218 100644
--- a/doc/user/project/operations/error_tracking.md
+++ b/doc/user/project/operations/error_tracking.md
@@ -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:**
diff --git a/lib/gitlab/devise_failure.rb b/lib/gitlab/devise_failure.rb
index 4d27b706e1e..59a7c4a6660 100644
--- a/lib/gitlab/devise_failure.rb
+++ b/lib/gitlab/devise_failure.rb
@@ -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
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 323efe2e6eb..5506b8ab805 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -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 ""
diff --git a/package.json b/package.json
index 0e14159a956..bf9eb69bdfb 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/spec/features/users/anonymous_sessions_spec.rb b/spec/features/users/anonymous_sessions_spec.rb
new file mode 100644
index 00000000000..e87ee39a3f4
--- /dev/null
+++ b/spec/features/users/anonymous_sessions_spec.rb
@@ -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
diff --git a/spec/frontend/performance_bar/components/add_request_spec.js b/spec/frontend/performance_bar/components/add_request_spec.js
new file mode 100644
index 00000000000..cef264f3915
--- /dev/null
+++ b/spec/frontend/performance_bar/components/add_request_spec.js
@@ -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('');
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
index 72d6e832aca..998637ef595 100644
--- a/spec/javascripts/merge_request_spec.js
+++ b/spec/javascripts/merge_request_spec.js
@@ -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, {});
diff --git a/spec/lib/gitlab/devise_failure_spec.rb b/spec/lib/gitlab/devise_failure_spec.rb
new file mode 100644
index 00000000000..eee05c7befd
--- /dev/null
+++ b/spec/lib/gitlab/devise_failure_spec.rb
@@ -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
diff --git a/spec/policies/application_setting/term_policy_spec.rb b/spec/policies/application_setting/term_policy_spec.rb
index 93b5ebf5f72..21690d4b457 100644
--- a/spec/policies/application_setting/term_policy_spec.rb
+++ b/spec/policies/application_setting/term_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ApplicationSetting::TermPolicy do
diff --git a/spec/policies/base_policy_spec.rb b/spec/policies/base_policy_spec.rb
index 09be831dcd5..9e59d35b1bb 100644
--- a/spec/policies/base_policy_spec.rb
+++ b/spec/policies/base_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BasePolicy do
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb
index 79a616899fa..333f4e560cf 100644
--- a/spec/policies/ci/build_policy_spec.rb
+++ b/spec/policies/ci/build_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Ci::BuildPolicy do
diff --git a/spec/policies/ci/pipeline_policy_spec.rb b/spec/policies/ci/pipeline_policy_spec.rb
index 126d44d1860..293fe1fc5b9 100644
--- a/spec/policies/ci/pipeline_policy_spec.rb
+++ b/spec/policies/ci/pipeline_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Ci::PipelinePolicy, :models do
diff --git a/spec/policies/ci/pipeline_schedule_policy_spec.rb b/spec/policies/ci/pipeline_schedule_policy_spec.rb
index 5a56e91cd69..700d7d1af0a 100644
--- a/spec/policies/ci/pipeline_schedule_policy_spec.rb
+++ b/spec/policies/ci/pipeline_schedule_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Ci::PipelineSchedulePolicy, :models do
diff --git a/spec/policies/ci/trigger_policy_spec.rb b/spec/policies/ci/trigger_policy_spec.rb
index e9a85890082..e936277a391 100644
--- a/spec/policies/ci/trigger_policy_spec.rb
+++ b/spec/policies/ci/trigger_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Ci::TriggerPolicy do
diff --git a/spec/policies/clusters/cluster_policy_spec.rb b/spec/policies/clusters/cluster_policy_spec.rb
index cc3dde154dc..55c3351a171 100644
--- a/spec/policies/clusters/cluster_policy_spec.rb
+++ b/spec/policies/clusters/cluster_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Clusters::ClusterPolicy, :models do
diff --git a/spec/policies/deploy_key_policy_spec.rb b/spec/policies/deploy_key_policy_spec.rb
index e7263d49613..aca93d8fe85 100644
--- a/spec/policies/deploy_key_policy_spec.rb
+++ b/spec/policies/deploy_key_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe DeployKeyPolicy do
diff --git a/spec/policies/deploy_token_policy_spec.rb b/spec/policies/deploy_token_policy_spec.rb
index cef5a4a22bc..43e23ee55ac 100644
--- a/spec/policies/deploy_token_policy_spec.rb
+++ b/spec/policies/deploy_token_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe DeployTokenPolicy do
diff --git a/spec/policies/environment_policy_spec.rb b/spec/policies/environment_policy_spec.rb
index 0442b032e89..3d0f250740c 100644
--- a/spec/policies/environment_policy_spec.rb
+++ b/spec/policies/environment_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe EnvironmentPolicy do
diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb
index 880f1bcbc05..c18cc245468 100644
--- a/spec/policies/global_policy_spec.rb
+++ b/spec/policies/global_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GlobalPolicy do
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 603e7e874c9..9634a591592 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GroupPolicy do
diff --git a/spec/policies/issuable_policy_spec.rb b/spec/policies/issuable_policy_spec.rb
index 6d34b0a8b4b..18e35308ecd 100644
--- a/spec/policies/issuable_policy_spec.rb
+++ b/spec/policies/issuable_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe IssuablePolicy, models: true do
diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb
index 25267d36ab8..89fcf3c10df 100644
--- a/spec/policies/issue_policy_spec.rb
+++ b/spec/policies/issue_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe IssuePolicy do
diff --git a/spec/policies/merge_request_policy_spec.rb b/spec/policies/merge_request_policy_spec.rb
index af4c9703eb4..287325e96df 100644
--- a/spec/policies/merge_request_policy_spec.rb
+++ b/spec/policies/merge_request_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MergeRequestPolicy do
diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb
index 216aaae70ee..ece0519112a 100644
--- a/spec/policies/namespace_policy_spec.rb
+++ b/spec/policies/namespace_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe NamespacePolicy do
diff --git a/spec/policies/note_policy_spec.rb b/spec/policies/note_policy_spec.rb
index d18ded8bce9..5aee66275d4 100644
--- a/spec/policies/note_policy_spec.rb
+++ b/spec/policies/note_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe NotePolicy do
diff --git a/spec/policies/personal_snippet_policy_spec.rb b/spec/policies/personal_snippet_policy_spec.rb
index 097000ceb6a..9a74a3d07f3 100644
--- a/spec/policies/personal_snippet_policy_spec.rb
+++ b/spec/policies/personal_snippet_policy_spec.rb
@@ -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
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index e61a064e82c..d0788452a20 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ProjectPolicy do
diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb
index 2e9ef1e89fd..3c68d33b1f3 100644
--- a/spec/policies/project_snippet_policy_spec.rb
+++ b/spec/policies/project_snippet_policy_spec.rb
@@ -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
diff --git a/spec/policies/protected_branch_policy_spec.rb b/spec/policies/protected_branch_policy_spec.rb
index 1587196754d..ea7fd093e38 100644
--- a/spec/policies/protected_branch_policy_spec.rb
+++ b/spec/policies/protected_branch_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ProtectedBranchPolicy do
diff --git a/spec/policies/resource_label_event_policy_spec.rb b/spec/policies/resource_label_event_policy_spec.rb
index 9206640ea00..799534d2b08 100644
--- a/spec/policies/resource_label_event_policy_spec.rb
+++ b/spec/policies/resource_label_event_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ResourceLabelEventPolicy do
diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb
index 7e0a1824200..9da9d2ce49b 100644
--- a/spec/policies/user_policy_spec.rb
+++ b/spec/policies/user_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe UserPolicy do
diff --git a/spec/requests/groups/registry/repositories_controller_spec.rb b/spec/requests/groups/registry/repositories_controller_spec.rb
new file mode 100644
index 00000000000..35fdeaab604
--- /dev/null
+++ b/spec/requests/groups/registry/repositories_controller_spec.rb
@@ -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
diff --git a/yarn.lock b/yarn.lock
index 9e2ed15d78c..54221ffc2ce 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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"