summaryrefslogtreecommitdiffstats
path: root/spec/rails_helper.rb
blob: 38aa711089e3258c030c3e4f0d06a3779c7bc25d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# frozen_string_literal: true

ENV['RAILS_ENV'] ||= 'test'

unless ENV['DISABLE_SIMPLECOV'] == 'true'
  require 'simplecov'

  SimpleCov.start 'rails' do
    if ENV['CI']
      require 'simplecov-lcov'
      formatter SimpleCov::Formatter::LcovFormatter
      formatter.config.report_with_single_file = true
    else
      formatter SimpleCov::Formatter::HTMLFormatter
    end

    enable_coverage :branch

    add_filter 'lib/linter'

    add_group 'Libraries', 'lib'
    add_group 'Policies', 'app/policies'
    add_group 'Presenters', 'app/presenters'
    add_group 'Serializers', 'app/serializers'
    add_group 'Services', 'app/services'
    add_group 'Validators', 'app/validators'
  end
end

# This needs to be defined before Rails is initialized
STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020')
ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}"

require File.expand_path('../config/environment', __dir__)

abort('The Rails environment is running in production mode!') if Rails.env.production?

require 'spec_helper'
require 'rspec/rails'
require 'webmock/rspec'
require 'paperclip/matchers'
require 'capybara/rspec'
require 'chewy/rspec'
require 'email_spec/rspec'
require 'test_prof/recipes/rspec/before_all'

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!
WebMock.disable_net_connect!(
  allow_localhost: true,
  allow: Chewy.settings[:host]
)
Sidekiq.logger = nil

DatabaseCleaner.strategy = [:deletion]

Devise::Test::ControllerHelpers.module_eval do
  alias_method :original_sign_in, :sign_in

  def sign_in(resource, _deprecated = nil, scope: nil)
    original_sign_in(resource, scope: scope)

    SessionActivation.deactivate warden.cookies.signed['_session_id']

    warden.cookies.signed['_session_id'] = {
      value: resource.activate_session(warden.request),
      expires: 1.year.from_now,
      httponly: true,
    }
  end
end

RSpec.configure do |config|
  # By default, skip specs that need full JS browser
  config.filter_run_excluding :js

  # By default, skip specs that need elastic search server
  config.filter_run_excluding :search

  # By default, skip specs that need the streaming server
  config.filter_run_excluding :streaming

  config.fixture_paths = [
    Rails.root.join('spec', 'fixtures'),
  ]
  config.use_transactional_fixtures = true
  config.order = 'random'
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!

  # Set type to `cli` for all CLI specs
  config.define_derived_metadata(file_path: Regexp.new('spec/lib/mastodon/cli')) do |metadata|
    metadata[:type] = :cli
  end

  # Set `search` metadata true for all specs in spec/search/
  config.define_derived_metadata(file_path: Regexp.new('spec/search/*')) do |metadata|
    metadata[:search] = true
  end

  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :helper
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Devise::Test::IntegrationHelpers, type: :system
  config.include Devise::Test::IntegrationHelpers, type: :request
  config.include ActionMailer::TestHelper
  config.include Paperclip::Shoulda::Matchers
  config.include ActiveSupport::Testing::TimeHelpers
  config.include Chewy::Rspec::Helpers
  config.include Redisable
  config.include ThreadingHelpers
  config.include SignedRequestHelpers, type: :request
  config.include CommandLineHelpers, type: :cli

  config.around(:each, use_transactional_tests: false) do |example|
    self.use_transactional_tests = false
    example.run
    self.use_transactional_tests = true
  end

  config.around do |example|
    if example.metadata[:sidekiq_inline] == true
      Sidekiq::Testing.inline!
    else
      Sidekiq::Testing.fake!
    end
    example.run
  end

  config.before :each, type: :cli do
    stub_reset_connection_pools
  end

  config.before do |example|
    allow(Resolv::DNS).to receive(:open).and_raise('Real DNS queries are disabled, stub Resolv::DNS as needed') unless example.metadata[:type] == :system
  end

  config.before do |example|
    unless example.metadata[:paperclip_processing]
      allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance
    end
  end

  config.after do
    Rails.cache.clear
    redis.del(redis.keys)
  end

  # Assign types based on dir name for non-inferred types
  config.define_derived_metadata(file_path: %r{/spec/}) do |metadata|
    unless metadata.key?(:type)
      match = metadata[:location].match(%r{/spec/([^/]+)/})
      metadata[:type] = match[1].singularize.to_sym
    end
  end
end

RSpec::Sidekiq.configure do |config|
  config.warn_when_jobs_not_processed_by_sidekiq = false
end

RSpec::Matchers.define_negated_matcher :not_change, :change
RSpec::Matchers.define_negated_matcher :not_include, :include

def request_fixture(name)
  Rails.root.join('spec', 'fixtures', 'requests', name).read
end

def attachment_fixture(name)
  Rails.root.join('spec', 'fixtures', 'files', name).open
end

def stub_reset_connection_pools
  # TODO: Is there a better way to correctly run specs without stubbing this?
  # (Avoids reset_connection_pools! in test env)
  allow(ActiveRecord::Base).to receive(:establish_connection)
  allow(RedisConfiguration).to receive(:establish_pool)
end