about summary refs log tree commit diff
path: root/app/models/concerns/account_finder_concern.rb
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/concerns/account_finder_concern.rb
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/concerns/account_finder_concern.rb')
-rw-r--r--app/models/concerns/account_finder_concern.rb58
1 files changed, 58 insertions, 0 deletions
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