Commit a24a1c25 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into 2302-environment-specific-variables

* ee/master:
  Fix remaining DotPosition cops
  Fix broken time sync leeway with Geo
  Use curl --remote-name instead of curl -O to fix broken docs lint
  Ignore RSpec/FilePath for this spec
  Use User#has_full_private_access? to check if user has Private access
  Move user Auditor role code to EE-specific file
  Auditor user should also have private access
  Refactor GroupProjectsFinder#init_collection
  Refactor Project.with_feature_available_for_user
  Refactor ProjectsFinder#init_collection
  Inject EE specific modules using EE::Project
  Move EE specific code out of Project
parents 829bd27e 5514552c
......@@ -33,7 +33,8 @@ class EventsFinder
private
def by_current_user_access(events)
events.merge(ProjectsFinder.new(current_user: current_user).execute).references(:project)
events.merge(ProjectsFinder.new(current_user: current_user).execute)
.joins(:project)
end
def by_action(events)
......
......@@ -29,35 +29,69 @@ class GroupProjectsFinder < ProjectsFinder
private
def init_collection
only_owned = options.fetch(:only_owned, false)
only_shared = options.fetch(:only_shared, false)
projects = if current_user
collection_with_user
else
collection_without_user
end
projects = []
union(projects)
end
if current_user
def collection_with_user
if group.users.include?(current_user)
projects << group.projects unless only_shared
projects << group.shared_projects unless only_owned
if only_shared?
[shared_projects]
elsif only_owned?
[owned_projects]
else
unless only_shared
projects << group.projects.visible_to_user(current_user)
projects << group.projects.public_to_user(current_user)
[shared_projects, owned_projects]
end
unless only_owned
projects << group.shared_projects.visible_to_user(current_user)
projects << group.shared_projects.public_to_user(current_user)
else
if only_shared?
[shared_projects.public_or_visible_to_user(current_user)]
elsif only_owned?
[owned_projects.public_or_visible_to_user(current_user)]
else
[
owned_projects.public_or_visible_to_user(current_user),
shared_projects.public_or_visible_to_user(current_user)
]
end
end
else
projects << group.projects.public_only unless only_shared
projects << group.shared_projects.public_only unless only_owned
end
projects
def collection_without_user
if only_shared?
[shared_projects.public_only]
elsif only_owned?
[owned_projects.public_only]
else
[shared_projects.public_only, owned_projects.public_only]
end
end
def union(items)
if items.one?
items.first
else
find_union(items, Project)
end
end
def only_owned?
options.fetch(:only_owned, false)
end
def only_shared?
options.fetch(:only_shared, false)
end
def owned_projects
group.projects
end
def shared_projects
group.shared_projects
end
end
......@@ -28,34 +28,56 @@ class ProjectsFinder < UnionFinder
end
def execute
items = init_collection
items = items.map do |item|
item = by_ids(item)
item = by_personal(item)
item = by_starred(item)
item = by_trending(item)
item = by_visibilty_level(item)
item = by_tags(item)
item = by_search(item)
by_archived(item)
end
items = union(items)
sort(items)
collection = init_collection
collection = by_ids(collection)
collection = by_personal(collection)
collection = by_starred(collection)
collection = by_trending(collection)
collection = by_visibilty_level(collection)
collection = by_tags(collection)
collection = by_search(collection)
collection = by_archived(collection)
sort(collection)
end
private
def init_collection
projects = []
if current_user
collection_with_user
else
collection_without_user
end
end
if params[:owned].present?
projects << current_user.owned_projects if current_user
def collection_with_user
if owned_projects?
current_user.owned_projects
else
projects << current_user.authorized_projects if current_user
projects << Project.unscoped.public_to_user(current_user) unless params[:non_public].present?
if private_only?
current_user.authorized_projects
else
Project.public_or_visible_to_user(current_user)
end
end
end
# Builds a collection for an anonymous user.
def collection_without_user
if private_only? || owned_projects?
Project.none
else
Project.public_to_user
end
end
def owned_projects?
params[:owned].present?
end
projects
def private_only?
params[:non_public].present?
end
def by_ids(items)
......
......@@ -8,13 +8,33 @@ module EE
prepended do
include IgnorableColumn
include Elastic::ProjectsSearch
prepend GeoAwareAvatar
prepend ImportStatusStateMachine
ignore_column :sync_time
before_validation :mark_remote_mirrors_for_removal
after_save :create_mirror_data, if: ->(project) { project.mirror? && project.mirror_changed? }
after_save :destroy_mirror_data, if: ->(project) { !project.mirror? && project.mirror_changed? }
after_update :remove_mirror_repository_reference,
if: ->(project) { project.mirror? && project.import_url_updated? }
belongs_to :mirror_user, foreign_key: 'mirror_user_id', class_name: 'User'
has_one :mirror_data, dependent: :delete, autosave: true, class_name: 'ProjectMirrorData'
has_one :push_rule, dependent: :destroy
has_one :index_status, dependent: :destroy
has_one :jenkins_service, dependent: :destroy
has_one :jenkins_deprecated_service, dependent: :destroy
has_many :approvers, as: :target, dependent: :destroy
has_many :approver_groups, as: :target, dependent: :destroy
has_many :audit_events, as: :entity, dependent: :destroy
has_many :remote_mirrors, inverse_of: :project, dependent: :destroy
has_many :path_locks, dependent: :destroy
scope :with_shared_runners_limit_enabled, -> { with_shared_runners.non_public_only }
......@@ -29,11 +49,94 @@ module EE
{ limit: 20.minutes.ago })
end
scope :mirror, -> { where(mirror: true) }
scope :with_remote_mirrors, -> { joins(:remote_mirrors).where(remote_mirrors: { enabled: true }).distinct }
scope :with_wiki_enabled, -> { with_feature_enabled(:wiki) }
delegate :shared_runners_minutes, :shared_runners_seconds, :shared_runners_seconds_last_reset,
to: :statistics, allow_nil: true
delegate :actual_shared_runners_minutes_limit,
:shared_runners_minutes_used?, to: :namespace
validates :repository_size_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0, allow_nil: true }
validates :approvals_before_merge, numericality: true, allow_blank: true
accepts_nested_attributes_for :remote_mirrors,
allow_destroy: true,
reject_if: ->(attrs) { attrs[:id].blank? && attrs[:url].blank? }
with_options if: :mirror? do |project|
project.validates :import_url, presence: true
project.validates :mirror_user, presence: true
end
end
module ClassMethods
def search_by_visibility(level)
where(visibility_level: ::Gitlab::VisibilityLevel.string_options[level])
end
end
def mirror_updated?
mirror? && self.mirror_last_update_at
end
def updating_mirror?
return false unless mirror? && !empty_repo?
return true if import_in_progress?
self.mirror_data.next_execution_timestamp < Time.now
end
def mirror_last_update_status
return unless mirror_updated?
if self.mirror_last_update_at == self.mirror_last_successful_update_at
:success
else
:failed
end
end
def mirror_last_update_success?
mirror_last_update_status == :success
end
def mirror_last_update_failed?
mirror_last_update_status == :failed
end
def mirror_ever_updated_successfully?
mirror_updated? && self.mirror_last_successful_update_at
end
def has_remote_mirror?
remote_mirrors.enabled.exists?
end
def updating_remote_mirror?
remote_mirrors.enabled.started.exists?
end
def update_remote_mirrors
remote_mirrors.each(&:sync)
end
def mark_stuck_remote_mirrors_as_failed!
remote_mirrors.stuck.update_all(
update_status: :failed,
last_error: 'The remote mirror took to long to complete.',
last_update_at: Time.now
)
end
def fetch_mirror
return unless mirror?
repository.fetch_upstream(self.import_url)
end
def shared_runners_available?
......@@ -124,6 +227,150 @@ module EE
.order(order % quoted_values) # `order` cannot escape for us!
end
def cache_has_external_issue_tracker
super unless ::Gitlab::Geo.secondary?
end
def cache_has_external_wiki
super unless ::Gitlab::Geo.secondary?
end
def execute_hooks(data, hooks_scope = :push_hooks)
super
if group
group.hooks.send(hooks_scope).each do |hook|
hook.async_execute(data, hooks_scope.to_s)
end
end
end
# No need to have a Kerberos Web url. Kerberos URL will be used only to
# clone
def kerberos_url_to_repo
"#{::Gitlab.config.build_gitlab_kerberos_url + ::Gitlab::Application.routes.url_helpers.namespace_project_path(self.namespace, self)}.git"
end
def group_ldap_synced?
if group
group.ldap_synced?
else
false
end
end
def reference_issue_tracker?
default_issues_tracker? || jira_tracker_active?
end
def approver_ids=(value)
value.split(",").map(&:strip).each do |user_id|
approvers.find_or_create_by(user_id: user_id, target_id: id)
end
end
def approver_group_ids=(value)
value.split(",").map(&:strip).each do |group_id|
approver_groups.find_or_initialize_by(group_id: group_id, target_id: id)
end
end
def find_path_lock(path, exact_match: false, downstream: false)
@path_lock_finder ||= ::Gitlab::PathLocksFinder.new(self)
@path_lock_finder.find(path, exact_match: exact_match, downstream: downstream)
end
def merge_method
if self.merge_requests_ff_only_enabled
:ff
elsif self.merge_requests_rebase_enabled
:rebase_merge
else
:merge
end
end
def merge_method=(method)
case method.to_s
when "ff"
self.merge_requests_ff_only_enabled = true
self.merge_requests_rebase_enabled = true
when "rebase_merge"
self.merge_requests_ff_only_enabled = false
self.merge_requests_rebase_enabled = true
when "merge"
self.merge_requests_ff_only_enabled = false
self.merge_requests_rebase_enabled = false
end
end
def ff_merge_must_be_possible?
self.merge_requests_ff_only_enabled || self.merge_requests_rebase_enabled
end
def import_url_updated?
# check if import_url has been updated and it's not just the first assignment
import_url_changed? && changes['import_url'].first
end
def remove_mirror_repository_reference
repository.remove_remote(Repository::MIRROR_REMOTE)
end
def import_url_availability
if remote_mirrors.find_by(url: import_url)
errors.add(:import_url, 'is already in use by a remote mirror')
end
end
def mark_remote_mirrors_for_removal
remote_mirrors.each(&:mark_for_delete_if_blank_url)
end
def change_repository_storage(new_repository_storage_key)
return if repository_read_only?
return if repository_storage == new_repository_storage_key
raise ArgumentError unless ::Gitlab.config.repositories.storages.keys.include?(new_repository_storage_key)
run_after_commit { ProjectUpdateRepositoryStorageWorker.perform_async(id, new_repository_storage_key) }
self.repository_read_only = true
end
def repository_and_lfs_size
statistics.total_repository_size
end
def above_size_limit?
return false unless size_limit_enabled?
repository_and_lfs_size > actual_size_limit
end
def size_to_remove
repository_and_lfs_size - actual_size_limit
end
def actual_size_limit
return namespace.actual_size_limit if repository_size_limit.nil?
repository_size_limit
end
def size_limit_enabled?
actual_size_limit != 0
end
def changes_will_exceed_size_limit?(size_in_bytes)
size_limit_enabled? &&
(size_in_bytes > actual_size_limit ||
size_in_bytes + repository_and_lfs_size > actual_size_limit)
end
def remove_import_data
super unless mirror?
end
private
def licensed_feature_available?(feature)
......
module EE
module Project
module ImportStatusStateMachine
extend ActiveSupport::Concern
included do
state_machine :import_status, initial: :none do
before_transition [:none, :finished, :failed] => :scheduled do |project, _|
project.mirror_data&.last_update_scheduled_at = Time.now
end
before_transition scheduled: :started do |project, _|
project.mirror_data&.last_update_started_at = Time.now
end
before_transition scheduled: :failed do |project, _|
if project.mirror?
timestamp = Time.now
project.mirror_last_update_at = timestamp
project.mirror_data.next_execution_timestamp = timestamp
end
end
after_transition [:scheduled, :started] => [:finished, :failed] do |project, _|
::Gitlab::Mirror.decrement_capacity(project.id) if project.mirror?
end
before_transition started: :failed do |project, _|
if project.mirror?
project.mirror_last_update_at = Time.now
mirror_data = project.mirror_data
mirror_data.increment_retry_count!
mirror_data.set_next_execution_timestamp!
end
end
before_transition started: :finished do |project, _|
if project.mirror?
timestamp = Time.now
project.mirror_last_update_at = timestamp
project.mirror_last_successful_update_at = timestamp
mirror_data = project.mirror_data
mirror_data.reset_retry_count!
mirror_data.set_next_execution_timestamp!
end
if current_application_settings.elasticsearch_indexing?
ElasticCommitIndexerWorker.perform_async(project.id)
end
end
after_transition [:finished, :failed] => [:scheduled, :started] do |project, _|
::Gitlab::Mirror.increment_capacity(project.id) if project.mirror?
end
end
end
end
end
end
......@@ -56,6 +56,27 @@ module EE
admin? || auditor?
end
def access_level
if auditor?
:auditor
else
super
end
end
def access_level=(new_level)
new_level = new_level.to_s
return unless %w(admin auditor regular).include?(new_level)
self.admin = (new_level == 'admin')
self.auditor = (new_level == 'auditor')
end
# Does the user have access to all private groups & projects?
def has_full_private_access?
admin_or_auditor?
end
def remember_me!
return if ::Gitlab::Geo.secondary?
super
......
This diff is collapsed.
......@@ -27,6 +27,13 @@ class ProjectFeature < ActiveRecord::Base
"#{feature}_access_level".to_sym
end
def quoted_access_level_column(feature)
attribute = connection.quote_column_name(access_level_attribute(feature))
table = connection.quote_table_name(table_name)
"#{table}.#{attribute}"
end
end
# Default scopes force us to unscope here since a service may need to check
......
......@@ -1003,8 +1003,6 @@ class User < ActiveRecord::Base
def access_level
if admin?
:admin
elsif auditor?
:auditor
else
:regular
end
......@@ -1012,10 +1010,14 @@ class User < ActiveRecord::Base
def access_level=(new_level)
new_level = new_level.to_s
return unless %w(admin auditor regular).include?(new_level)
return unless %w(admin regular).include?(new_level)
self.admin = (new_level == 'admin')
self.auditor = (new_level == 'auditor')
end
# Does the user have access to all private groups & projects?
def has_full_private_access?
admin?
end
def update_two_factor_requirement
......
---
title: Fix broken time sync leeway with Geo
merge_request:
author:
---
title: Refactor ProjectsFinder#init_collection to produce more efficient queries for
retrieving projects
merge_request:
author:
......@@ -82,7 +82,7 @@ OpenSSH 7.5 for CentOS 6 and 7:
```
sudo su -
cd /tmp
curl -O https://mirrors.evowise.com/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
curl --remote-name https://mirrors.evowise.com/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
tar xzvf openssh-7.5p1.tar.gz
yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel
```
......
......@@ -41,7 +41,7 @@ module Gitlab
encoded_message,
secret,
true,
{ iat_leeway: IAT_LEEWAY, verify_iat: true, algorithm: 'HS256' }
{ leeway: IAT_LEEWAY, verify_iat: true, algorithm: 'HS256' }
)
message = decoded.first
......
......@@ -13,18 +13,8 @@ module Gitlab
scope :public_and_internal_only, -> { where(visibility_level: [PUBLIC, INTERNAL] ) }
scope :non_public_only, -> { where.not(visibility_level: PUBLIC) }
scope :public_to_user, -> (user) do
if user
if user.admin_or_auditor?
all
elsif !user.external?
public_and_internal_only
else
public_only
end
else
public_only
end
scope :public_to_user, -> (user = nil) do
where(visibility_level: VisibilityLevel.levels_for_user(user))
end
end
......@@ -35,6 +25,18 @@ module Gitlab
class << self
delegate :values, to: :options
def levels_for_user(user = nil)
return [PUBLIC] unless user
if user.has_full_private_access?
[PRIVATE, INTERNAL, PUBLIC]
elsif user.external?
[PUBLIC]
else
[INTERNAL, PUBLIC]
end
end
def string_values
string_options.keys
end
......
......@@ -176,7 +176,9 @@ describe ProjectsController do
context 'project repo over limit' do
before do
allow_any_instance_of(Project).to receive(:above_size_limit?).and_return(true)
allow_any_instance_of(EE::Project)
.to receive(:above_size_limit?).and_return(true)
project.team << [user, :master]
end
......
require 'spec_helper'
describe Gitlab::VisibilityLevel, lib: true do # rubocop:disable RSpec/FilePath
describe '.levels_for_user' do
it 'returns all levels for an auditor' do
user = build(:user, :auditor)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::PRIVATE,
Gitlab::VisibilityLevel::INTERNAL,
Gitlab::VisibilityLevel::PUBLIC])
end
end
end
......@@ -27,10 +27,16 @@ describe Gitlab::Geo::JwtRequestDecoder do
expect(described_class.new(data).decode).to be_nil
end
it 'successfully decodes when clocks are off by IAT leeway' do
subject
Timecop.travel(30.seconds.ago) { expect(subject.decode).to eq(data) }
end
it 'returns nil when clocks are not in sync' do
allow(JWT).to receive(:decode).and_raise(JWT::InvalidIatError)
subject
expect(subject.decode).to be_nil
Timecop.travel(2.minutes.ago) { expect(subject.decode).to be_nil }
end
it 'raises invalid decryption key error' do
......
......@@ -18,4 +18,35 @@ describe Gitlab::VisibilityLevel, lib: true do
expect(described_class.level_value(100)).to eq(Gitlab::VisibilityLevel::PRIVATE)
end
end
describe '.levels_for_user' do
it 'returns all levels for an admin' do
user = build(:user, :admin)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::PRIVATE,
Gitlab::VisibilityLevel::INTERNAL,
Gitlab::VisibilityLevel::PUBLIC])
end
it 'returns INTERNAL and PUBLIC for internal users' do
user = build(:user)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::INTERNAL,
Gitlab::VisibilityLevel::PUBLIC])
end
it 'returns PUBLIC for external users' do
user = build(:user, :external)
expect(described_class.levels_for_user(user))
.to eq([Gitlab::VisibilityLevel::PUBLIC])
end
it 'returns PUBLIC when no user is given' do
expect(described_class.levels_for_user)
.to eq([Gitlab::VisibilityLevel::PUBLIC])
end
end
end
require 'spec_helper'
describe EE::User, models: true do
describe '#access_level=' do
let(:user) { build(:user) }
before do
# `auditor?` returns true only when the user is an auditor _and_ the auditor license
# add-on is present. We aren't testing this here, so we can assume that the add-on exists.
allow_any_instance_of(License).to receive(:feature_available?).with(:auditor_user) { true }
end
it "does not set 'auditor' for an invalid access level" do
user.access_level = :invalid_access_level
expect(user.auditor).to be false
end
it "does not set 'auditor' for admin level" do
user.access_level = :admin
expect(user.auditor).to be false
end
it "assigns the 'auditor' access level" do
user.access_level = :auditor
expect(user.access_level).to eq(:auditor)
expect(user.admin).to be false
expect(user.auditor).to be true
end
it "assigns the 'auditor' access level" do
user.access_level = :regular
expect(user.access_level).to eq(:regular)
expect(user.admin).to be false
expect(user.auditor).to be false
end
it "clears the 'admin' access level when a user is made an auditor" do
user.access_level = :admin
user.access_level = :auditor
expect(user.access_level).to eq(:auditor)
expect(user.admin).to be false
expect(user.auditor).to be true
end
it "clears the 'auditor' access level when a user is made an admin" do
user.access_level = :auditor
user.access_level = :admin
expect(user.access_level).to eq(:admin)
expect(user.admin).to be true
expect(user.auditor).to be false
end
it "doesn't clear existing 'auditor' access levels when an invalid access level is passed in" do
user.access_level = :auditor
user.access_level = :invalid_access_level
expect(user.access_level).to eq(:auditor)
expect(user.admin).to be false
expect(user.auditor).to be true
end
end
describe '#has_full_private_access?' do
it 'returns true for auditor user' do
user = build(:user, :auditor)
expect(user.has_full_private_access?).to be_truthy
end
end
end
......@@ -4,6 +4,18 @@ describe ProjectFeature do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
describe '.quoted_access_level_column' do
it 'returns the table name and quoted column name for a feature' do
expected = if Gitlab::Database.postgresql?
'"project_features"."issues_access_level"'
else
'`project_features`.`issues_access_level`'
end
expect(described_class.quoted_access_level_column(:issues)).to eq(expected)
end
end
describe '#feature_available?' do
let(:features) { %w(issues wiki builds merge_requests snippets repository) }
......
......@@ -2552,4 +2552,36 @@ describe Project, models: true do
expect(project.last_repository_updated_at.to_i).to eq(project.created_at.to_i)
end
end
describe '.public_or_visible_to_user' do
let!(:user) { create(:user) }
let!(:private_project) do
create(:empty_project, :private, creator: user, namespace: user.namespace)
end
let!(:public_project) { create(:empty_project, :public) }
context 'with a user' do
let(:projects) do
Project.all.public_or_visible_to_user(user)
end
it 'includes projects the user has access to' do
expect(projects).to include(private_project)
end
it 'includes projects the user can see' do
expect(projects).to include(public_project)
end
end
context 'without a user' do
it 'only includes public projects' do
projects = Project.all.public_or_visible_to_user
expect(projects).to eq([public_project])
end
end
end
end
......@@ -1737,18 +1737,11 @@ describe User, models: true do
describe '#access_level=' do
let(:user) { build(:user) }
before do
# `auditor?` returns true only when the user is an auditor _and_ the auditor license
# add-on is present. We aren't testing this here, so we can assume that the add-on exists.
allow_any_instance_of(License).to receive(:feature_available?).with(:auditor_user) { true }
end
it 'does nothing for an invalid access level' do
user.access_level = :invalid_access_level
expect(user.access_level).to eq(:regular)
expect(user.admin).to be false
expect(user.auditor).to be false
end
it "assigns the 'admin' access level" do
......@@ -1756,41 +1749,6 @@ describe User, models: true do
expect(user.access_level).to eq(:admin)
expect(user.admin).to be true
expect(user.auditor).to be false
end
it "assigns the 'auditor' access level" do
user.access_level = :auditor
expect(user.access_level).to eq(:auditor)
expect(user.admin).to be false
expect(user.auditor).to be true
end
it "assigns the 'auditor' access level" do
user.access_level = :regular
expect(user.access_level).to eq(:regular)
expect(user.admin).to be false
expect(user.auditor).to be false
end
it "clears the 'admin' access level when a user is made an auditor" do
user.access_level = :admin
user.access_level = :auditor
expect(user.access_level).to eq(:auditor)
expect(user.admin).to be false
expect(user.auditor).to be true
end
it "clears the 'auditor' access level when a user is made an admin" do
user.access_level = :auditor
user.access_level = :admin
expect(user.access_level).to eq(:admin)
expect(user.admin).to be true
expect(user.auditor).to be false
end
it "doesn't clear existing access levels when an invalid access level is passed in" do
......@@ -1799,7 +1757,6 @@ describe User, models: true do
expect(user.access_level).to eq(:admin)
expect(user.admin).to be true
expect(user.auditor).to be false
end
it "accepts string values in addition to symbols" do
......@@ -1807,7 +1764,20 @@ describe User, models: true do
expect(user.access_level).to eq(:admin)
expect(user.admin).to be true
expect(user.auditor).to be false
end
end
describe '#has_full_private_access?' do
it 'returns false for regular user' do
user = build(:user)
expect(user.has_full_private_access?).to be_falsy
end
it 'returns true for admin user' do
user = build(:user, :admin)
expect(user.has_full_private_access?).to be_truthy
end
end
......
......@@ -768,7 +768,8 @@ describe 'Git HTTP requests', lib: true do
end
it 'responds with status 403 Forbidden' do
allow_any_instance_of(Project).to receive(:above_size_limit?).and_return(true)
allow_any_instance_of(EE::Project)
.to receive(:above_size_limit?).and_return(true)
upload(path, env) do |response|
expect(response).to have_http_status(:forbidden)
......
......@@ -710,7 +710,7 @@ describe 'Git LFS API and storage' do
context 'and project is above the limit' do
let(:update_lfs_permissions) do
allow_any_instance_of(Project).to receive_messages(
allow_any_instance_of(EE::Project).to receive_messages(
repository_and_lfs_size: 100.megabytes,
actual_size_limit: 99.megabytes)
end
......@@ -726,7 +726,7 @@ describe 'Git LFS API and storage' do
context 'and project will go over the limit' do
let(:update_lfs_permissions) do
allow_any_instance_of(Project).to receive_messages(
allow_any_instance_of(EE::Project).to receive_messages(
repository_and_lfs_size: 200.megabytes,
actual_size_limit: 300.megabytes)
end
......@@ -982,7 +982,10 @@ describe 'Git LFS API and storage' do
context 'and project has limit enabled but will stay under the limit' do
before do
allow_any_instance_of(Project).to receive_messages(actual_size_limit: 200, size_limit_enabled?: true)
allow_any_instance_of(EE::Project).to receive_messages(
actual_size_limit: 200,
size_limit_enabled?: true)
put_finalize
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment