about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorMatt Jankowski <mjankowski@thoughtbot.com>2017-05-31 14:28:45 -0400
committerEugen Rochko <eugen@zeonfederated.com>2017-05-31 20:28:45 +0200
commit2cc3111a7775066c34eb407cd3b4707acc659488 (patch)
tree64b3212472eb10df4b22709e4bf4b00e13ac8e47 /app/models
parentbf811e4d4a8626579fc5187f465cdf1e79a32e10 (diff)
Expand spec coverage and refactor the `Account.find_` methods (#3485)
* Move specs for account finder methods to concern spec

* Move account finder methods to concern

* Improve spec wording

* Use more explicit comparison to ensure correct return value

* Add coverage for .find_local! and .find_remote!

* Add some methods to the finder

* Use arel on matching_username method

* Avoid ternary in matching domain method

* Simplify finder methods

* Use an AccountFinder class to simplify lookup
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb22
-rw-r--r--app/models/concerns/account_finder_concern.rb58
2 files changed, 59 insertions, 21 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index cb116dbaf..4561fd0a4 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -42,6 +42,7 @@ class Account < ApplicationRecord
   MENTION_RE = /(?:^|[^\/[:word:]])@([a-z0-9_]+(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
 
   include AccountAvatar
+  include AccountFinderConcern
   include AccountHeader
   include AccountInteractions
   include Attachmentable
@@ -162,27 +163,6 @@ class Account < ApplicationRecord
   end
 
   class << self
-    def find_local!(username)
-      find_remote!(username, nil)
-    end
-
-    def find_remote!(username, domain)
-      raise ActiveRecord::RecordNotFound if username.blank?
-      where('lower(accounts.username) = ?', username.downcase).where(domain.nil? ? { domain: nil } : 'lower(accounts.domain) = ?', domain&.downcase).take!
-    end
-
-    def find_local(username)
-      find_local!(username)
-    rescue ActiveRecord::RecordNotFound
-      nil
-    end
-
-    def find_remote(username, domain)
-      find_remote!(username, domain)
-    rescue ActiveRecord::RecordNotFound
-      nil
-    end
-
     def triadic_closures(account, limit: 5, offset: 0)
       sql = <<-SQL.squish
         WITH first_degree AS (
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
new file mode 100644
index 000000000..d3ad519b1
--- /dev/null
+++ b/app/models/concerns/account_finder_concern.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module AccountFinderConcern
+  extend ActiveSupport::Concern
+
+  class_methods do
+    def find_local!(username)
+      find_local(username) || raise(ActiveRecord::RecordNotFound)
+    end
+
+    def find_remote!(username, domain)
+      find_remote(username, domain) || raise(ActiveRecord::RecordNotFound)
+    end
+
+    def find_local(username)
+      find_remote(username, nil)
+    end
+
+    def find_remote(username, domain)
+      AccountFinder.new(username, domain).account
+    end
+  end
+
+  class AccountFinder
+    attr_reader :username, :domain
+
+    def initialize(username, domain)
+      @username = username
+      @domain = domain
+    end
+
+    def account
+      scoped_accounts.take
+    end
+
+    private
+
+    def scoped_accounts
+      Account.unscoped.tap do |scope|
+        scope.merge! matching_username
+        scope.merge! matching_domain
+      end
+    end
+
+    def matching_username
+      raise(ActiveRecord::RecordNotFound) if username.blank?
+      Account.where(Account.arel_table[:username].lower.eq username.downcase)
+    end
+
+    def matching_domain
+      if domain.nil?
+        Account.where(domain: nil)
+      else
+        Account.where(Account.arel_table[:domain].lower.eq domain.downcase)
+      end
+    end
+  end
+end