From 9e5a8662a1f578fbd38ca7a4de7234ac090f6bc0 Mon Sep 17 00:00:00 2001
From: Mauricio Giacomini Girardello <mgg12@inf.ufpr.br>
Date: Tue, 5 Apr 2016 11:19:01 -0300
Subject: [PATCH] refactoring followable concern and user model

---
 app/models/concerns/followable.rb | 13 +++------
 app/models/user.rb                | 29 +++++++++++++++++---
 test/fixtures/collections.yml     |  4 +++
 test/fixtures/users.yml           |  5 +++-
 test/models/user_test.rb          | 45 +++++++++++++++++++++++++++----
 5 files changed, 76 insertions(+), 20 deletions(-)
 create mode 100644 test/fixtures/collections.yml

diff --git a/app/models/concerns/followable.rb b/app/models/concerns/followable.rb
index 7c375f59..c5485dbe 100644
--- a/app/models/concerns/followable.rb
+++ b/app/models/concerns/followable.rb
@@ -5,16 +5,9 @@ module Followable
     has_many :follows, as: :followable, dependent: :destroy
   end
 
-  def follow(user)
-    Follow.create(user: user, followable: self)
-  end
-
-  def unfollow(user)
-    Follow.where(user: user, followable: self).destroy_all
-  end
-
-  def following?(followable)
-    !follows.where(followable_id: followable.id, followable_type: followable.class.name).blank?
+  # Retrieve the user followers
+  def followers
+    Follow.where(followable: self)
   end
 
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index dc8ee707..8d904eae 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -45,10 +45,6 @@ class User < ActiveRecord::Base
     }
   end
 
-  def followers
-    Follow.where(followable: self)
-  end
-
   def is_admin?
     roles.each do |role|
       return true if role.name == "admin"
@@ -56,6 +52,31 @@ class User < ActiveRecord::Base
     false
   end
 
+  # ~~~~ followable actions ~~~~ #
+  # An user can follow anothers users and collections
+  # Examples:
+  # current_user.follow(User.find_by_email('john@revelator.com'))
+  # current_user.follow(Collection.find(143))
+  def follow(followable)
+    Follow.create(user: self, followable: followable)
+  end
+
+  # Examples:
+  # current_user.unfollow(User.find_by_email('john@revelator.com'))
+  # current_user.unfollow(Collection.find(143))
+  def unfollow(followable)
+    Follow.where(user: self, followable: followable).destroy_all
+  end
+
+  # An user can see if is following another user
+  # Examples:
+  # current_user.following?(User.find_by_email('john@revelator.com')) => true
+  # current_user.following?(Collection.find(143)) => true
+  def following?(followable)
+    !follows.where(followable_id: followable.id, followable_type: followable.class.name).blank?
+  end
+  # ~~~~ end followable actions ~~~~ #
+
   private
 
   def default_role
diff --git a/test/fixtures/collections.yml b/test/fixtures/collections.yml
new file mode 100644
index 00000000..28f25d7e
--- /dev/null
+++ b/test/fixtures/collections.yml
@@ -0,0 +1,4 @@
+ufpr:
+  name: 'UFPR collection'
+  owner: john (User)
+  privacy: 'public'
\ No newline at end of file
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
index 4e56b618..946f2e1c 100644
--- a/test/fixtures/users.yml
+++ b/test/fixtures/users.yml
@@ -1,7 +1,10 @@
 john:
   name: 'John'
   email: 'john@test.com'
-  encrypted_password: 'test123455'
+
+jack:
+  name: 'Jack'
+  email: 'jack@rackan.com'
 
 one:
   name: 'John'
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
index cab66843..3341668e 100644
--- a/test/models/user_test.rb
+++ b/test/models/user_test.rb
@@ -3,20 +3,55 @@ require 'test_helper'
 class UserTest < ActiveSupport::TestCase
   should have_and_belong_to_many(:roles)
   should have_and_belong_to_many(:institutions)
-
   should have_many :bookmarks
   should have_many(:bookmark_collections).through(:bookmarks).source(:bookmarkable)
   should have_many(:bookmark_learning_objects).through(:bookmarks).source(:bookmarkable)
-
   should have_many :collections
-
   should have_many :learning_objects
-
   should have_many :views
   should have_many :downloads
   should have_many :likes
   should have_many :shares
   should have_many :follows
-
   should have_many :reviews
+
+  test 'an user can follow another user' do
+    john = users(:john)
+    jack = users(:jack)
+    assert john.follow(jack)
+
+    # check jack followers
+    assert_count 1, jack.followers
+    assert_count 1, john.follows
+    assert john.following? jack
+  end
+
+  test 'an user can follow a collection' do
+    john = users(:john)
+    ufpr_collection = collections(:ufpr)
+    assert john.follow(ufpr_collection)
+
+    # check ufpr followers
+    assert_count 1, ufpr_collection.followers
+    assert_count 1, john.follows
+    assert john.following? ufpr_collection
+  end
+
+  test 'an user can unfollow a collection' do
+    john = users(:john)
+    ufpr_collection = collections(:ufpr)
+    assert john.follow(ufpr_collection)
+
+    # check ufpr followers
+    assert_count 1, ufpr_collection.followers
+    assert_count 1, john.follows
+    assert john.following? ufpr_collection
+
+    john.unfollow(ufpr_collection)
+
+    # check ufpr followers
+    assert_count 0, ufpr_collection.followers
+    assert_count 0, john.follows
+    assert_not john.following? ufpr_collection
+  end
 end
-- 
GitLab