Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-04-01 15:07:45 +00:00
parent 1a0d6dbdc2
commit 1219a9dce9
140 changed files with 860 additions and 369 deletions

View File

@ -85,7 +85,7 @@ review-build-cng:
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
GITLAB_HELM_CHART_REF: "v2.6.8"
GITLAB_HELM_CHART_REF: "v3.2.2"
GITLAB_EDITION: "ce"
environment:
name: review/${CI_COMMIT_REF_NAME}

View File

@ -25,13 +25,6 @@ Please provide pros/cons and a weight estimate for each solution.
- [ ] All potential solutions are listed.
- [ ] A solution has been chosen for the first iteration: `PUT THE CHOSEN SOLUTION HERE`
## Who and when will the solution be implemented?
<!--
For history reason, please list the person that will implement the solution and
the planned milestone/date.
-->
## Verify that the solution has improved the situation
<!--

View File

@ -21,6 +21,8 @@ export default {
},
false,
),
goToTrackValue: 10,
trackEvent: 'click_button',
components: {
GlModal,
GlSprintf,
@ -43,12 +45,17 @@ export default {
},
data() {
return {
tracking: {
label: 'congratulate_first_pipeline',
property: this.humanAccess,
},
trackLabel: 'congratulate_first_pipeline',
};
},
computed: {
tracking() {
return {
label: this.trackLabel,
property: this.humanAccess,
};
},
},
mounted() {
this.track();
this.disableModalFromRenderingAgain();
@ -89,7 +96,17 @@ export default {
</template>
</gl-sprintf>
<template #modal-footer>
<a :href="goToPipelinesPath" class="btn btn-success">{{ __('Go to Pipelines') }}</a>
<a
ref="goto"
:href="goToPipelinesPath"
class="btn btn-success"
:data-track-property="humanAccess"
:data-track-value="$options.goToTrackValue"
:data-track-event="$options.trackEvent"
:data-track-label="trackLabel"
>
{{ __('Go to Pipelines') }}
</a>
</template>
</gl-modal>
</template>

View File

@ -9,8 +9,10 @@ const getSvgDom = memoize(() =>
axios
.get(gon.sprite_icons)
.then(({ data: svgs }) => new DOMParser().parseFromString(svgs, 'text/xml'))
.catch(() => {
.catch(e => {
getSvgDom.cache.clear();
throw e;
}),
);

View File

@ -0,0 +1,5 @@
import initStaticSiteEditor from '~/static_site_editor';
window.addEventListener('DOMContentLoaded', () => {
initStaticSiteEditor(document.querySelector('#static-site-editor'));
});

View File

@ -0,0 +1,3 @@
<template>
<div></div>
</template>

View File

@ -0,0 +1,20 @@
import Vue from 'vue';
import StaticSiteEditor from './components/static_site_editor.vue';
import createStore from './store';
const initStaticSiteEditor = el => {
const store = createStore();
return new Vue({
el,
store,
components: {
StaticSiteEditor,
},
render(createElement) {
return createElement('static-site-editor', StaticSiteEditor);
},
});
};
export default initStaticSiteEditor;

View File

@ -0,0 +1,13 @@
import Vuex from 'vuex';
import Vue from 'vue';
import createState from './state';
Vue.use(Vuex);
const createStore = ({ initialState } = {}) => {
return new Vuex.Store({
state: createState(initialState),
});
};
export default createStore;

View File

@ -0,0 +1,6 @@
const createState = (initialState = {}) => ({
content: '',
...initialState,
});
export default createState;

View File

@ -470,7 +470,6 @@ class Member < ApplicationRecord
# for a Member to be commited before attempting to update the highest role.
# rubocop: disable CodeReuse/ServiceClass
def update_highest_role
return unless Feature.enabled?(:highest_role_callback)
return unless user_id.present?
return unless previous_changes[:access_level].present?

View File

@ -237,6 +237,7 @@ class User < ApplicationRecord
end
end
end
after_commit :update_highest_role, on: [:create, :update]
after_initialize :set_projects_limit
@ -1844,6 +1845,21 @@ class User < ApplicationRecord
def no_recent_activity?
last_active_at.to_i <= MINIMUM_INACTIVE_DAYS.days.ago.to_i
end
# Triggers the service to schedule a Sidekiq job to update the highest role
# for a User
#
# The job will be called outside of a transaction in order to ensure the changes
# for a Member to be commited before attempting to update the highest role.
# rubocop: disable CodeReuse/ServiceClass
def update_highest_role
return unless (previous_changes.keys & %w(state user_type ghost)).any?
run_after_commit_or_now do
Members::UpdateHighestRoleService.new(id).execute
end
end
# rubocop: enable CodeReuse/ServiceClass
end
User.prepend_if_ee('EE::User')

View File

@ -4,7 +4,8 @@ module Members
class UpdateHighestRoleService < ::BaseService
include ExclusiveLeaseGuard
LEASE_TIMEOUT = 30.minutes.to_i
LEASE_TIMEOUT = 10.minutes.to_i
DELAY = 10.minutes
attr_reader :user_id
@ -14,7 +15,7 @@ module Members
def execute
try_obtain_lease do
UpdateHighestRoleWorker.perform_async(user_id)
UpdateHighestRoleWorker.perform_in(DELAY, user_id)
end
end

View File

@ -52,7 +52,7 @@ module Snippets
create_commit(snippet) if snippet.repository_exists?
end
rescue => e
snippet.errors.add(:repository, 'Error updating the snippet')
snippet.errors.add(:repository, e.message)
log_error(e.message)
false

View File

@ -2,7 +2,7 @@
module Users
class UpdateHighestMemberRoleService < BaseService
attr_reader :user, :identity_params
attr_reader :user
def initialize(user)
@user = user

View File

@ -11,9 +11,15 @@ class UpdateHighestRoleWorker
# rubocop: disable CodeReuse/ActiveRecord
def perform(user_id)
user = User.active.find_by(id: user_id)
user = User.find_by(id: user_id)
Users::UpdateHighestMemberRoleService.new(user).execute if user.present?
return unless user.present?
if user.active? && user.user_type.nil? && !user.internal?
Users::UpdateHighestMemberRoleService.new(user).execute
else
UserHighestRole.where(user_id: user_id).delete_all
end
end
# rubocop: enable CodeReuse/ActiveRecord
end

View File

@ -0,0 +1,5 @@
---
title: Show snippet error update to the user
merge_request: 28516
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: Populate user_highest_roles table
merge_request: 27127
author:
type: added

View File

@ -0,0 +1,5 @@
---
title: Update user's highest role to keep the users statistics up to date
merge_request: 28087
author:
type: added

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddMigratingUserHighestRolesTableIndexToUsers < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_for_migrating_user_highest_roles_table'
disable_ddl_transaction!
def up
add_concurrent_index :users,
:id,
where: "state = 'active' AND user_type IS NULL AND bot_type IS NULL AND ghost IS NOT TRUE",
name: INDEX_NAME
end
def down
remove_concurrent_index :users, :id, name: INDEX_NAME
end
end

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
class SchedulePopulateUserHighestRolesTable < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
BATCH_SIZE = 10_000
DELAY = 5.minutes.to_i
DOWNTIME = false
MIGRATION = 'PopulateUserHighestRolesTable'
disable_ddl_transaction!
class User < ActiveRecord::Base
include EachBatch
scope :active, -> {
where(state: 'active', user_type: nil, bot_type: nil)
.where('ghost IS NOT TRUE')
}
end
def up
# We currently have ~5_300_000 users with the state active on GitLab.com.
# This means it'll schedule ~530 jobs (10k Users each) with a 5 minutes gap,
# so this should take ~44 hours for all background migrations to complete.
User.active.each_batch(of: BATCH_SIZE) do |batch, index|
range = batch.pluck(Arel.sql('MIN(id)'), Arel.sql('MAX(id)')).first
delay = index * DELAY
migrate_in(delay.seconds, MIGRATION, [*range])
end
end
def down
# nothing
end
end

View File

@ -9066,6 +9066,8 @@ CREATE UNIQUE INDEX index_feature_gates_on_feature_key_and_key_and_value ON publ
CREATE UNIQUE INDEX index_features_on_key ON public.features USING btree (key);
CREATE INDEX index_for_migrating_user_highest_roles_table ON public.users USING btree (id) WHERE (((state)::text = 'active'::text) AND (user_type IS NULL) AND (bot_type IS NULL) AND (ghost IS NOT TRUE));
CREATE INDEX index_for_resource_group ON public.ci_builds USING btree (resource_group_id, id) WHERE (resource_group_id IS NOT NULL);
CREATE INDEX index_for_status_per_branch_per_project ON public.merge_trains USING btree (target_project_id, target_branch, status);
@ -12865,6 +12867,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200311084025
20200311093210
20200311094020
20200311130802
20200311141053
20200311141943
20200311154110
@ -12880,6 +12883,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200316111759
20200316162648
20200316173312
20200317110602
20200317142110
20200318140400
20200318152134

View File

@ -70,6 +70,13 @@ NOTE: **Note:** Set the limit to `0` to disable it.
GitLab ignores all incoming emails sent from auto-responders by looking for the `X-Autoreply`
header. Such emails don't create comments on issues or merge requests.
## Amount of data sent from Sentry via Error Tracking
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14926) in GitLab 12.6.
Sentry payloads sent to GitLab have a 1 MB maximum limit, both for security reasons
and to limit memory consumption.
## CI/CD limits
### Number of jobs in active pipelines

View File

@ -92,15 +92,6 @@ The following metrics are available:
| `failed_login_captcha_total` | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | |
| `successful_login_captcha_total` | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | |
| `auto_devops_pipelines_completed_total` | Counter | 12.7 | Counter of completed Auto DevOps pipelines, labeled by status | |
| `sidekiq_jobs_cpu_seconds` | Histogram | 12.4 | Seconds of cpu time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_completion_seconds` | Histogram | 12.2 | Seconds to complete Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_db_seconds` | Histogram | 12.9 | Seconds of DB time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_gitaly_seconds` | Histogram | 12.9 | Seconds of Gitaly time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_queue_duration_seconds` | Histogram | 12.5 | Duration in seconds that a Sidekiq job was queued before being executed | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_jobs_failed_total` | Counter | 12.2 | Sidekiq jobs failed | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_jobs_retried_total` | Counter | 12.2 | Sidekiq jobs retried | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_running_jobs` | Gauge | 12.2 | Number of Sidekiq jobs running | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_concurrency` | Gauge | 12.5 | Maximum number of Sidekiq jobs | |
## Metrics controlled by a feature flag
@ -120,6 +111,15 @@ configuration option in `gitlab.yml`. These metrics are served from the
| Metric | Type | Since | Description | Labels |
|:---------------------------------------------- |:------- |:----- |:----------- |:------ |
| `sidekiq_jobs_cpu_seconds` | Histogram | 12.4 | Seconds of cpu time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_completion_seconds` | Histogram | 12.2 | Seconds to complete Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_db_seconds` | Histogram | 12.9 | Seconds of DB time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_gitaly_seconds` | Histogram | 12.9 | Seconds of Gitaly time to run Sidekiq job | queue, boundary, external_dependencies, feature_category, job_status, urgency |
| `sidekiq_jobs_queue_duration_seconds` | Histogram | 12.5 | Duration in seconds that a Sidekiq job was queued before being executed | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_jobs_failed_total` | Counter | 12.2 | Sidekiq jobs failed | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_jobs_retried_total` | Counter | 12.2 | Sidekiq jobs retried | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_running_jobs` | Gauge | 12.2 | Number of Sidekiq jobs running | queue, boundary, external_dependencies, feature_category, urgency |
| `sidekiq_concurrency` | Gauge | 12.5 | Maximum number of Sidekiq jobs | |
| `geo_db_replication_lag_seconds` | Gauge | 10.2 | Database replication lag (seconds) | url |
| `geo_repositories` | Gauge | 10.2 | Total number of repositories available on primary | url |
| `geo_repositories_synced` | Gauge | 10.2 | Number of repositories synced on secondary | url |

View File

@ -78,6 +78,10 @@ FDOC=1 bin/rspec spec/[path]/[to]/[spec].rb
- Use `focus: true` to isolate parts of the specs you want to run.
- Use [`:aggregate_failures`](https://relishapp.com/rspec/rspec-core/docs/expectation-framework-integration/aggregating-failures) when there is more than one expectation in a test.
- For [empty test description blocks](https://github.com/rubocop-hq/rspec-style-guide#it-and-specify), use `specify` rather than `it do` if the test is self-explanatory.
- Use `non_existing_record_id`/`non_existing_record_iid`/`non_existing_record_access_level`
when you need an ID/IID/access level that doesn't actually exists. Using 123, 1234,
or even 999 is brittle as these IDs could actually exist in the database in the
context of a CI run.
### Coverage
@ -244,7 +248,11 @@ so we need to set some guidelines for their use going forward:
In some cases, there is no need to recreate the same object for tests
again for each example. For example, a project and a guest of that project
is needed to test issues on the same project, one project and user will do for the entire file.
This can be achieved by using
As much as possible, do not implement this using `before(:all)` or `before(:context)`. If you do,
you would need to manually clean up the data as those hooks run outside a database transaction.
Instead, this can be achieved by using
[`let_it_be`](https://test-prof.evilmartians.io/#/let_it_be) variables and the
[`before_all`](https://test-prof.evilmartians.io/#/before_all) hook
from the [`test-prof` gem](https://rubygems.org/gems/test-prof).

View File

@ -0,0 +1,56 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# This background migration creates records on user_highest_roles according to
# the given user IDs range. IDs will load users with a left outer joins to
# have a record for users without a Group or Project. One INSERT per ID is
# issued.
class PopulateUserHighestRolesTable
BATCH_SIZE = 100
# rubocop:disable Style/Documentation
class User < ActiveRecord::Base
self.table_name = 'users'
scope :active, -> {
where(state: 'active', user_type: nil, bot_type: nil)
.where('ghost IS NOT TRUE')
}
end
def perform(from_id, to_id)
(from_id..to_id).each_slice(BATCH_SIZE) do |ids|
execute(
<<-EOF
INSERT INTO user_highest_roles (updated_at, user_id, highest_access_level)
#{select_sql(from_id, to_id)}
ON CONFLICT (user_id) DO
UPDATE SET highest_access_level = EXCLUDED.highest_access_level
EOF
)
end
end
private
def select_sql(from_id, to_id)
User
.select('NOW() as updated_at, users.id, MAX(access_level) AS highest_access_level')
.joins('LEFT OUTER JOIN members ON members.user_id = users.id AND members.requested_at IS NULL')
.where(users: { id: active_user_ids(from_id, to_id) })
.group('users.id')
.to_sql
end
def active_user_ids(from_id, to_id)
User.active.where(users: { id: from_id..to_id }).pluck(:id)
end
def execute(sql)
@connection ||= ActiveRecord::Base.connection
@connection.execute(sql)
end
end
end
end

View File

@ -155,8 +155,6 @@ redis:
limits:
cpu: 200m
memory: 130M
redis-ha:
enabled: false
registry:
hpa:
minReplicas: 1

View File

@ -192,9 +192,9 @@ describe AutocompleteController do
end
it 'rejects non existent user ids' do
get(:users, params: { author_id: 99999 })
get(:users, params: { author_id: non_existing_record_id })
expect(json_response.collect { |u| u['id'] }).not_to include(99999)
expect(json_response.collect { |u| u['id'] }).not_to include(non_existing_record_id)
end
end

View File

@ -26,7 +26,7 @@ describe Boards::IssuesController do
context 'with invalid board id' do
it 'returns a not found 404 response' do
list_issues user: user, board: 999, list: list2
list_issues user: user, board: non_existing_record_id, list: list2
expect(response).to have_gitlab_http_status(:not_found)
end
@ -123,7 +123,7 @@ describe Boards::IssuesController do
context 'with invalid list id' do
it 'returns a not found 404 response' do
list_issues user: user, board: board, list: 999
list_issues user: user, board: board, list: non_existing_record_id
expect(response).to have_gitlab_http_status(:not_found)
end
@ -441,7 +441,7 @@ describe Boards::IssuesController do
context 'with invalid board id' do
it 'returns a not found 404 response' do
create_issue user: user, board: 999, list: list1, title: 'New issue'
create_issue user: user, board: non_existing_record_id, list: list1, title: 'New issue'
expect(response).to have_gitlab_http_status(:not_found)
end
@ -449,7 +449,7 @@ describe Boards::IssuesController do
context 'with invalid list id' do
it 'returns a not found 404 response' do
create_issue user: user, board: board, list: 999, title: 'New issue'
create_issue user: user, board: board, list: non_existing_record_id, title: 'New issue'
expect(response).to have_gitlab_http_status(:not_found)
end
@ -512,13 +512,13 @@ describe Boards::IssuesController do
end
it 'returns a not found 404 response for invalid board id' do
move user: user, board: 999, issue: issue, from_list_id: list1.id, to_list_id: list2.id
move user: user, board: non_existing_record_id, issue: issue, from_list_id: list1.id, to_list_id: list2.id
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns a not found 404 response for invalid issue id' do
move user: user, board: board, issue: double(id: 999), from_list_id: list1.id, to_list_id: list2.id
move user: user, board: board, issue: double(id: non_existing_record_id), from_list_id: list1.id, to_list_id: list2.id
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -154,7 +154,7 @@ describe Boards::ListsController do
context 'with invalid list id' do
it 'returns a not found 404 response' do
move user: user, board: board, list: 999, position: 1
move user: user, board: board, list: non_existing_record_id, position: 1
expect(response).to have_gitlab_http_status(:not_found)
end
@ -246,7 +246,7 @@ describe Boards::ListsController do
context 'with invalid list id' do
it 'returns a not found 404 response' do
remove_board_list user: user, board: board, list: 999
remove_board_list user: user, board: board, list: non_existing_record_id
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -24,7 +24,7 @@ describe Dashboard::TodosController do
end
it 'renders 404 when given project does not exists' do
get :index, params: { project_id: 999 }
get :index, params: { project_id: non_existing_record_id }
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -176,7 +176,7 @@ describe Projects::EnvironmentsController do
context 'with invalid id' do
it 'responds with a status code 404' do
params = environment_params
params[:id] = 12345
params[:id] = non_existing_record_id
get :show, params: params
expect(response).to have_gitlab_http_status(:not_found)

View File

@ -12,7 +12,7 @@ describe Projects::ErrorTracking::StackTracesController do
end
describe 'GET #index' do
let(:issue_id) { 1234 }
let(:issue_id) { non_existing_record_id }
let(:issue_stack_trace_service) { spy(:issue_stack_trace_service) }
subject(:get_stack_trace) do

View File

@ -182,7 +182,7 @@ describe Projects::ErrorTrackingController do
end
describe 'GET #issue_details' do
let_it_be(:issue_id) { 1234 }
let_it_be(:issue_id) { non_existing_record_id }
let(:issue_details_service) { spy(:issue_details_service) }
@ -279,7 +279,7 @@ describe Projects::ErrorTrackingController do
end
describe 'PUT #update' do
let(:issue_id) { 1234 }
let(:issue_id) { non_existing_record_id }
let(:issue_update_service) { spy(:issue_update_service) }
let(:permitted_params) do
ActionController::Parameters.new(
@ -301,7 +301,7 @@ describe Projects::ErrorTrackingController do
context 'update result is successful' do
before do
expect(issue_update_service).to receive(:execute)
.and_return(status: :success, updated: true, closed_issue_iid: 1234)
.and_return(status: :success, updated: true, closed_issue_iid: non_existing_record_iid)
update_issue
end

View File

@ -338,13 +338,13 @@ describe Projects::IssuesController do
context 'with invalid params' do
it 'returns a unprocessable entity 422 response for invalid move ids' do
reorder_issue(issue1, move_after_id: 99, move_before_id: 999)
reorder_issue(issue1, move_after_id: 99, move_before_id: non_existing_record_id)
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it 'returns a not found 404 response for invalid issue id' do
reorder_issue(object_double(issue1, iid: 999),
reorder_issue(object_double(issue1, iid: non_existing_record_iid),
move_after_id: issue2.id,
move_before_id: issue3.id)

View File

@ -132,7 +132,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when job does not exist' do
before do
get_show(id: 1234)
get_show(id: non_existing_record_id)
end
it 'renders not_found' do
@ -1146,7 +1146,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when job does not exist' do
it 'renders not_found' do
get_terminal(id: 1234)
get_terminal(id: non_existing_record_id)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -1191,7 +1191,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'and invalid id' do
it 'returns 404' do
get_terminal_websocket(id: 1234)
get_terminal_websocket(id: non_existing_record_id)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -8,11 +8,9 @@ describe Projects::MergeRequests::DiffsController do
shared_examples '404 for unexistent diffable' do
context 'when diffable does not exists' do
it 'returns 404' do
unexistent_diff_id = 9999
go(diff_id: non_existing_record_id)
go(diff_id: unexistent_diff_id)
expect(MergeRequestDiff.find_by(id: unexistent_diff_id)).to be_nil
expect(MergeRequestDiff.find_by(id: non_existing_record_id)).to be_nil
expect(response).to have_gitlab_http_status(:not_found)
end
end

View File

@ -585,7 +585,7 @@ describe Projects::NotesController do
context 'when a noteable is not found' do
it 'returns 404 status' do
request_params[:target_id] = 9999
request_params[:target_id] = non_existing_record_id
post :create, params: request_params.merge(format: :json)
expect(response).to have_gitlab_http_status(:not_found)

View File

@ -76,7 +76,7 @@ describe UploadsController do
end
it "returns 404 status when object not found" do
post :create, params: { model: model, id: 9999 }, format: :json
post :create, params: { model: model, id: non_existing_record_id }, format: :json
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -163,7 +163,7 @@ describe "Jira", :js do
markdown = <<~HEREDOC
Referencing internal issue #{issue_actual_project.to_reference},
cross-project #{issue_other_project.to_reference(actual_project)} external JIRA-5
and non existing #999
and non existing ##{non_existing_record_iid}
HEREDOC
page.within("#diff-notes-app") do
@ -186,6 +186,6 @@ describe "Jira", :js do
expect(page).not_to have_link("JIRA-5", href: "https://jira.example.com/browse/JIRA-5")
end
expect(page).not_to have_link("#999")
expect(page).not_to have_link("##{non_existing_record_iid}")
end
end

View File

@ -54,9 +54,11 @@ describe 'Projects > Snippets > User updates a snippet', :js do
end
context 'when the git operation fails' do
let(:error_message) { 'foobar' }
before do
allow_next_instance_of(Snippets::UpdateService) do |instance|
allow(instance).to receive(:create_commit).and_raise(StandardError)
allow(instance).to receive(:create_commit).and_raise(StandardError, error_message)
end
fill_in('project_snippet_title', with: 'Snippet new title')
@ -65,7 +67,7 @@ describe 'Projects > Snippets > User updates a snippet', :js do
end
it 'renders edit page and displays the error' do
expect(page.find('.flash-container span').text).to eq('Error updating the snippet')
expect(page.find('.flash-container span').text).to eq(error_message)
expect(page).to have_content('Edit Snippet')
end
end

View File

@ -85,9 +85,11 @@ describe 'User edits snippet', :js do
end
context 'when the git operation fails' do
let(:error_message) { 'foobar' }
before do
allow_next_instance_of(Snippets::UpdateService) do |instance|
allow(instance).to receive(:create_commit).and_raise(StandardError)
allow(instance).to receive(:create_commit).and_raise(StandardError, error_message)
end
fill_in 'personal_snippet_title', with: 'New Snippet Title'
@ -96,7 +98,7 @@ describe 'User edits snippet', :js do
end
it 'renders edit page and displays the error' do
expect(page.find('.flash-container span').text).to eq('Error updating the snippet')
expect(page.find('.flash-container span').text).to eq(error_message)
expect(page).to have_content('Edit Snippet')
end
end

View File

@ -97,7 +97,7 @@ describe FinderWithCrossProjectAccess do
end
it 're-enables the check after the find failed' do
finder.find_by!(id: 9999) rescue ActiveRecord::RecordNotFound
finder.find_by!(id: non_existing_record_id) rescue ActiveRecord::RecordNotFound
expect(finder.instance_variable_get(:@should_skip_cross_project_check))
.to eq(false)

View File

@ -774,14 +774,16 @@ describe IssuesFinder do
end
describe '#row_count', :request_store do
let_it_be(:admin) { create(:admin) }
it 'returns the number of rows for the default state' do
finder = described_class.new(user)
finder = described_class.new(admin)
expect(finder.row_count).to eq(4)
end
it 'returns the number of rows for a given state' do
finder = described_class.new(user, state: 'closed')
finder = described_class.new(admin, state: 'closed')
expect(finder.row_count).to be_zero
end

View File

@ -27,7 +27,7 @@ describe SentryIssueFinder do
it { is_expected.to eq(sentry_issue) }
context 'when identifier is incorrect' do
let(:identifier) { 1234 }
let(:identifier) { non_existing_record_id }
it { is_expected.to be_nil }
end

View File

@ -114,7 +114,7 @@ describe SnippetsFinder do
context 'when author is not valid' do
it 'returns quickly' do
finder = described_class.new(admin, author: 1234)
finder = described_class.new(admin, author: non_existing_record_id)
expect(finder).not_to receive(:init_collection)
expect(Snippet).to receive(:none).and_call_original
@ -208,7 +208,7 @@ describe SnippetsFinder do
context 'when project is not valid' do
it 'returns quickly' do
finder = described_class.new(admin, project: 1234)
finder = described_class.new(admin, project: non_existing_record_id)
expect(finder).not_to receive(:init_collection)
expect(Snippet).to receive(:none).and_call_original

View File

@ -2468,7 +2468,7 @@
"id": 27,
"target_branch": "feature",
"source_branch": "feature_conflict",
"source_project_id": 999,
"source_project_id": 2147483547,
"author_id": 1,
"assignee_id": null,
"title": "MR1",
@ -6334,13 +6334,13 @@
"status": "failed",
"started_at": null,
"finished_at": null,
"user_id": 9999,
"user_id": 2147483547,
"duration": null,
"source": "push",
"merge_request_id": null,
"notes": [
{
"id": 999,
"id": 2147483547,
"note": "Natus rerum qui dolorem dolorum voluptas.",
"noteable_type": "Commit",
"author_id": 1,
@ -6544,7 +6544,7 @@
"id": 27,
"target_branch": "feature",
"source_branch": "feature_conflict",
"source_project_id": 999,
"source_project_id": 2147483547,
"author_id": 1,
"assignee_id": null,
"title": "MR1",

View File

@ -1,7 +1,7 @@
{
"name": "ymg09t5704clnxnqfgaj2h098gz4r7gyx4wc3fzmlqj1en24zf",
"path": "ymg09t5704clnxnqfgaj2h098gz4r7gyx4wc3fzmlqj1en24zf",
"owner_id": 123,
"owner_id": 2147483547,
"created_at": "2019-11-20 17:01:53 UTC",
"updated_at": "2019-11-20 17:05:44 UTC",
"description": "Group Description",

View File

@ -1,7 +1,7 @@
{
"description": "Nisi et repellendus ut enim quo accusamus vel magnam.",
"import_type": "gitlab_project",
"creator_id": 123,
"creator_id": 2147483547,
"visibility_level": 10,
"archived": false,
"milestones": [

View File

@ -1,7 +1,7 @@
{
"description": "Nisi et repellendus ut enim quo accusamus vel magnam.",
"import_type": "gitlab_project",
"creator_id": 123,
"creator_id": 2147483547,
"visibility_level": 10,
"archived": false,
"issues": [

View File

@ -1,7 +1,7 @@
{
"description": "Nisi et repellendus ut enim quo accusamus vel magnam.",
"import_type": "gitlab_project",
"creator_id": 999,
"creator_id": 2147483547,
"visibility_level": 10,
"archived": false,
"milestones": [

View File

@ -2,7 +2,7 @@ import pipelineTourSuccess from '~/blob/pipeline_tour_success_modal.vue';
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
import { GlSprintf, GlModal } from '@gitlab/ui';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper';
import modalProps from './pipeline_tour_success_mock_data';
describe('PipelineTourSuccessModal', () => {
@ -16,6 +16,9 @@ describe('PipelineTourSuccessModal', () => {
trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
wrapper = shallowMount(pipelineTourSuccess, {
propsData: modalProps,
stubs: {
GlModal,
},
});
cookieSpy = jest.spyOn(Cookies, 'remove');
@ -41,11 +44,23 @@ describe('PipelineTourSuccessModal', () => {
});
describe('tracking', () => {
it('send event for basic view of popover', () => {
it('send event for basic view of modal', () => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, undefined, {
label: 'congratulate_first_pipeline',
property: modalProps.humanAccess,
});
});
it('send an event when go to pipelines is clicked', () => {
trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn);
const goToBtn = wrapper.find({ ref: 'goto' });
triggerEvent(goToBtn.element);
expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_button', {
label: 'congratulate_first_pipeline',
property: modalProps.humanAccess,
value: '10',
});
});
});
});

View File

@ -43,7 +43,7 @@ describe Mutations::Issues::Update do
context 'when iid does not exist' do
it 'raises resource not available error' do
mutation_params[:iid] = 99999
mutation_params[:iid] = non_existing_record_iid
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end

View File

@ -40,7 +40,7 @@ describe IssuablesHelper do
end
it 'returns default label when a group was not found for the provided id' do
expect(group_dropdown_label(9999, default)).to eq('default label')
expect(group_dropdown_label(non_existing_record_id, default)).to eq('default label')
end
end

View File

@ -22,7 +22,7 @@ describe API::Helpers do
context 'when ID is used as an argument' do
let(:existing_id) { project.id }
let(:non_existing_id) { (Project.maximum(:id) || 0) + 1 }
let(:non_existing_id) { non_existing_record_id }
it_behaves_like 'project finder'
end
@ -66,7 +66,7 @@ describe API::Helpers do
context 'when ID is used as an argument' do
let(:existing_id) { namespace.id }
let(:non_existing_id) { 9999 }
let(:non_existing_id) { non_existing_record_id }
it_behaves_like 'namespace finder'
end

View File

@ -77,7 +77,7 @@ describe Banzai::Filter::ReferenceRedactorFilter do
end
it 'handles invalid references' do
link = reference_link(project: 12345, reference_type: 'test')
link = reference_link(project: non_existing_record_id, reference_type: 'test')
expect { filter(link) }.not_to raise_error
end

View File

@ -9,14 +9,16 @@ describe Gitlab::ApplicationContext do
end
it 'passes the expected context on to labkit' do
user = build(:user)
project = build(:project)
fake_proc = duck_type(:call)
expected_context = hash_including(user: fake_proc, project: fake_proc, root_namespace: fake_proc)
expect(Labkit::Context).to receive(:with_context).with(expected_context)
described_class.with_context(
user: build(:user),
project: build(:project),
user: user,
project: project,
namespace: build(:namespace)) {}
end

View File

@ -39,7 +39,7 @@ describe Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig, schem
end
it 'raises OrphanedNamespaceError when any parent namespace does not exist' do
subgroup.update_attribute(:parent_id, namespaces.maximum(:id).succ)
subgroup.update_attribute(:parent_id, non_existing_record_id)
expect { project.full_path }.to raise_error(Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig::OrphanedNamespaceError)
end

View File

@ -90,7 +90,7 @@ describe Gitlab::BackgroundMigration::BackfillProjectRepositories do
it 'raises OrphanedNamespaceError when any parent namespace does not exist' do
subgroup = create(:group, parent: group)
project_orphaned_namespace = create(:project, name: 'baz', path: 'baz', namespace: subgroup, storage_version: nil)
subgroup.update_column(:parent_id, Namespace.maximum(:id).succ)
subgroup.update_column(:parent_id, non_existing_record_id)
project = described_class.find(project_orphaned_namespace.id)
project.route.destroy

View File

@ -0,0 +1,71 @@
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::BackgroundMigration::PopulateUserHighestRolesTable, schema: 20200311130802 do
let(:members) { table(:members) }
let(:users) { table(:users) }
let(:user_highest_roles) { table(:user_highest_roles) }
def create_user(id, params = {})
user_params = {
id: id,
state: 'active',
user_type: nil,
bot_type: nil,
ghost: nil,
email: "user#{id}@example.com",
projects_limit: 0
}.merge(params)
users.create(user_params)
end
def create_member(id, access_level, params = {})
params = {
user_id: id,
access_level: access_level,
source_id: 1,
source_type: 'Group',
notification_level: 0
}.merge(params)
members.create(params)
end
before do
create_user(1)
create_user(2, state: 'blocked')
create_user(3, user_type: 2)
create_user(4)
create_user(5, bot_type: 1)
create_user(6, ghost: true)
create_user(7, ghost: false)
create_user(8)
create_member(1, 40)
create_member(7, 30)
create_member(8, 20, requested_at: Time.current)
user_highest_roles.create(user_id: 1, highest_access_level: 50)
end
describe '#perform' do
it 'creates user_highest_roles rows according to users', :aggregate_failures do
expect { subject.perform(1, 8) }.to change(UserHighestRole, :count).from(1).to(4)
created_or_updated_rows = [
{ 'user_id' => 1, 'highest_access_level' => 40 },
{ 'user_id' => 4, 'highest_access_level' => nil },
{ 'user_id' => 7, 'highest_access_level' => 30 },
{ 'user_id' => 8, 'highest_access_level' => nil }
]
rows = user_highest_roles.order(:user_id).map do |row|
row.attributes.slice('user_id', 'highest_access_level')
end
expect(rows).to match_array(created_or_updated_rows)
end
end
end

View File

@ -234,10 +234,8 @@ describe Gitlab::BackgroundMigration::RecalculateProjectAuthorizations, schema:
end
context 'deleted user' do
let(:nonexistent_user_id) { User.maximum(:id).to_i + 999 }
it 'does not fail' do
expect { described_class.new.perform([nonexistent_user_id]) }.not_to raise_error
expect { described_class.new.perform([non_existing_record_id]) }.not_to raise_error
end
end
end

View File

@ -5,7 +5,7 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Composite do
let_it_be(:pipeline) { create(:ci_pipeline) }
before(:all) do
before_all do
@statuses = HasStatus::STATUSES_ENUM.map do |status, idx|
[status, create(:ci_build, pipeline: pipeline, status: status, importing: true)]
end.to_h

View File

@ -8,7 +8,7 @@ describe Gitlab::ImportExport::Group::TreeRestorer do
let(:shared) { Gitlab::ImportExport::Shared.new(group) }
describe 'restore group tree' do
before(:context) do
before_all do
# Using an admin for import, so we can check assignment of existing members
user = create(:admin, email: 'root@gitlabexample.com')
create(:user, email: 'adriene.mcclure@gitlabexample.com')

View File

@ -0,0 +1,98 @@
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::ImportExport::JSON::StreamingSerializer do
let_it_be(:user) { create(:user) }
let_it_be(:release) { create(:release) }
let_it_be(:group) { create(:group) }
let_it_be(:exportable) do
create(:project,
:public,
:repository,
:issues_disabled,
:wiki_enabled,
:builds_private,
description: 'description',
releases: [release],
group: group,
approvals_before_merge: 1)
end
let_it_be(:issue) do
create(:issue,
assignees: [user],
project: exportable)
end
let(:exportable_path) { 'project' }
let(:json_writer) { instance_double('Gitlab::ImportExport::JSON::LegacyWriter') }
let(:hash) { { name: exportable.name, description: exportable.description }.stringify_keys }
let(:include) { [] }
let(:relations_schema) do
{
only: [:name, :description],
include: include,
preload: { issues: nil }
}
end
subject do
described_class.new(exportable, relations_schema, json_writer, exportable_path: exportable_path)
end
describe '#execute' do
before do
allow(json_writer).to receive(:write_attributes).with(exportable_path, hash)
end
it 'calls json_writer.write_attributes with proper params' do
subject.execute
end
context 'with many relations' do
let(:include) do
[{ issues: { include: [] } }]
end
it 'calls json_writer.write_relation_array with proper params' do
expect(json_writer).to receive(:write_relation_array).with(exportable_path, :issues, array_including(issue.to_json))
subject.execute
end
end
context 'with single relation' do
let(:group_options) do
{ include: [], only: [:name, :path, :description] }
end
let(:include) do
[{ group: group_options }]
end
it 'calls json_writer.write_relation with proper params' do
expect(json_writer).to receive(:write_relation).with(exportable_path, :group, group.to_json(group_options))
subject.execute
end
end
context 'with array relation' do
let(:project_member) { create(:project_member, user: user) }
let(:include) do
[{ project_members: { include: [] } }]
end
before do
allow(exportable).to receive(:project_members).and_return([project_member])
end
it 'calls json_writer.write_relation_array with proper params' do
expect(json_writer).to receive(:write_relation_array).with(exportable_path, :project_members, array_including(project_member.to_json))
subject.execute
end
end
end
end

View File

@ -8,7 +8,7 @@ describe Gitlab::ImportExport::Project::TreeRestorer do
let(:shared) { project.import_export_shared }
describe 'restore project tree' do
before(:context) do
before_all do
# Using an admin for import, so we can check assignment of existing members
@user = create(:admin)
@existing_members = [

View File

@ -165,13 +165,13 @@ describe Gitlab::ObjectHierarchy do
end
it 'uses ancestors_base #initialize argument for ancestors' do
relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_objects
relation = described_class.new(Group.where(id: child1.id), Group.where(id: non_existing_record_id)).all_objects
expect(relation).to include(parent)
end
it 'uses descendants_base #initialize argument for descendants' do
relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_objects
relation = described_class.new(Group.where(id: non_existing_record_id), Group.where(id: child1.id)).all_objects
expect(relation).to include(child2)
end

View File

@ -234,7 +234,7 @@ describe Gitlab::ProjectAuthorizations do
end
context 'unrelated project owner' do
let(:common_id) { [Project.maximum(:id).to_i, Namespace.maximum(:id).to_i].max + 999 }
let(:common_id) { non_existing_record_id }
let!(:group) { create(:group, id: common_id) }
let!(:unrelated_project) { create(:project, id: common_id) }
let(:user) { unrelated_project.owner }

View File

@ -130,7 +130,7 @@ describe Gitlab::ReferenceExtractor do
@i0 = create(:issue, project: project)
@i1 = create(:issue, project: project)
subject.analyze("#{@i0.to_reference}, #{@i1.to_reference}, and #{Issue.reference_prefix}999.")
subject.analyze("#{@i0.to_reference}, #{@i1.to_reference}, and #{Issue.reference_prefix}#{non_existing_record_iid}.")
expect(subject.issues).to match_array([@i0, @i1])
end
@ -139,7 +139,7 @@ describe Gitlab::ReferenceExtractor do
@m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'markdown')
@m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'feature_conflict')
subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.")
subject.analyze("!#{non_existing_record_iid}, !#{@m1.iid}, and !#{@m0.iid}.")
expect(subject.merge_requests).to match_array([@m1, @m0])
end
@ -149,7 +149,7 @@ describe Gitlab::ReferenceExtractor do
@l1 = create(:label, title: 'two', project: project)
@l2 = create(:label)
subject.analyze("~#{@l0.id}, ~999, ~#{@l2.id}, ~#{@l1.id}")
subject.analyze("~#{@l0.id}, ~#{non_existing_record_id}, ~#{@l2.id}, ~#{@l1.id}")
expect(subject.labels).to match_array([@l0, @l1])
end
@ -159,7 +159,7 @@ describe Gitlab::ReferenceExtractor do
@s1 = create(:project_snippet, project: project)
@s2 = create(:project_snippet)
subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}")
subject.analyze("$#{@s0.id}, $#{non_existing_record_id}, $#{@s2.id}, $#{@s1.id}")
expect(subject.snippets).to match_array([@s0, @s1])
end
@ -205,7 +205,7 @@ describe Gitlab::ReferenceExtractor do
end
it 'returns only Jira issues if the internal one does not exists' do
subject.analyze("JIRA-123 and FOOBAR-4567 and #999")
subject.analyze("JIRA-123 and FOOBAR-4567 and ##{non_existing_record_iid}")
expect(subject.issues).to eq [ExternalIssue.new('JIRA-123', project),
ExternalIssue.new('FOOBAR-4567', project)]
end

View File

@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200311130802_schedule_populate_user_highest_roles_table.rb')
describe SchedulePopulateUserHighestRolesTable do
let(:users) { table(:users) }
def create_user(id, params = {})
user_params = {
id: id,
state: 'active',
user_type: nil,
bot_type: nil,
ghost: nil,
email: "user#{id}@example.com",
projects_limit: 0
}.merge(params)
users.create!(user_params)
end
it 'correctly schedules background migrations' do
create_user(1)
create_user(2, state: 'blocked')
create_user(3, user_type: 2)
create_user(4)
create_user(5, bot_type: 1)
create_user(6, ghost: true)
create_user(7, ghost: false)
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
Timecop.freeze do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 4)
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 7, 7)
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
end
end
end
end

View File

@ -165,10 +165,10 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
ActiveSession.set(user, request)
Gitlab::Redis::SharedState.with do |redis|
expect(redis.scan_each.to_a).to match_array [
expect(redis.scan_each.to_a).to include(
"session:user:gitlab:#{user.id}:6919a6f1bb119dd7396fadc38fd18d0d",
"session:lookup:user:gitlab:#{user.id}"
]
)
end
end

View File

@ -597,99 +597,51 @@ describe Member do
end
context 'when after_commit :update_highest_role' do
context 'with feature flag enabled' do
where(:member_type, :source_type) do
:project_member | :project
:group_member | :group
where(:member_type, :source_type) do
:project_member | :project
:group_member | :group
end
with_them do
describe 'create member' do
it 'initializes a new Members::UpdateHighestRoleService object' do
source = create(source_type) # source owner initializes a new service object too
user = create(:user)
expect(Members::UpdateHighestRoleService).to receive(:new).with(user.id).and_call_original
create(member_type, :guest, user: user, source_type => source)
end
end
with_them do
describe 'create member' do
it 'initializes a new Members::UpdateHighestRoleService object' do
source = create(source_type) # source owner initializes a new service object too
user = create(:user)
context 'when member exists' do
let!(:member) { create(member_type) }
expect(Members::UpdateHighestRoleService).to receive(:new).with(user.id).and_call_original
create(member_type, :guest, user: user, source_type => source)
end
end
context 'when member exists' do
let!(:member) { create(member_type) }
describe 'update member' do
context 'when access level was changed' do
it 'initializes a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).to receive(:new).with(member.user_id).and_call_original
member.update(access_level: Gitlab::Access::GUEST)
end
end
context 'when access level was not changed' do
it 'does not initialize a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).not_to receive(:new).with(member.user_id)
member.update(notification_level: NotificationSetting.levels[:disabled])
end
end
end
describe 'destroy member' do
describe 'update member' do
context 'when access level was changed' do
it 'initializes a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).to receive(:new).with(member.user_id).and_call_original
member.destroy
end
end
end
end
end
context 'with feature flag disabled' do
before do
stub_feature_flags(highest_role_callback: false)
end
where(:member_type, :source_type) do
:project_member | :project
:group_member | :group
end
with_them do
describe 'create member' do
it 'does not initialize a new Members::UpdateHighestRoleService object' do
source = create(source_type)
user = create(:user)
expect(Members::UpdateHighestRoleService).not_to receive(:new).with(user.id)
create(member_type, :guest, user: user, source_type => source)
end
end
context 'when member exists' do
let!(:member) { create(member_type) }
describe 'update member' do
context 'when access level was changed' do
it 'does not initialize a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).not_to receive(:new).with(member.user_id)
member.update(access_level: Gitlab::Access::GUEST)
end
member.update(access_level: Gitlab::Access::GUEST)
end
end
describe 'destroy member' do
context 'when access level was not changed' do
it 'does not initialize a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).not_to receive(:new).with(member.user_id)
member.destroy
member.update(notification_level: NotificationSetting.levels[:disabled])
end
end
end
describe 'destroy member' do
it 'initializes a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).to receive(:new).with(member.user_id).and_call_original
member.destroy
end
end
end
end
end

View File

@ -827,7 +827,7 @@ describe Project do
end
it 'returns nil when no issue found' do
expect(project.get_issue(999, user)).to be_nil
expect(project.get_issue(non_existing_record_id, user)).to be_nil
end
it "returns nil when user doesn't have access" do

View File

@ -53,7 +53,7 @@ describe UserPreference do
it 'returns the current notes filter' do
user_preference.set_notes_filter(only_comments, issuable)
expect(user_preference.set_notes_filter(9999, issuable)).to eq(only_comments)
expect(user_preference.set_notes_filter(non_existing_record_id, issuable)).to eq(only_comments)
end
end
end

View File

@ -1221,6 +1221,10 @@ describe User, :do_not_mock_admin_mode do
end
it 'uses SecureRandom to generate the incoming email token' do
allow_next_instance_of(User) do |user|
allow(user).to receive(:update_highest_role)
end
expect(SecureRandom).to receive(:hex).and_return('3b8ca303')
user = create(:user)
@ -4441,4 +4445,52 @@ describe User, :do_not_mock_admin_mode do
end
end
end
context 'when after_commit :update_highest_role' do
describe 'create user' do
it 'initializes a new Members::UpdateHighestRoleService object' do
expect_next_instance_of(Members::UpdateHighestRoleService) do |service|
expect(service).to receive(:execute)
end
create(:user)
end
end
context 'when user already exists' do
let!(:user) { create(:user) }
describe 'update user' do
using RSpec::Parameterized::TableSyntax
where(:attributes) do
[
{ state: 'blocked' },
{ ghost: true },
{ user_type: :alert_bot }
]
end
with_them do
context 'when state was changed' do
it 'initializes a new Members::UpdateHighestRoleService object' do
expect_next_instance_of(Members::UpdateHighestRoleService) do |service|
expect(service).to receive(:execute)
end
user.update(attributes)
end
end
end
context 'when state was not changed' do
it 'does not initialize a new Members::UpdateHighestRoleService object' do
expect(Members::UpdateHighestRoleService).not_to receive(:new)
user.update(email: 'newmail@example.com')
end
end
end
end
end
end

View File

@ -17,5 +17,7 @@ RSpec.configure do |config|
# Reset stdout
config.after(:all) do
$stdout = STDOUT
delete_from_all_tables!
end
end

View File

@ -26,7 +26,7 @@ describe API::AwardEmoji do
end
it "returns a 404 error when issue id not found" do
get api("/projects/#{project.id}/issues/12345/award_emoji", user)
get api("/projects/#{project.id}/issues/#{non_existing_record_iid}/award_emoji", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -91,7 +91,7 @@ describe API::AwardEmoji do
end
it "returns a 404 error if the award is not found" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/12345", user)
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -255,7 +255,7 @@ describe API::AwardEmoji do
end
it 'returns a 404 error when the award emoji can not be found' do
delete api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/12345", user)
delete api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -275,7 +275,7 @@ describe API::AwardEmoji do
end
it 'returns a 404 error when note id not found' do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes/12345", user)
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -127,7 +127,7 @@ describe API::Environments do
end
it 'returns a 400 when the required params are missing' do
post api("/projects/12345/environments", non_member), params: { external_url: 'http://env.git.com' }
post api("/projects/#{non_existing_record_id}/environments", non_member), params: { external_url: 'http://env.git.com' }
end
end
end
@ -163,7 +163,7 @@ describe API::Environments do
end
it 'returns a 404 if the environment does not exist' do
put api("/projects/#{project.id}/environments/12345", user)
put api("/projects/#{project.id}/environments/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -186,7 +186,7 @@ describe API::Environments do
end
it 'returns a 404 for non existing id' do
delete api("/projects/#{project.id}/environments/12345", user)
delete api("/projects/#{project.id}/environments/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')
@ -229,7 +229,7 @@ describe API::Environments do
end
it 'returns a 404 for non existing id' do
post api("/projects/#{project.id}/environments/12345/stop", user)
post api("/projects/#{project.id}/environments/#{non_existing_record_id}/stop", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')

View File

@ -47,7 +47,7 @@ describe API::GroupContainerRepositories do
it_behaves_like 'a gitlab tracking event', described_class.name, 'list_repositories'
context 'with invalid group id' do
let(:url) { '/groups/123412341234/registry/repositories' }
let(:url) { "/groups/#{non_existing_record_id}/registry/repositories" }
it 'returns not found' do
subject

View File

@ -97,7 +97,7 @@ describe API::GroupImport do
context 'when parent group is invalid' do
it 'returns 404 and does not create new group' do
params[:parent_id] = 99999
params[:parent_id] = non_existing_record_id
expect { subject }.not_to change { Group.count }

View File

@ -334,7 +334,7 @@ describe API::GroupLabels do
context 'when label ID is not found' do
it 'returns 404 error' do
post api("/groups/#{group.id}/labels/1234/subscribe", user)
post api("/groups/#{group.id}/labels/#{non_existing_record_id}/subscribe", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -380,7 +380,7 @@ describe API::GroupLabels do
context 'when label ID is not found' do
it 'returns 404 error' do
post api("/groups/#{group.id}/labels/1234/unsubscribe", user)
post api("/groups/#{group.id}/labels/#{non_existing_record_id}/unsubscribe", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -34,7 +34,7 @@ describe API::ImportGithub do
post api("/import/github", user), params: {
target_namespace: user.namespace_path,
personal_access_token: token,
repo_id: 1234
repo_id: non_existing_record_id
}
expect(response).to have_gitlab_http_status(:created)
expect(json_response).to be_a Hash
@ -47,7 +47,7 @@ describe API::ImportGithub do
post api("/import/github", user), params: {
target_namespace: other_namespace.name,
personal_access_token: token,
repo_id: 1234
repo_id: non_existing_record_id
}
expect(response).to have_gitlab_http_status(:unprocessable_entity)

View File

@ -53,7 +53,7 @@ describe API::Internal::Base do
post api('/internal/two_factor_recovery_codes'),
params: {
secret_token: secret_token,
key_id: 12345
key_id: non_existing_record_id
}
expect(json_response['success']).to be_falsey
@ -152,13 +152,13 @@ describe API::Internal::Base do
end
it 'returns a 404 when the wrong key is provided' do
lfs_auth_key(key.id + 12345, project)
lfs_auth_key(non_existing_record_id, project)
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns a 404 when the wrong user is provided' do
lfs_auth_user(user.id + 12345, project)
lfs_auth_user(non_existing_record_id, project)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -78,7 +78,7 @@ describe API::Issues do
description: "closes #{issue.to_reference(private_mrs_project)}")
end
before(:all) do
before_all do
project.add_reporter(user)
project.add_guest(guest)
private_mrs_project.add_reporter(user)

View File

@ -61,7 +61,7 @@ describe API::Issues do
let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
before(:all) do
before_all do
project.add_reporter(user)
project.add_guest(guest)
private_mrs_project.add_reporter(user)

View File

@ -60,7 +60,7 @@ describe API::Issues do
let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
before(:all) do
before_all do
project.add_reporter(user)
project.add_guest(guest)
end

View File

@ -61,7 +61,7 @@ describe API::Issues do
let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
before(:all) do
before_all do
project.add_reporter(user)
project.add_guest(guest)
end

View File

@ -596,7 +596,7 @@ describe API::Labels do
context "when label ID is not found" do
it "returns 404 error" do
post api("/projects/#{project.id}/labels/1234/subscribe", user)
post api("/projects/#{project.id}/labels/#{non_existing_record_id}/subscribe", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -642,7 +642,7 @@ describe API::Labels do
context "when label ID is not found" do
it "returns 404 error" do
post api("/projects/#{project.id}/labels/1234/unsubscribe", user)
post api("/projects/#{project.id}/labels/#{non_existing_record_id}/unsubscribe", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -314,9 +314,9 @@ describe API::Members do
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'returns 400 when access_level is not valid' do
it 'returns 400 when access_level is not valid' do
post api("/#{source_type.pluralize}/#{source.id}/members", maintainer),
params: { user_id: stranger.id, access_level: 1234 }
params: { user_id: stranger.id, access_level: non_existing_record_access_level }
expect(response).to have_gitlab_http_status(:bad_request)
end
@ -371,9 +371,9 @@ describe API::Members do
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'returns 400 when access level is not valid' do
it 'returns 400 when access level is not valid' do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", maintainer),
params: { access_level: 1234 }
params: { access_level: non_existing_record_access_level }
expect(response).to have_gitlab_http_status(:bad_request)
end

View File

@ -60,7 +60,7 @@ describe API::MergeRequestDiffs, 'MergeRequestDiffs' do
end
it 'returns a 404 when merge_request_iid is not found' do
get api("/projects/#{project.id}/merge_requests/12345/versions/#{merge_request_diff.id}", user)
get api("/projects/#{project.id}/merge_requests/#{non_existing_record_iid}/versions/#{merge_request_diff.id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
end

View File

@ -1720,7 +1720,7 @@ describe API::MergeRequests do
end
it "returns 404 for an invalid merge request IID" do
delete api("/projects/#{project.id}/merge_requests/12345", user)
delete api("/projects/#{project.id}/merge_requests/#{non_existing_record_iid}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -1931,7 +1931,7 @@ describe API::MergeRequests do
end
it "returns 404 for an invalid merge request IID" do
put api("/projects/#{project.id}/merge_requests/12345/merge", user)
put api("/projects/#{project.id}/merge_requests/#{non_existing_record_iid}/merge", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -2053,7 +2053,7 @@ describe API::MergeRequests do
end
context 'when invalid merge request IID' do
let(:merge_request_iid) { '12345' }
let(:merge_request_iid) { non_existing_record_iid }
it 'returns 404' do
get api(url, user)
@ -2301,7 +2301,7 @@ describe API::MergeRequests do
end
it "returns 404 for an invalid merge request IID" do
put api("/projects/#{project.id}/merge_requests/12345", user), params: { state_event: "close" }
put api("/projects/#{project.id}/merge_requests/#{non_existing_record_iid}", user), params: { state_event: "close" }
expect(response).to have_gitlab_http_status(:not_found)
end
@ -2366,7 +2366,7 @@ describe API::MergeRequests do
end
it "returns 404 for an invalid merge request IID" do
get api("/projects/#{project.id}/merge_requests/12345/closes_issues", user)
get api("/projects/#{project.id}/merge_requests/#{non_existing_record_iid}/closes_issues", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -442,7 +442,7 @@ describe API::Pipelines do
end
it 'returns 404 when it does not exist' do
get api("/projects/#{project.id}/pipelines/123456", user)
get api("/projects/#{project.id}/pipelines/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq '404 Not found'
@ -599,7 +599,7 @@ describe API::Pipelines do
end
it 'returns 404 when it does not exist' do
delete api("/projects/#{project.id}/pipelines/123456", owner)
delete api("/projects/#{project.id}/pipelines/#{non_existing_record_id}", owner)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq '404 Not found'

View File

@ -107,7 +107,7 @@ describe API::ProjectEvents do
end
it 'returns 404 if project does not exist' do
get api("/projects/1234/events", user)
get api("/projects/#{non_existing_record_id}/events", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -75,7 +75,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
end
it "returns a 404 error if hook id is not available" do
get api("/projects/#{project.id}/hooks/1234", user)
get api("/projects/#{project.id}/hooks/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -180,7 +180,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
end
it "returns 404 error if hook id not found" do
put api("/projects/#{project.id}/hooks/1234", user), params: { url: 'http://example.org' }
put api("/projects/#{project.id}/hooks/#{non_existing_record_id}", user), params: { url: 'http://example.org' }
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -110,7 +110,7 @@ describe API::ProjectSnippets do
end
it 'returns 404 for invalid snippet id' do
get api("/projects/#{project.id}/snippets/1234", user)
get api("/projects/#{project.id}/snippets/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')
@ -349,7 +349,7 @@ describe API::ProjectSnippets do
end
it 'returns 404 for invalid snippet id' do
update_snippet(snippet_id: '1234', params: { title: 'foo' })
update_snippet(snippet_id: non_existing_record_id, params: { title: 'foo' })
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Snippet Not Found')
@ -442,7 +442,7 @@ describe API::ProjectSnippets do
end
it 'returns 404 for invalid snippet id' do
delete api("/projects/#{snippet.project.id}/snippets/1234", admin)
delete api("/projects/#{snippet.project.id}/snippets/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Snippet Not Found')
@ -471,7 +471,7 @@ describe API::ProjectSnippets do
end
it 'returns 404 for invalid snippet id' do
get api("/projects/#{snippet.project.id}/snippets/1234/raw", admin)
get api("/projects/#{snippet.project.id}/snippets/#{non_existing_record_id}/raw", admin)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Snippet Not Found')

View File

@ -1101,7 +1101,7 @@ describe API::Projects do
end
it 'returns error when user not found' do
get api('/users/9999/starred_projects/')
get api("/users/#{non_existing_record_id}/starred_projects/")
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
@ -2088,13 +2088,13 @@ describe API::Projects do
end
it 'returns a 404 error when group does not exist' do
post api("/projects/#{project.id}/share", user), params: { group_id: 1234, group_access: Gitlab::Access::DEVELOPER }
post api("/projects/#{project.id}/share", user), params: { group_id: non_existing_record_id, group_access: Gitlab::Access::DEVELOPER }
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns a 400 error when wrong params passed" do
post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: 1234 }
post api("/projects/#{project.id}/share", user), params: { group_id: group.id, group_access: non_existing_record_access_level }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq 'group_access does not have a valid value'
@ -2137,13 +2137,13 @@ describe API::Projects do
end
it 'returns a 404 error when group link does not exist' do
delete api("/projects/#{project.id}/share/1234", user)
delete api("/projects/#{project.id}/share/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns a 404 error when project does not exist' do
delete api("/projects/123/share/1234", user)
delete api("/projects/123/share/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@ -2634,7 +2634,7 @@ describe API::Projects do
end
it 'returns not_found(404) for not existing project' do
get api("/projects/9999999999/starrers", user)
get api("/projects/#{non_existing_record_id}/starrers", user)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -117,7 +117,7 @@ describe API::Repositories do
context 'when sha does not exist' do
it_behaves_like '404 response' do
let(:request) { get api(route.sub(sample_blob.oid, '123456'), current_user) }
let(:request) { get api(route.sub(sample_blob.oid, 'abcd9876'), current_user) }
let(:message) { '404 Blob Not Found' }
end
end
@ -179,7 +179,7 @@ describe API::Repositories do
context 'when sha does not exist' do
it_behaves_like '404 response' do
let(:request) { get api(route.sub(sample_blob.oid, '123456'), current_user) }
let(:request) { get api(route.sub(sample_blob.oid, 'abcd9876'), current_user) }
let(:message) { '404 Blob Not Found' }
end
end

View File

@ -354,7 +354,7 @@ describe API::Snippets do
it_behaves_like 'snippet updates'
it 'returns 404 for invalid snippet id' do
update_snippet(snippet_id: '1234', params: { title: 'Foo' })
update_snippet(snippet_id: non_existing_record_id, params: { title: 'Foo' })
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Snippet Not Found')
@ -441,7 +441,7 @@ describe API::Snippets do
end
it 'returns 404 for invalid snippet id' do
delete api("/snippets/1234", user)
delete api("/snippets/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Snippet Not Found')

View File

@ -126,7 +126,7 @@ describe API::SystemHooks do
end
it 'returns 404 if the system hook does not exist' do
delete api('/hooks/12345', admin)
delete api("/hooks/#{non_existing_record_id}", admin)
expect(response).to have_gitlab_http_status(:not_found)
end

View File

@ -5,7 +5,7 @@ require 'spec_helper'
describe ErrorTracking::IssueUpdateService do
include_context 'sentry error tracking context'
let(:arguments) { { issue_id: 1234, status: 'resolved' } }
let(:arguments) { { issue_id: non_existing_record_id, status: 'resolved' } }
subject(:update_service) { described_class.new(project, user, arguments) }

View File

@ -824,14 +824,14 @@ describe Issues::UpdateService, :mailer do
context 'when moving an issue ' do
it 'raises an error for invalid move ids within a project' do
opts = { move_between_ids: [9000, 9999] }
opts = { move_between_ids: [9000, non_existing_record_id] }
expect { described_class.new(issue.project, user, opts).execute(issue) }
.to raise_error(ActiveRecord::RecordNotFound)
end
it 'raises an error for invalid move ids within a group' do
opts = { move_between_ids: [9000, 9999], board_group_id: create(:group).id }
opts = { move_between_ids: [9000, non_existing_record_id], board_group_id: create(:group).id }
expect { described_class.new(issue.project, user, opts).execute(issue) }
.to raise_error(ActiveRecord::RecordNotFound)

View File

@ -65,7 +65,7 @@ describe Labels::AvailableLabelsService do
end
describe '#filter_labels_ids_in_param' do
let(:label_ids) { labels.map(&:id).push(99999) }
let(:label_ids) { labels.map(&:id).push(non_existing_record_id) }
context 'when parent is a project' do
it 'returns only relevant label ids' do

Some files were not shown because too many files have changed in this diff Show More