spec_helper.rb 8.2 KB
Newer Older
1 2
require './spec/simplecov_env'
SimpleCovEnv.start!
3

4
ENV["RAILS_ENV"] = 'test'
5
ENV["IN_MEMORY_APPLICATION_SETTINGS"] = 'true'
6

7
require File.expand_path("../../config/environment", __FILE__)
R
Robert Speicher 已提交
8
require 'rspec/rails'
R
Robert Speicher 已提交
9
require 'shoulda/matchers'
K
Kamil Trzcinski 已提交
10
require 'rspec/retry'
11
require 'rspec-parameterized'
K
Kamil Trzcinski 已提交
12

13
rspec_profiling_is_configured =
14
  ENV['RSPEC_PROFILING_POSTGRES_URL'].present? ||
15 16
  ENV['RSPEC_PROFILING']
branch_can_be_profiled =
17 18 19
  ENV['GITLAB_DATABASE'] == 'postgresql' &&
  (ENV['CI_COMMIT_REF_NAME'] == 'master' ||
    ENV['CI_COMMIT_REF_NAME'] =~ /rspec-profile/)
20 21

if rspec_profiling_is_configured && (!ENV.key?('CI') || branch_can_be_profiled)
22 23 24
  require 'rspec_profiling/rspec'
end

25
if ENV['CI'] && !ENV['NO_KNAPSACK']
26 27 28
  require 'knapsack'
  Knapsack::Adapters::RSpecAdapter.bind
end
R
Robert Speicher 已提交
29

30 31 32
# require rainbow gem String monkeypatch, so we can test SystemChecks
require 'rainbow/ext/string'

R
Robert Speicher 已提交
33 34
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
35 36 37 38
# Requires helpers, and shared contexts/examples first since they're used in other support files
Dir[Rails.root.join("spec/support/helpers/*.rb")].each { |f| require f }
Dir[Rails.root.join("spec/support/shared_contexts/*.rb")].each { |f| require f }
Dir[Rails.root.join("spec/support/shared_examples/*.rb")].each { |f| require f }
39
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
R
Robert Speicher 已提交
40 41

RSpec.configure do |config|
J
Jeroen van Baarsen 已提交
42 43
  config.use_transactional_fixtures = false
  config.use_instantiated_fixtures  = false
R
Robert Speicher 已提交
44

K
Kamil Trzcinski 已提交
45 46 47
  config.verbose_retry = true
  config.display_try_failure_messages = true

48
  config.infer_spec_type_from_file_location!
49

50 51 52 53 54 55 56 57 58 59
  config.define_derived_metadata(file_path: %r{/spec/}) do |metadata|
    location = metadata[:location]

    metadata[:api] = true if location =~ %r{/spec/requests/api/}

    # do not overwrite type if it's already set
    next if metadata.key?(:type)

    match = location.match(%r{/spec/([^/]+)/})
    metadata[:type] = match[1].singularize.to_sym if match
60 61
  end

62 63 64 65 66 67 68 69 70 71
  config.include ActiveJob::TestHelper
  config.include ActiveSupport::Testing::TimeHelpers
  config.include CycleAnalyticsHelpers
  config.include ExpectOffense
  config.include FactoryBot::Syntax::Methods
  config.include FixtureHelpers
  config.include GitlabRoutingHelper
  config.include StubFeatureFlags
  config.include StubGitlabCalls
  config.include StubGitlabData
72
  config.include ExpectNextInstanceOf
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
  config.include TestEnv
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::IntegrationHelpers, type: :feature
  config.include LoginHelpers, type: :feature
  config.include SearchHelpers, type: :feature
  config.include EmailHelpers, :mailer, type: :mailer
  config.include Warden::Test::Helpers, type: :request
  config.include Gitlab::Routing, type: :routing
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include ApiHelpers, :api
  config.include CookieHelper, :js
  config.include InputHelper, :js
  config.include SelectionHelper, :js
  config.include InspectRequests, :js
  config.include WaitForRequests, :js
  config.include LiveDebugger, :js
  config.include MigrationsHelpers, :migration
90
  config.include RedisHelpers
L
Lin Jen-Shin 已提交
91
  config.include Rails.application.routes.url_helpers, type: :routing
R
Robert Speicher 已提交
92

93 94 95
  if ENV['CI']
    # This includes the first try, i.e. tests will be run 4 times before failing.
    config.default_retry_count = 4
96 97 98 99
    config.reporter.register_listener(
      RspecFlaky::Listener.new,
      :example_passed,
      :dump_summary)
100 101
  end

R
Robert Speicher 已提交
102
  config.before(:suite) do
R
Rémy Coutable 已提交
103
    Timecop.safe_mode = true
104
    TestEnv.init
R
Robert Speicher 已提交
105
  end
106

107 108 109 110
  config.after(:all) do
    TestEnv.clean_test_path
  end

111
  config.before(:example) do
112 113
    # Enable all features by default for testing
    allow(Feature).to receive(:enabled?) { true }
114 115
  end

116 117 118 119 120 121 122 123 124
  config.before(:example, :request_store) do
    RequestStore.begin!
  end

  config.after(:example, :request_store) do
    RequestStore.end!
    RequestStore.clear!
  end

