Commit d986aea3 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'upgrade_to_rails_4.1' into 'master'

Upgrade to rails 4.1
parents 9e924c70 18b1f171
...@@ -8,7 +8,7 @@ def linux_only(require_as) ...@@ -8,7 +8,7 @@ def linux_only(require_as)
RUBY_PLATFORM.include?('linux') && require_as RUBY_PLATFORM.include?('linux') && require_as
end end
gem "rails", "~> 4.0.0" gem "rails", "~> 4.1.0"
gem "protected_attributes" gem "protected_attributes"
gem 'rails-observers' gem 'rails-observers'
...@@ -207,7 +207,7 @@ group :development, :test do ...@@ -207,7 +207,7 @@ group :development, :test do
gem 'factory_girl_rails' gem 'factory_girl_rails'
# Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826) # Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
gem 'minitest', '~> 4.7.0' gem 'minitest', '~> 5.3.0'
# Generate Fake data # Generate Fake data
gem "ffaker" gem "ffaker"
...@@ -224,7 +224,7 @@ group :development, :test do ...@@ -224,7 +224,7 @@ group :development, :test do
# PhantomJS driver for Capybara # PhantomJS driver for Capybara
gem 'poltergeist', '~> 1.5.1' gem 'poltergeist', '~> 1.5.1'
gem 'jasmine', '2.0.0.rc5' gem 'jasmine', '2.0.2'
gem "spring", '1.1.1' gem "spring", '1.1.1'
gem "spring-commands-rspec", '1.0.1' gem "spring-commands-rspec", '1.0.1'
......
...@@ -2,37 +2,39 @@ GEM ...@@ -2,37 +2,39 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
ace-rails-ap (2.0.1) ace-rails-ap (2.0.1)
actionmailer (4.0.5) actionmailer (4.1.1)
actionpack (= 4.0.5) actionpack (= 4.1.1)
actionview (= 4.1.1)
mail (~> 2.5.4) mail (~> 2.5.4)
actionpack (4.0.5) actionpack (4.1.1)
activesupport (= 4.0.5) actionview (= 4.1.1)
builder (~> 3.1.0) activesupport (= 4.1.1)
erubis (~> 2.7.0)
rack (~> 1.5.2) rack (~> 1.5.2)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
activemodel (4.0.5) actionview (4.1.1)
activesupport (= 4.0.5) activesupport (= 4.1.1)
builder (~> 3.1.0) builder (~> 3.1)
activerecord (4.0.5) erubis (~> 2.7.0)
activemodel (= 4.0.5) activemodel (4.1.1)
activerecord-deprecated_finders (~> 1.0.2) activesupport (= 4.1.1)
activesupport (= 4.0.5) builder (~> 3.1)
arel (~> 4.0.0) activerecord (4.1.1)
activerecord-deprecated_finders (1.0.3) activemodel (= 4.1.1)
activesupport (4.0.5) activesupport (= 4.1.1)
arel (~> 5.0.0)
activesupport (4.1.1)
i18n (~> 0.6, >= 0.6.9) i18n (~> 0.6, >= 0.6.9)
minitest (~> 4.2) json (~> 1.7, >= 1.7.7)
multi_json (~> 1.3) minitest (~> 5.1)
thread_safe (~> 0.1) thread_safe (~> 0.1)
tzinfo (~> 0.3.37) tzinfo (~> 1.1)
acts-as-taggable-on (2.4.1) acts-as-taggable-on (2.4.1)
rails (>= 3, < 5) rails (>= 3, < 5)
addressable (2.3.5) addressable (2.3.5)
annotate (2.6.0) annotate (2.6.0)
activerecord (>= 2.3.0) activerecord (>= 2.3.0)
rake (>= 0.8.7) rake (>= 0.8.7)
arel (4.0.2) arel (5.0.1.20140414130214)
asciidoctor (0.1.4) asciidoctor (0.1.4)
awesome_print (1.2.0) awesome_print (1.2.0)
axiom-types (0.0.5) axiom-types (0.0.5)
...@@ -46,7 +48,7 @@ GEM ...@@ -46,7 +48,7 @@ GEM
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
bootstrap-sass (3.0.3.0) bootstrap-sass (3.0.3.0)
sass (~> 3.2) sass (~> 3.2)
builder (3.1.4) builder (3.2.2)
capybara (2.2.1) capybara (2.2.1)
mime-types (>= 1.16) mime-types (>= 1.16)
nokogiri (>= 1.3.3) nokogiri (>= 1.3.3)
...@@ -223,13 +225,13 @@ GEM ...@@ -223,13 +225,13 @@ GEM
guard-spinach (0.0.2) guard-spinach (0.0.2)
guard (>= 1.1) guard (>= 1.1)
spinach spinach
haml (4.0.4) haml (4.0.5)
tilt tilt
haml-rails (0.5.1) haml-rails (0.5.3)
actionpack (~> 4.0.0) actionpack (>= 4.0.1)
activesupport (~> 4.0.0) activesupport (>= 4.0.1)
haml (>= 3.1, < 5.0) haml (>= 3.1, < 5.0)
railties (~> 4.0.0) railties (>= 4.0.1)
hashie (2.0.5) hashie (2.0.5)
hike (1.2.3) hike (1.2.3)
hipchat (0.14.0) hipchat (0.14.0)
...@@ -242,12 +244,12 @@ GEM ...@@ -242,12 +244,12 @@ GEM
httpauth (0.2.0) httpauth (0.2.0)
i18n (0.6.9) i18n (0.6.9)
ice_nine (0.10.0) ice_nine (0.10.0)
jasmine (2.0.0.rc5) jasmine (2.0.2)
jasmine-core (~> 2.0.0.rc5) jasmine-core (~> 2.0.0)
phantomjs phantomjs
rack (>= 1.2.1) rack (>= 1.2.1)
rake rake
jasmine-core (2.0.0.rc5) jasmine-core (2.0.0)
jquery-atwho-rails (0.3.3) jquery-atwho-rails (0.3.3)
jquery-rails (3.1.0) jquery-rails (3.1.0)
railties (>= 3.0, < 5.0) railties (>= 3.0, < 5.0)
...@@ -282,11 +284,11 @@ GEM ...@@ -282,11 +284,11 @@ GEM
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
mini_portile (0.6.0) mini_portile (0.6.0)
minitest (4.7.5) minitest (5.3.4)
multi_json (1.10.1) multi_json (1.10.1)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (1.2.0) multipart-post (1.2.0)
mysql2 (0.3.11) mysql2 (0.3.16)
net-ldap (0.3.1) net-ldap (0.3.1)
net-scp (1.1.2) net-scp (1.1.2)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
...@@ -355,14 +357,16 @@ GEM ...@@ -355,14 +357,16 @@ GEM
rack rack
rack-test (0.6.2) rack-test (0.6.2)
rack (>= 1.0) rack (>= 1.0)
rails (4.0.5) rails (4.1.1)
actionmailer (= 4.0.5) actionmailer (= 4.1.1)
actionpack (= 4.0.5) actionpack (= 4.1.1)
activerecord (= 4.0.5) actionview (= 4.1.1)
activesupport (= 4.0.5) activemodel (= 4.1.1)
activerecord (= 4.1.1)
activesupport (= 4.1.1)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.0.5) railties (= 4.1.1)
sprockets-rails (~> 2.0.0) sprockets-rails (~> 2.0)
rails-observers (0.1.2) rails-observers (0.1.2)
activemodel (~> 4.0) activemodel (~> 4.0)
rails_best_practices (1.14.4) rails_best_practices (1.14.4)
...@@ -374,13 +378,13 @@ GEM ...@@ -374,13 +378,13 @@ GEM
i18n i18n
require_all require_all
ruby-progressbar ruby-progressbar
railties (4.0.5) railties (4.1.1)
actionpack (= 4.0.5) actionpack (= 4.1.1)
activesupport (= 4.0.5) activesupport (= 4.1.1)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
raindrops (0.12.0) raindrops (0.12.0)
rake (10.3.1) rake (10.3.2)
raphael-rails (2.1.2) raphael-rails (2.1.2)
rb-fsevent (0.9.3) rb-fsevent (0.9.3)
rb-inotify (0.9.2) rb-inotify (0.9.2)
...@@ -443,9 +447,9 @@ GEM ...@@ -443,9 +447,9 @@ GEM
sdoc (0.3.20) sdoc (0.3.20)
json (>= 1.1.3) json (>= 1.1.3)
rdoc (~> 3.10) rdoc (~> 3.10)
seed-fu (2.3.0) seed-fu (2.3.1)
activerecord (>= 3.1, < 4.1) activerecord (>= 3.1, < 4.2)
activesupport (>= 3.1, < 4.1) activesupport (>= 3.1, < 4.2)
select2-rails (3.5.2) select2-rails (3.5.2)
thor (~> 0.14) thor (~> 0.14)
settingslogic (2.0.9) settingslogic (2.0.9)
...@@ -491,7 +495,7 @@ GEM ...@@ -491,7 +495,7 @@ GEM
multi_json (~> 1.0) multi_json (~> 1.0)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.0.1) sprockets-rails (2.1.3)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
sprockets (~> 2.8) sprockets (~> 2.8)
...@@ -510,7 +514,7 @@ GEM ...@@ -510,7 +514,7 @@ GEM
eventmachine (>= 1.0.0) eventmachine (>= 1.0.0)
rack (>= 1.0.0) rack (>= 1.0.0)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.3) thread_safe (0.3.4)
tilt (1.4.1) tilt (1.4.1)
timers (1.1.0) timers (1.1.0)
tinder (1.9.3) tinder (1.9.3)
...@@ -532,7 +536,8 @@ GEM ...@@ -532,7 +536,8 @@ GEM
eventmachine (>= 0.12.8) eventmachine (>= 0.12.8)
http_parser.rb (~> 0.5.1) http_parser.rb (~> 0.5.1)
simple_oauth (~> 0.1.4) simple_oauth (~> 0.1.4)
tzinfo (0.3.39) tzinfo (1.2.0)
thread_safe (~> 0.1)
uglifier (2.3.2) uglifier (2.3.2)
execjs (>= 0.3.0) execjs (>= 0.3.0)
json (>= 1.8.0) json (>= 1.8.0)
...@@ -612,7 +617,7 @@ DEPENDENCIES ...@@ -612,7 +617,7 @@ DEPENDENCIES
haml-rails haml-rails
hipchat (~> 0.14.0) hipchat (~> 0.14.0)
httparty httparty
jasmine (= 2.0.0.rc5) jasmine (= 2.0.2)
jquery-atwho-rails (~> 0.3.3) jquery-atwho-rails (~> 0.3.3)
jquery-rails jquery-rails
jquery-scrollto-rails jquery-scrollto-rails
...@@ -621,7 +626,7 @@ DEPENDENCIES ...@@ -621,7 +626,7 @@ DEPENDENCIES
kaminari (~> 0.15.1) kaminari (~> 0.15.1)
launchy launchy
letter_opener letter_opener
minitest (~> 4.7.0) minitest (~> 5.3.0)
mysql2 mysql2
nprogress-rails nprogress-rails
omniauth (~> 1.1.3) omniauth (~> 1.1.3)
...@@ -637,7 +642,7 @@ DEPENDENCIES ...@@ -637,7 +642,7 @@ DEPENDENCIES
rack-attack rack-attack
rack-cors rack-cors
rack-mini-profiler rack-mini-profiler
rails (~> 4.0.0) rails (~> 4.1.0)
rails-observers rails-observers
rails_best_practices rails_best_practices
raphael-rails (~> 2.1.2) raphael-rails (~> 2.1.2)
......
...@@ -211,6 +211,6 @@ class ProjectsController < ApplicationController ...@@ -211,6 +211,6 @@ class ProjectsController < ApplicationController
end end
def sorted(users) def sorted(users)
users.uniq.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } } users.uniq.to_a.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
end end
end end
...@@ -14,7 +14,7 @@ class SnippetsController < ApplicationController ...@@ -14,7 +14,7 @@ class SnippetsController < ApplicationController
layout 'navless' layout 'navless'
def index def index
@snippets = Snippet.public.fresh.non_expired.page(params[:page]).per(20) @snippets = Snippet.are_public.fresh.non_expired.page(params[:page]).per(20)
end end
def user_index def user_index
...@@ -26,15 +26,15 @@ class SnippetsController < ApplicationController ...@@ -26,15 +26,15 @@ class SnippetsController < ApplicationController
if @user == current_user if @user == current_user
@snippets = case params[:scope] @snippets = case params[:scope]
when 'public' then when 'are_public' then
@snippets.public @snippets.are_public
when 'private' then when 'are_private' then
@snippets.private @snippets.are_private
else else
@snippets @snippets
end end
else else
@snippets = @snippets.public @snippets = @snippets.are_public
end end
@snippets = @snippets.page(params[:page]).per(20) @snippets = @snippets.page(params[:page]).per(20)
......
...@@ -34,8 +34,8 @@ class Snippet < ActiveRecord::Base ...@@ -34,8 +34,8 @@ class Snippet < ActiveRecord::Base
validates :content, presence: true validates :content, presence: true
# Scopes # Scopes
scope :public, -> { where(private: false) } scope :are_public, -> { where(private: false) }
scope :private, -> { where(private: true) } scope :are_private, -> { where(private: true) }
scope :fresh, -> { order("created_at DESC") } scope :fresh, -> { order("created_at DESC") }
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
......
...@@ -18,16 +18,16 @@ ...@@ -18,16 +18,16 @@
All All
%span.pull-right %span.pull-right
= @user.snippets.count = @user.snippets.count
= nav_tab :scope, 'private' do = nav_tab :scope, 'are_private' do
= link_to user_snippets_path(@user, scope: 'private') do = link_to user_snippets_path(@user, scope: 'are_private') do
Private Private
%span.pull-right %span.pull-right
= @user.snippets.private.count = @user.snippets.are_private.count
= nav_tab :scope, 'public' do = nav_tab :scope, 'are_public' do
= link_to user_snippets_path(@user, scope: 'public') do = link_to user_snippets_path(@user, scope: 'are_public') do
Public Public
%span.pull-right %span.pull-right
= @user.snippets.public.count = @user.snippets.are_public.count
.col-md-9.my-snippets .col-md-9.my-snippets
= render 'snippets' = render 'snippets'
......
...@@ -74,10 +74,6 @@ Gitlab::Application.configure do ...@@ -74,10 +74,6 @@ Gitlab::Application.configure do
# Send deprecation notices to registered listeners # Send deprecation notices to registered listeners
config.active_support.deprecation = :notify config.active_support.deprecation = :notify
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
# config.active_record.auto_explain_threshold_in_seconds = 0.5
config.action_mailer.delivery_method = :sendmail config.action_mailer.delivery_method = :sendmail
# Defaults to: # Defaults to:
# # config.action_mailer.sendmail_settings = { # # config.action_mailer.sendmail_settings = {
......
# This is a patch to address the issue in https://github.com/mbleigh/acts-as-taggable-on/issues/427 caused by
# https://github.com/rails/rails/commit/31a43ebc107fbd50e7e62567e5208a05909ec76c
# gem 'acts-as-taggable-on' has the fix included https://github.com/mbleigh/acts-as-taggable-on/commit/89bbed3864a9252276fb8dd7d535fce280454b90
# but not in the currently used version of gem ('2.4.1')
# With replacement of 'acts-as-taggable-on' gem this file will become obsolete
module ActsAsTaggableOn::Taggable
module Core
module ClassMethods
def tagged_with(tags, options = {})
tag_list = ActsAsTaggableOn::TagList.from(tags)
empty_result = where("1 = 0")
return empty_result if tag_list.empty?
joins = []
conditions = []
having = []
select_clause = []
context = options.delete(:on)
owned_by = options.delete(:owned_by)
alias_base_name = undecorated_table_name.gsub('.','_')
quote = ActsAsTaggableOn::Tag.using_postgresql? ? '"' : ''
if options.delete(:exclude)
if options.delete(:wild)
tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ? ESCAPE '!'", "%#{escape_like(t)}%"]) }.join(" OR ")
else
tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
end
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)})"
if owned_by
joins << "JOIN #{ActsAsTaggableOn::Tagging.table_name}" +
" ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{owned_by.id}" +
" AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s, nil)}"
end
elsif options.delete(:any)
# get tags, drop out if nothing returned (we need at least one)
tags = if options.delete(:wild)
ActsAsTaggableOn::Tag.named_like_any(tag_list)
else
ActsAsTaggableOn::Tag.named_any(tag_list)
end
return empty_result unless tags.length > 0
# setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123
# avoid ambiguous column name
taggings_context = context ? "_#{context}" : ''
taggings_alias = adjust_taggings_alias(
"#{alias_base_name[0..4]}#{taggings_context[0..6]}_taggings_#{sha_prefix(tags.map(&:name).join('_'))}"
)
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
# don't need to sanitize sql, map all ids and join with OR logic
conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ")
select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
if owned_by
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
end
joins << tagging_join
else
tags = ActsAsTaggableOn::Tag.named_any(tag_list)
return empty_result unless tags.length == tag_list.length
tags.each do |tag|
taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}")
tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}" +
" AND #{taggings_alias}.tag_id = #{tag.id}"
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
if owned_by
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
end
joins << tagging_join
end
end
taggings_alias, tags_alias = adjust_taggings_alias("#{alias_base_name}_taggings_group"), "#{alias_base_name}_tags_group"
if options.delete(:match_all)
joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
" ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
group = group_columns
having = "COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
end
select(select_clause) \
.joins(joins.join(" ")) \
.where(conditions.join(" AND ")) \
.group(group) \
.having(having) \
.order(options[:order]) \
.readonly(false)
end
end
end
end
# This is a patch to address the issue in https://github.com/pluginaweek/state_machine/issues/251
# where gem 'state_machine' was not working for Rails 4.1
module StateMachine
module Integrations
module ActiveModel
public :around_validation
end
end
end
...@@ -16,7 +16,8 @@ describe SubmoduleHelper do ...@@ -16,7 +16,8 @@ describe SubmoduleHelper do
end end
it 'should detect ssh on standard port' do it 'should detect ssh on standard port' do
Gitlab.config.gitlab.stub(ssh_port: 22) # set this just to be sure Gitlab.config.gitlab_shell.stub(ssh_port: 22) # set this just to be sure
Gitlab.config.gitlab_shell.stub(ssh_path_prefix: Settings.send(:build_gitlab_shell_ssh_path_prefix))
stub_url([ config.user, '@', config.host, ':gitlab-org/gitlab-ce.git' ].join('')) stub_url([ config.user, '@', config.host, ':gitlab-org/gitlab-ce.git' ].join(''))
submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ] submodule_links(submodule_item).should == [ project_path('gitlab-org/gitlab-ce'), project_tree_path('gitlab-org/gitlab-ce', 'hash') ]
end end
......
...@@ -59,7 +59,7 @@ describe SystemHook do ...@@ -59,7 +59,7 @@ describe SystemHook do
user = create(:user) user = create(:user)
project = create(:project) project = create(:project)
project.team << [user, :master] project.team << [user, :master]
project.users_projects.clear project.users_projects.destroy_all
WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once
end end
end 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