summaryrefslogtreecommitdiff
path: root/spec/support/finder_collection.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/finder_collection.rb')
-rw-r--r--spec/support/finder_collection.rb48
1 files changed, 48 insertions, 0 deletions
diff --git a/spec/support/finder_collection.rb b/spec/support/finder_collection.rb
new file mode 100644
index 00000000000..494dd4bdca1
--- /dev/null
+++ b/spec/support/finder_collection.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'set'
+
+module Support
+ # Ensure that finders' `execute` method always returns
+ # `ActiveRecord::Relation`.
+ #
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/298771
+ module FinderCollection
+ def self.install_check(finder_class)
+ return unless check?(finder_class)
+
+ finder_class.prepend CheckResult
+ end
+
+ ALLOWLIST_YAML = File.join(__dir__, 'finder_collection_allowlist.yml')
+
+ def self.check?(finder_class)
+ @allowlist ||= YAML.load_file(ALLOWLIST_YAML).to_set
+
+ @allowlist.exclude?(finder_class.name)
+ end
+
+ module CheckResult
+ def execute(...)
+ result = super
+
+ unless result.is_a?(ActiveRecord::Relation)
+ raise <<~MESSAGE
+ #{self.class}#execute returned `#{result.class}` instead of `ActiveRecord::Relation`.
+ All finder classes are expected to return `ActiveRecord::Relation`.
+
+ Read more at https://docs.gitlab.com/ee/development/reusing_abstractions.html#finders
+ MESSAGE
+ end
+
+ result
+ end
+ end
+ end
+end
+
+RSpec.configure do |config|
+ config.before(:all, type: :finder) do
+ Support::FinderCollection.install_check(described_class)
+ end
+end