K
Kamil Trzciński 已提交
125 126 127 128
  config.after(:example) do
    Fog.unmock! if Fog.mock?
  end

129 130 131 132
  config.before(:example, :mailer) do
    reset_delivered_emails!
  end

133 134 135 136 137 138 139
  config.before(:example, :prometheus) do
    matching_files = File.join(::Prometheus::Client.configuration.multiprocess_files_dir, "*.db")
    Dir[matching_files].map { |filename| File.delete(filename) if File.file?(filename) }

    Gitlab::Metrics.reset_registry!
  end

140
  config.around(:each, :use_clean_rails_memory_store_caching) do |example|
141
    caching_store = Rails.cache
142 143
    Rails.cache = ActiveSupport::Cache::MemoryStore.new

144
    example.run
145

146 147
    Rails.cache = caching_store
  end
148

149
  config.around(:each, :clean_gitlab_redis_cache) do |example|
150
    redis_cache_cleanup!
151 152 153

    example.run

154
    redis_cache_cleanup!
155 156 157
  end

  config.around(:each, :clean_gitlab_redis_shared_state) do |example|
158
    redis_shared_state_cleanup!
159

160
    example.run
161

162 163 164 165 166 167 168 169 170
    redis_shared_state_cleanup!
  end

  config.around(:each, :clean_gitlab_redis_queues) do |example|
    redis_queues_cleanup!

    example.run

    redis_queues_cleanup!
171
  end
172

173 174 175 176 177 178 179 180 181 182 183
  config.around(:each, :use_clean_rails_memory_store_fragment_caching) do |example|
    caching_store = ActionController::Base.cache_store
    ActionController::Base.cache_store = ActiveSupport::Cache::MemoryStore.new
    ActionController::Base.perform_caching = true

    example.run

    ActionController::Base.perform_caching = false
    ActionController::Base.cache_store = caching_store
  end

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  # The :each scope runs "inside" the example, so this hook ensures the DB is in the
  # correct state before any examples' before hooks are called. This prevents a
  # problem where `ScheduleIssuesClosedAtTypeChange` (or any migration that depends
  # on background migrations being run inline during test setup) can be broken by
  # altering Sidekiq behavior in an unrelated spec like so:
  #
  # around do |example|
  #   Sidekiq::Testing.fake! do
  #     example.run
  #   end
  # end
  config.before(:context, :migration) do
    schema_migrate_down!
  end

  # Each example may call `migrate!`, so we must ensure we are migrated down every time
200
  config.before(:each, :migration) do
201
    schema_migrate_down!
202 203
  end

204
  config.after(:context, :migration) do
205
    schema_migrate_up!
206
  end
207

208
  config.around(:each, :nested_groups) do |example|
209
    example.run if Group.supports_nested_groups?
210 211 212 213 214
  end

  config.around(:each, :postgresql) do |example|
    example.run if Gitlab::Database.postgresql?
  end
215

216 217 218 219
  config.around(:each, :mysql) do |example|
    example.run if Gitlab::Database.mysql?
  end

220 221 222 223 224 225 226
  # This makes sure the `ApplicationController#can?` method is stubbed with the
  # original implementation for all view specs.
  config.before(:each, type: :view) do
    allow(view).to receive(:can?) do |*args|
      Ability.allowed?(*args)
    end
  end
R
Rob Watson 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

  config.before(:each, :http_pages_enabled) do |_|
    allow(Gitlab.config.pages).to receive(:external_http).and_return(['1.1.1.1:80'])
  end

  config.before(:each, :https_pages_enabled) do |_|
    allow(Gitlab.config.pages).to receive(:external_https).and_return(['1.1.1.1:443'])
  end

  config.before(:each, :http_pages_disabled) do |_|
    allow(Gitlab.config.pages).to receive(:external_http).and_return(false)
  end

  config.before(:each, :https_pages_disabled) do |_|
    allow(Gitlab.config.pages).to receive(:external_https).and_return(false)
  end
A
Andrew8xx8 已提交
243
end
244

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
# add simpler way to match asset paths containing digest strings
RSpec::Matchers.define :match_asset_path do |expected|
  match do |actual|
    path = Regexp.escape(expected)
    extname = Regexp.escape(File.extname(expected))
    digest_regex = Regexp.new(path.sub(extname, "(?:-\\h+)?#{extname}") << '$')
    digest_regex =~ actual
  end

  failure_message do |actual|
    "expected that #{actual} would include an asset path for #{expected}"
  end

  failure_message_when_negated do |actual|
    "expected that #{actual} would not include an asset path for  #{expected}"
  end
end

263
FactoryBot::SyntaxRunner.class_eval do
K
Kamil Trzcinski 已提交
264 265 266
  include RSpec::Mocks::ExampleMethods
end

267
ActiveRecord::Migration.maintain_test_schema!
268 269 270 271 272 273 274

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end
275 276 277

# Prevent Rugged from picking up local developer gitconfig.
Rugged::Settings['search_path_global'] = Rails.root.join('tmp/tests').to_s