# frozen_string_literal: true GIT_INITIAL_BRANCH_SUPPORTED = Gem::Version.new(`git --version`.match(/[\d\.]+/)[0]) >= Gem::Version.new("2.28.0") module Helpers extend ActiveSupport::Concern def self.next_seq @next_seq = (@next_seq || 0) + 1 end def log_in(fabricator = nil) user = Fabricate(fabricator || :user) log_in_user(user) user end def log_in_user(user) cookie_jar = ActionDispatch::Request.new(request.env).cookie_jar provider = Discourse.current_user_provider.new(request.env) provider.log_on_user(user, session, cookie_jar) provider end def log_out_user(provider) provider.log_off_user(session, cookies) end def fixture_file(filename) return "" if filename.blank? file_path = File.expand_path(Rails.root + "spec/fixtures/" + filename) File.read(file_path) end def build(*args) Fabricate.build(*args) end def create_topic(args = {}) args[:title] ||= "This is my title #{Helpers.next_seq}" user = args.delete(:user) || Fabricate(:user) guardian = Guardian.new(user) args[:category] = args[:category].id if args[:category].is_a?(Category) TopicCreator.create(user, guardian, args) end def create_post(args = {}) # Pretty much all the tests with `create_post` will fail without this # since allow_uncategorized_topics is now false by default SiteSetting.allow_uncategorized_topics = true unless args[:allow_uncategorized_topics] == false args[:title] ||= "This is my title #{Helpers.next_seq}" args[:raw] ||= "This is the raw body of my post, it is cool #{Helpers.next_seq}" args[:topic_id] = args[:topic].id if args[:topic] automated_group_refresh_required = args[:user].blank? user = args.delete(:user) || Fabricate(:user) Group.refresh_automatic_groups! if automated_group_refresh_required args[:category] = args[:category].id if args[:category].is_a?(Category) creator = PostCreator.new(user, args) post = creator.create raise StandardError.new(creator.errors.full_messages.join(" ")) if creator.errors.present? post end def stub_guardian(user) guardian = Guardian.new(user) yield(guardian) if block_given? Guardian.stubs(new: guardian).with(user, anything) end def wait_for(on_fail: nil, timeout: 1, &blk) i = 0 result = false while !result && i < timeout * 1000 result = blk.call i += 1 sleep 0.001 end on_fail&.call expect(result).to eq(true) end def email(email_name) fixture_file("emails/#{email_name}.eml") end def create_staff_only_tags(tag_names) create_limited_tags("Staff Tags", Group::AUTO_GROUPS[:staff], tag_names) end def create_limited_tags(tag_group_name, group_id, tag_names) tag_group = Fabricate(:tag_group, name: tag_group_name) TagGroupPermission.where( tag_group: tag_group, group_id: Group::AUTO_GROUPS[:everyone], permission_type: TagGroupPermission.permission_types[:full], ).update(permission_type: TagGroupPermission.permission_types[:readonly]) TagGroupPermission.create!( tag_group: tag_group, group_id: group_id, permission_type: TagGroupPermission.permission_types[:full], ) tag_names.each do |name| tag_group.tags << (Tag.where(name: name).first || Fabricate(:tag, name: name)) end end def create_hidden_tags(tag_names) tag_group = Fabricate(:tag_group, name: "Hidden Tags", permissions: { staff: :full }) tag_names.each do |name| tag_group.tags << (Tag.where(name: name).first || Fabricate(:tag, name: name)) end end def sorted_tag_names(tag_records) tag_records.map { |t| t.is_a?(String) ? t : t.name }.sort end def expect_same_tag_names(a, b) expect(sorted_tag_names(a)).to eq(sorted_tag_names(b)) end def capture_output(output_name) if ENV["RAILS_ENABLE_TEST_STDOUT"] yield return end previous_output = output_name == :stdout ? $stdout : $stderr io = StringIO.new output_name == :stdout ? $stdout = io : $stderr = io yield io.string ensure output_name == :stdout ? $stdout = previous_output : $stderr = previous_output end def capture_stdout(&block) capture_output(:stdout, &block) end def capture_stderr(&block) capture_output(:stderr, &block) end def set_subfolder(new_root) global_setting :relative_url_root, new_root old_root = ActionController::Base.config.relative_url_root ActionController::Base.config.relative_url_root = new_root Rails.application.routes.stubs(:relative_url_root).returns(new_root) before_next_spec { ActionController::Base.config.relative_url_root = old_root } if RSpec.current_example.metadata[:type] == :system Capybara.app.map("/") { run lambda { |env| [404, {}, [""]] } } Capybara.app.map(new_root) { run Rails.application } before_next_spec do Capybara.app.map(new_root) { run lambda { |env| [404, {}, [""]] } } Capybara.app.map("/") { run Rails.application } end end end def setup_git_repo(files) repo_dir = Dir.mktmpdir `cd #{repo_dir} && git init . #{"--initial-branch=main" if GIT_INITIAL_BRANCH_SUPPORTED}` `cd #{repo_dir} && git config user.email 'someone@cool.com'` `cd #{repo_dir} && git config user.name 'The Cool One'` `cd #{repo_dir} && git config commit.gpgsign 'false'` files.each do |name, data| FileUtils.mkdir_p(Pathname.new("#{repo_dir}/#{name}").dirname) File.write("#{repo_dir}/#{name}", data) `cd #{repo_dir} && git add #{name}` end `cd #{repo_dir} && git commit -am 'first commit'` repo_dir end def stub_const(target, const, value) old = target.const_get(const) target.send(:remove_const, const) target.const_set(const, value) yield ensure target.send(:remove_const, const) target.const_set(const, old) end def track_sql_queries queries = [] callback = ->(*, payload) do queries << payload.fetch(:sql) unless %w[CACHE SCHEMA].include?(payload.fetch(:name)) end ActiveSupport::Notifications.subscribed(callback, "sql.active_record") { yield } queries end def stub_ip_lookup(stub_addr, ips) Addrinfo .stubs(:getaddrinfo) .with { |addr, _| addr == stub_addr } .returns( ips.map { |ip| Addrinfo.new([IPAddr.new(ip).ipv6? ? "AF_INET6" : "AF_INET", 80, nil, ip]) }, ) end def with_search_indexer_enabled SearchIndexer.enable yield ensure SearchIndexer.disable end end