charkost/prosopite

False positive when used together with FactoryBot `create_list`?

Closed this issue · 2 comments

santib commented

Hi, seems like there is a false positive when used together with FactoryBot create_list. I'm not sure if the problem is in Prosopite codebase or somewhere else, but I'd like to hear others' thoughts.

I created a reproduction script:

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "rails", "~> 7.0.0"
  gem "sqlite3", "~> 1.6.4"
  gem "prosopite", "~> 1.3.3"
  gem "pg_query", "~> 4.2.3"
  gem "factory_bot_rails", "~> 6.2.0"
end

require "active_record/railtie"
require "active_storage/engine"
require "tmpdir"
require "minitest/autorun"

class TestApp < Rails::Application
  config.root = __dir__
  config.hosts << "example.org"
  config.eager_load = false
  config.session_store :cookie_store, key: "cookie_store_key"
  config.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  Rails.logger  = config.logger

  config.active_storage.service = :local
  config.active_storage.service_configurations = {
    local: {
      root: Dir.tmpdir,
      service: "Disk"
    }
  }
end

ENV["DATABASE_URL"] = "sqlite3::memory:"

Rails.application.config.after_initialize do
  Prosopite.rails_logger = true
  Prosopite.raise = true
end

Rails.application.initialize!

require ActiveStorage::Engine.root.join("db/migrate/20170806125915_create_active_storage_tables.rb").to_s

ActiveRecord::Schema.define do
  CreateActiveStorageTables.new.change

  create_table :users, force: true
end

class User < ActiveRecord::Base
  has_one_attached :profile
end

FactoryBot.define do
  factory :user do
    profile { { content_type: "text/plain", filename: "dummy.txt", io: ::StringIO.new("dummy") } }
  end
end

class BugTest < Minitest::Test
  def setup
    Prosopite.scan
  end

  def teardown
    Prosopite.finish
  end

  def test_it_works
    FactoryBot.create(:user)
    FactoryBot.create(:user)
  end

  def test_it_doesnt_work
    FactoryBot.create_list(:user, 2)
  end
end

as you can see, two create works fine, but one create_list(.., 2) doesn't

santib commented

after some debugging I see that the difference lays in the location_key

          query_caller = caller
          location_key = Digest::SHA256.hexdigest(query_caller.join)

which is different when calling create separately, but the same when calling create_list..

And the reason is that the line in the spec that triggers the query is different 🤯

Not sure if we could find a solution for this..

santib commented

I'm closing this because it's not a false positive. The SQL queries are being triggered, it's just how it is supposed to work