Commit 95367d53bdce54355fffdf724209d7d51db04708

Authored by Dylan Guedes
Committed by Gabriel Silva
1 parent 9b3cd0de
Exists in external_followers

Adds Follower behavior to External Person

- Introduces Follower and Followable concerns
- Adds External Profile
- External Person can follow profiles
- External Profiles can be followed
- Refactors Profile/Circle relations

Signed-off-by: DylanGuedes <djmgguedes@gmail.com>
Signed-off-by: Gabriel Silva <gabriel93.silva@gmail.com>
Showing 39 changed files with 665 additions and 401 deletions   Show diff stats
app/controllers/concerns/needs_profile.rb
@@ -32,6 +32,8 @@ module NeedsProfile @@ -32,6 +32,8 @@ module NeedsProfile
32 params.delete(:profile) 32 params.delete(:profile)
33 redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname)) 33 redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname))
34 end 34 end
  35 + elsif session[:external]
  36 + @profile = ExternalPerson.find(session[:external])
35 else 37 else
36 render_not_found 38 render_not_found
37 end 39 end
app/controllers/my_profile/circles_controller.rb
@@ -3,7 +3,7 @@ class CirclesController &lt; MyProfileController @@ -3,7 +3,7 @@ class CirclesController &lt; MyProfileController
3 before_action :accept_only_post, :only => [:create, :update, :destroy] 3 before_action :accept_only_post, :only => [:create, :update, :destroy]
4 4
5 def index 5 def index
6 - @circles = profile.circles 6 + @circles = profile.owned_circles
7 end 7 end
8 8
9 def new 9 def new
@@ -11,7 +11,7 @@ class CirclesController &lt; MyProfileController @@ -11,7 +11,7 @@ class CirclesController &lt; MyProfileController
11 end 11 end
12 12
13 def create 13 def create
14 - @circle = Circle.new(params[:circle].merge({ :person => profile })) 14 + @circle = Circle.new(params[:circle].merge({ :owner => profile }))
15 if @circle.save 15 if @circle.save
16 redirect_to :action => 'index' 16 redirect_to :action => 'index'
17 else 17 else
@@ -21,7 +21,7 @@ class CirclesController &lt; MyProfileController @@ -21,7 +21,7 @@ class CirclesController &lt; MyProfileController
21 21
22 def xhr_create 22 def xhr_create
23 if request.xhr? 23 if request.xhr?
24 - circle = Circle.new(params[:circle].merge({:person => profile })) 24 + circle = Circle.new(params[:circle].merge({:owner => profile }))
25 if circle.save 25 if circle.save
26 render :partial => "circle_checkbox", :locals => { :circle => circle }, 26 render :partial => "circle_checkbox", :locals => { :circle => circle },
27 :status => 201 27 :status => 201
app/controllers/my_profile/followers_controller.rb
@@ -4,11 +4,11 @@ class FollowersController &lt; MyProfileController @@ -4,11 +4,11 @@ class FollowersController &lt; MyProfileController
4 before_action :accept_only_post, :only => [:update_category] 4 before_action :accept_only_post, :only => [:update_category]
5 5
6 def index 6 def index
7 - @followed_people = profile.followed_profiles.order(:type) 7 + @followed_people = profile.followed_profiles.sort_by(&:type)
8 @profile_types = {_('All profiles') => nil}.merge(Circle.profile_types).to_a 8 @profile_types = {_('All profiles') => nil}.merge(Circle.profile_types).to_a
9 9
10 if params['filter'].present? 10 if params['filter'].present?
11 - @followed_people = @followed_people.where(:type => params['filter']) 11 + @followed_people = @followed_people.select{|c| c.type == params['filter']}
12 @active_filter = params['filter'] 12 @active_filter = params['filter']
13 end 13 end
14 14
@@ -17,7 +17,7 @@ class FollowersController &lt; MyProfileController @@ -17,7 +17,7 @@ class FollowersController &lt; MyProfileController
17 17
18 def set_category_modal 18 def set_category_modal
19 followed_profile = Profile.find(params[:followed_profile_id]) 19 followed_profile = Profile.find(params[:followed_profile_id])
20 - circles = Circle.where(:person => profile, :profile_type => followed_profile.class.name) 20 + circles = Circle.where(:owner => profile, :profile_type => followed_profile.class.name)
21 render :partial => 'followers/edit_circles_modal', :locals => { :circles => circles, :followed_profile => followed_profile } 21 render :partial => 'followers/edit_circles_modal', :locals => { :circles => circles, :followed_profile => followed_profile }
22 end 22 end
23 23
app/controllers/public/profile_controller.rb
@@ -74,6 +74,8 @@ class ProfileController &lt; PublicController @@ -74,6 +74,8 @@ class ProfileController &lt; PublicController
74 74
75 def following 75 def following
76 @followed_people = profile.followed_profiles.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followed_profiles.count) 76 @followed_people = profile.followed_profiles.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followed_profiles.count)
  77 + puts "FOLLOWED_PEOPLE: #{@followed_people.map(&:name)}"
  78 + return @followed_people
77 end 79 end
78 80
79 def followed 81 def followed
@@ -170,6 +172,7 @@ class ProfileController &lt; PublicController @@ -170,6 +172,7 @@ class ProfileController &lt; PublicController
170 if profile.followed_by?(current_person) 172 if profile.followed_by?(current_person)
171 render :text => _("You are already following %s.") % profile.name, :status => 400 173 render :text => _("You are already following %s.") % profile.name, :status => 400
172 else 174 else
  175 + params[:circles] ||= []
173 selected_circles = params[:circles].map{ |circle_name, circle_id| Circle.find_by(:id => circle_id) }.select{ |c| c.present? } 176 selected_circles = params[:circles].map{ |circle_name, circle_id| Circle.find_by(:id => circle_id) }.select{ |c| c.present? }
174 if selected_circles.present? 177 if selected_circles.present?
175 current_person.follow(profile, selected_circles) 178 current_person.follow(profile, selected_circles)
@@ -181,7 +184,7 @@ class ProfileController &lt; PublicController @@ -181,7 +184,7 @@ class ProfileController &lt; PublicController
181 end 184 end
182 185
183 def find_profile_circles 186 def find_profile_circles
184 - circles = Circle.where(:person => current_person, :profile_type => profile.class.name) 187 + circles = Circle.where(:owner => current_person, :profile_type => profile.class.name)
185 render :partial => 'blocks/profile_info_actions/circles', :locals => { :circles => circles, :profile_types => Circle.profile_types.to_a } 188 render :partial => 'blocks/profile_info_actions/circles', :locals => { :circles => circles, :profile_types => Circle.profile_types.to_a }
186 end 189 end
187 190
@@ -260,10 +263,11 @@ class ProfileController &lt; PublicController @@ -260,10 +263,11 @@ class ProfileController &lt; PublicController
260 end 263 end
261 264
262 def search_followed 265 def search_followed
263 - result = []  
264 - circles = find_by_contents(:circles, user, user.circles.where(:profile_type => 'Person'), params[:q])[:results]  
265 - followed = find_by_contents(:followed, user, Profile.followed_by(user), params[:q])[:results]  
266 - result = circles + followed 266 + circles = find_by_contents(:circles, user, user.owned_circles.where(:profile_type => 'Person'), params[:q])[:results]
  267 + local_followed = find_by_contents(:followed, user, user.local_followed_profiles, params[:q])[:results]
  268 + external_followed = find_by_contents(:followed, user, user.external_followed_profiles, params[:q])[:results]
  269 +
  270 + result = circles + local_followed + external_followed
267 render :text => prepare_to_token_input_by_class(result).to_json 271 render :text => prepare_to_token_input_by_class(result).to_json
268 end 272 end
269 273
@@ -516,7 +520,7 @@ class ProfileController &lt; PublicController @@ -516,7 +520,7 @@ class ProfileController &lt; PublicController
516 followed << Person.find(identifier) 520 followed << Person.find(identifier)
517 when 'Circle' 521 when 'Circle'
518 circle = Circle.find(identifier) 522 circle = Circle.find(identifier)
519 - followed += Profile.in_circle(circle) 523 + followed += circle.profiles
520 end 524 end
521 end 525 end
522 followed.uniq 526 followed.uniq
app/jobs/notify_activity_to_profiles_job.rb
@@ -24,7 +24,7 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id) @@ -24,7 +24,7 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id)
24 ActionTrackerNotification.connection.execute("INSERT INTO action_tracker_notifications(profile_id, action_tracker_id) SELECT DISTINCT profiles.id, #{tracked_action.id} FROM profiles WHERE profiles.id IN (#{target.marked_people.map(&:id).join(',')})") 24 ActionTrackerNotification.connection.execute("INSERT INTO action_tracker_notifications(profile_id, action_tracker_id) SELECT DISTINCT profiles.id, #{tracked_action.id} FROM profiles WHERE profiles.id IN (#{target.marked_people.map(&:id).join(',')})")
25 else 25 else
26 # Notify all followers 26 # Notify all followers
27 - ActionTrackerNotification.connection.execute("INSERT INTO action_tracker_notifications(profile_id, action_tracker_id) SELECT DISTINCT c.person_id, #{tracked_action.id} FROM profiles_circles AS p JOIN circles as c ON c.id = p.circle_id WHERE p.profile_id = #{tracked_action.user.id} AND (c.person_id NOT IN (SELECT atn.profile_id FROM action_tracker_notifications AS atn WHERE atn.action_tracker_id = #{tracked_action.id}))") 27 + ActionTrackerNotification.connection.execute("INSERT INTO action_tracker_notifications(profile_id, action_tracker_id) SELECT DISTINCT c.owner_id, #{tracked_action.id} FROM profiles_circles AS p JOIN circles as c ON c.id = p.circle_id WHERE p.profile_id = #{tracked_action.user.id} AND (c.owner_id NOT IN (SELECT atn.profile_id FROM action_tracker_notifications AS atn WHERE atn.action_tracker_id = #{tracked_action.id}))")
28 end 28 end
29 29
30 if tracked_action.user.is_a? Organization 30 if tracked_action.user.is_a? Organization
app/models/add_member.rb
@@ -22,7 +22,7 @@ class AddMember &lt; Task @@ -22,7 +22,7 @@ class AddMember &lt; Task
22 self.roles = [Profile::Roles.member(organization.environment.id).id] 22 self.roles = [Profile::Roles.member(organization.environment.id).id]
23 end 23 end
24 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)}) 24 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)})
25 - person.follow(organization, Circle.find_or_create_by(:person => person, :name =>_('memberships'), :profile_type => 'Community')) 25 + person.follow(organization, Circle.find_or_create_by(:owner => person, :name =>_('memberships'), :profile_type => 'Community'))
26 end 26 end
27 27
28 def title 28 def title
app/models/circle.rb
@@ -6,30 +6,35 @@ class Circle &lt; ApplicationRecord @@ -6,30 +6,35 @@ class Circle &lt; ApplicationRecord
6 _('Circle') 6 _('Circle')
7 7
8 has_many :profile_followers 8 has_many :profile_followers
9 - belongs_to :person 9 + belongs_to :owner, polymorphic: true
10 10
11 - attr_accessible :name, :person, :profile_type 11 + attr_accessible :name, :owner, :profile_type
12 12
13 validates :name, presence: true 13 validates :name, presence: true
14 - validates :person_id, presence: true 14 + validates :owner_id, presence: true
15 validates :profile_type, presence: true 15 validates :profile_type, presence: true
16 - validates :person_id, :uniqueness => {:scope => :name, :message => "can't add two circles with the same name"} 16 + validates :owner_id, :uniqueness => {:scope => :name, :message => "can't add two circles with the same name"}
17 17
18 validate :profile_type_must_be_in_list 18 validate :profile_type_must_be_in_list
19 19
20 scope :by_owner, -> person{ 20 scope :by_owner, -> person{
21 - where(:person => person) 21 + where(:owner => person)
22 } 22 }
23 23
24 scope :with_name, -> name{ 24 scope :with_name, -> name{
25 where(:name => name) 25 where(:name => name)
26 } 26 }
27 27
  28 + def profiles
  29 + self.profile_followers.map(&:profile)
  30 + end
  31 +
28 def self.profile_types 32 def self.profile_types
29 { 33 {
30 _("Person") => Person.name, 34 _("Person") => Person.name,
31 _("Community") => Community.name, 35 _("Community") => Community.name,
32 - _("Enterprise") => Enterprise.name 36 + _("Enterprise") => Enterprise.name,
  37 + _("Organization") => Organization.name
33 } 38 }
34 end 39 end
35 40
app/models/concerns/external_user.rb
@@ -20,7 +20,7 @@ module ExternalUser @@ -20,7 +20,7 @@ module ExternalUser
20 if login && domain && environment.has_federated_network?(domain) 20 if login && domain && environment.has_federated_network?(domain)
21 external_environment = environment.external_environments.find_by_domain(domain) 21 external_environment = environment.external_environments.find_by_domain(domain)
22 scheme = "http#{external_environment.uses_ssl? ? 's' : ''}" 22 scheme = "http#{external_environment.uses_ssl? ? 's' : ''}"
23 - url = URI.parse(scheme+"://"+ domain +'/.well-known/webfinger?resource=acct:'+ 23 +p url = URI.parse(scheme+"://"+ domain +'/.well-known/webfinger?resource=acct:'+
24 login+'@'+domain) 24 login+'@'+domain)
25 http = build_request(url) 25 http = build_request(url)
26 req = Net::HTTP::Get.new(url.to_s) 26 req = Net::HTTP::Get.new(url.to_s)
app/models/concerns/followable.rb 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +module Followable
  2 + extend ActiveSupport::Concern
  3 +
  4 + included do
  5 + has_many :profile_followers, :as => :profile
  6 + has_many :circles, :through => :profile_followers
  7 + end
  8 +
  9 + def followers
  10 + person_followers = Person.joins(:owned_circles).merge(circles).uniq
  11 + external_person_followers = ExternalPerson.joins(:owned_circles).merge(circles).uniq
  12 +
  13 + person_followers + external_person_followers
  14 + end
  15 +
  16 + def followed_by?(person)
  17 + (person == self) || (person.in? self.followers)
  18 + end
  19 +
  20 + def in_circle?(circle)
  21 + circle.in? self.circles
  22 + end
  23 +end
app/models/concerns/follower.rb 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  1 +module Follower
  2 + extend ActiveSupport::Concern
  3 +
  4 + included do
  5 + has_many :owned_circles, as: :owner, :class_name => "Circle"
  6 + end
  7 +
  8 + def follow(profile, circles)
  9 + circles = [circles] unless circles.is_a?(Array)
  10 + circles.each do |new_circle|
  11 + next if new_circle.owner != self || !profile.kind_of?(new_circle.profile_type.constantize)
  12 + ProfileFollower.create(profile: profile, circle: new_circle)
  13 + end
  14 + end
  15 +
  16 + def follows?(profile)
  17 + return false if profile.nil?
  18 + profile.followed_by?(self)
  19 + end
  20 +
  21 + def unfollow(profile)
  22 + ProfileFollower.with_follower(self).with_profile(profile).destroy_all
  23 + end
  24 +
  25 + def local_followed_profiles
  26 + Profile.joins(:circles).where("circles.owner_id = ?", self.id).uniq
  27 + end
  28 +
  29 + def external_followed_profiles
  30 + ExternalProfile.joins(:circles).where("circles.owner_id = ?", self.id).uniq
  31 + end
  32 +
  33 + def followed_profiles
  34 + local_followed_profiles + external_followed_profiles
  35 + end
  36 +
  37 + def update_profile_circles(profile, new_circles)
  38 + profile_circles = ProfileFollower.with_profile(profile).with_follower(self).map(&:circle)
  39 + circles_to_add = new_circles - profile_circles
  40 + self.follow(profile, circles_to_add)
  41 +
  42 + circles_to_remove = profile_circles - new_circles
  43 + ProfileFollower.where('circle_id IN (?) AND profile_id = ?',
  44 + circles_to_remove.map(&:id), profile.id).destroy_all
  45 + end
  46 +
  47 + def remove_profile_from_circle(profile, circle)
  48 + return if circle.owner != self
  49 + ProfileFollower.with_profile(profile).with_circle(circle).destroy_all
  50 + end
  51 +
  52 +end
app/models/external_person.rb
1 # A pseudo profile is a person from a remote network 1 # A pseudo profile is a person from a remote network
2 -class ExternalPerson < ActiveRecord::Base 2 +class ExternalPerson < ExternalProfile
3 3
4 include Human 4 include Human
5 include ProfileEntity 5 include ProfileEntity
  6 + include Follower
6 7
7 validates_uniqueness_of :identifier, scope: :source 8 validates_uniqueness_of :identifier, scope: :source
8 -  
9 validates_presence_of :source, :email, :created_at 9 validates_presence_of :source, :email, :created_at
10 10
11 attr_accessible :source, :email, :created_at 11 attr_accessible :source, :email, :created_at
@@ -27,13 +27,6 @@ class ExternalPerson &lt; ActiveRecord::Base @@ -27,13 +27,6 @@ class ExternalPerson &lt; ActiveRecord::Base
27 _('Public profile') 27 _('Public profile')
28 end 28 end
29 29
30 - def avatar  
31 - "http://#{self.source}/profile/#{self.identifier}/icon/"  
32 - end  
33 -  
34 - def url  
35 - "http://#{self.source}/profile/#{self.identifier}"  
36 - end  
37 30
38 alias :public_profile_url :url 31 alias :public_profile_url :url
39 32
@@ -75,10 +68,6 @@ class ExternalPerson &lt; ActiveRecord::Base @@ -75,10 +68,6 @@ class ExternalPerson &lt; ActiveRecord::Base
75 "#{scheme}://#{self.source}" 68 "#{scheme}://#{self.source}"
76 end 69 end
77 70
78 - def profile_custom_icon(gravatar_default=nil)  
79 - self.avatar  
80 - end  
81 -  
82 def preferred_login_redirection 71 def preferred_login_redirection
83 environment.redirection_after_login 72 environment.redirection_after_login
84 end 73 end
@@ -122,26 +111,6 @@ class ExternalPerson &lt; ActiveRecord::Base @@ -122,26 +111,6 @@ class ExternalPerson &lt; ActiveRecord::Base
122 "#{jid(options)}/#{self.name}" 111 "#{jid(options)}/#{self.name}"
123 end 112 end
124 113
125 - class ExternalPerson::Image  
126 - def initialize(path)  
127 - @path = path  
128 - end  
129 -  
130 - def public_filename(size = nil)  
131 - URI.join(@path, size.to_s)  
132 - end  
133 -  
134 - def content_type  
135 - # This is not really going to be used anywhere that matters  
136 - # so we are hardcodding it here.  
137 - 'image/png'  
138 - end  
139 - end  
140 -  
141 - def image  
142 - ExternalPerson::Image.new(avatar)  
143 - end  
144 -  
145 def data_hash(gravatar_default = nil) 114 def data_hash(gravatar_default = nil)
146 friends_list = {} 115 friends_list = {}
147 { 116 {
@@ -195,67 +164,11 @@ class ExternalPerson &lt; ActiveRecord::Base @@ -195,67 +164,11 @@ class ExternalPerson &lt; ActiveRecord::Base
195 build_contact: nil, is_a_friend?: false, ask_to_join?: false, refuse_join: 164 build_contact: nil, is_a_friend?: false, ask_to_join?: false, refuse_join:
196 nil, blocks_to_expire_cache: [], cache_keys: [], communities_cache_key: '', 165 nil, blocks_to_expire_cache: [], cache_keys: [], communities_cache_key: '',
197 friends_cache_key: '', manage_friends_cache_key: '', 166 friends_cache_key: '', manage_friends_cache_key: '',
198 - relationships_cache_key: '', is_member_of?: false, follows?: false, 167 + relationships_cache_key: '', is_member_of?: false,
199 each_friend: nil, is_last_admin?: false, is_last_admin_leaving?: false, 168 each_friend: nil, is_last_admin?: false, is_last_admin_leaving?: false,
200 leave: nil, last_notification: nil, notification_time: 0, notifier: nil, 169 leave: nil, last_notification: nil, notification_time: 0, notifier: nil,
201 - remove_suggestion: nil, allow_invitation_from?: false  
202 - }  
203 -  
204 - derivated_methods = generate_derivated_methods(methods_and_responses)  
205 - derivated_methods.merge(methods_and_responses)  
206 - end  
207 -  
208 - def profile_instance_methods  
209 - methods_and_responses = {  
210 - role_assignments: RoleAssignment.none, favorite_enterprises:  
211 - Enterprise.none, memberships: Profile.none, friendships: Profile.none,  
212 - tasks: Task.none, suggested_profiles: ProfileSuggestion.none,  
213 - suggested_people: ProfileSuggestion.none, suggested_communities:  
214 - ProfileSuggestion.none, public_profile: true, nickname: nil, custom_footer:  
215 - '', custom_header: '', address: '', zip_code: '', contact_phone: '',  
216 - image_builder: nil, description: '', closed: false, template_id: nil, lat:  
217 - nil, lng: nil, is_template: false, fields_privacy: {}, preferred_domain_id:  
218 - nil, category_ids: [], country: '', city: '', state: '',  
219 - national_region_code: '', redirect_l10n: false, notification_time: 0,  
220 - custom_url_redirection: nil, email_suggestions: false,  
221 - allow_members_to_invite: false, invite_friends_only: false, secret: false,  
222 - profile_admin_mail_notification: false, redirection_after_login: nil,  
223 - profile_activities: ProfileActivity.none, action_tracker_notifications:  
224 - ActionTrackerNotification.none, tracked_notifications:  
225 - ActionTracker::Record.none, scraps_received: Scrap.none, template:  
226 - Profile.none, comments_received: Comment.none, email_templates:  
227 - EmailTemplate.none, members: Profile.none, members_like: Profile.none,  
228 - members_by: Profile.none, members_by_role: Profile.none, scraps:  
229 - Scrap.none, welcome_page_content: nil, settings: {}, find_in_all_tasks:  
230 - nil, top_level_categorization: {}, interests: Category.none, geolocation:  
231 - '', country_name: '', pending_categorizations: [], add_category: false,  
232 - create_pending_categorizations: false, top_level_articles: Article.none,  
233 - valid_identifier: true, valid_template: false, create_default_set_of_boxes:  
234 - true, copy_blocks_from: nil, default_template: nil,  
235 - template_without_default: nil, template_with_default: nil, apply_template:  
236 - false, iframe_whitelist: [], recent_documents: Article.none, last_articles:  
237 - Article.none, is_validation_entity?: false, hostname: nil, own_hostname:  
238 - nil, article_tags: {}, tagged_with: Article.none,  
239 - insert_default_article_set: false, copy_articles_from: true,  
240 - copy_article_tree: nil, copy_article?: false, add_member: false,  
241 - remove_member: false, add_admin: false, remove_admin: false, add_moderator:  
242 - false, display_info_to?: true, update_category_from_region: nil,  
243 - accept_category?: false, custom_header_expanded: '',  
244 - custom_footer_expanded: '', public?: true, themes: [], find_theme: nil,  
245 - blogs: Blog.none, blog: nil, has_blog?: false, forums: Forum.none, forum:  
246 - nil, has_forum?: false, admins: [], settings_field: {}, setting_changed:  
247 - false, public_content: true, enable_contact?: false, folder_types: [],  
248 - folders: Article.none, image_galleries: Article.none, image_valid: true,  
249 - update_header_and_footer: nil, update_theme: nil, update_layout_template:  
250 - nil, recent_actions: ActionTracker::Record.none, recent_notifications:  
251 - ActionTracker::Record.none, more_active_label: _('no activity'),  
252 - more_popular_label: _('no members'), profile_custom_image: nil,  
253 - is_on_homepage?: false, activities: ProfileActivity.none,  
254 - may_display_field_to?: true, may_display_location_to?: true, public_fields:  
255 - {}, followed_by?: false, display_private_info_to?: true, can_view_field?:  
256 - true, remove_from_suggestion_list: nil, layout_template: 'default',  
257 - is_admin?: false, add_friend: false, follows?: false, is_a_friend?: false,  
258 - already_request_friendship?: false 170 + remove_suggestion: nil, allow_invitation_from?: false, in_social_circle?: false,
  171 + allow_followers: false
259 } 172 }
260 173
261 derivated_methods = generate_derivated_methods(methods_and_responses) 174 derivated_methods = generate_derivated_methods(methods_and_responses)
@@ -266,25 +179,15 @@ class ExternalPerson &lt; ActiveRecord::Base @@ -266,25 +179,15 @@ class ExternalPerson &lt; ActiveRecord::Base
266 if person_instance_methods.keys.include?(method) 179 if person_instance_methods.keys.include?(method)
267 return person_instance_methods[method] 180 return person_instance_methods[method]
268 end 181 end
269 - if profile_instance_methods.keys.include? method  
270 - return profile_instance_methods[method]  
271 - end 182 + super(method, *args, &block)
272 end 183 end
273 184
274 def respond_to_missing?(method_name, include_private = false) 185 def respond_to_missing?(method_name, include_private = false)
275 person_instance_methods.keys.include?(method_name) || 186 person_instance_methods.keys.include?(method_name) ||
276 - profile_instance_methods.keys.include?(method_name) ||  
277 super 187 super
278 end 188 end
279 189
280 - private  
281 -  
282 - def generate_derivated_methods(methods)  
283 - derivated_methods = {}  
284 - methods.keys.each do |method|  
285 - derivated_methods[method.to_s.insert(-1, '?').to_sym] = false  
286 - derivated_methods[method.to_s.insert(-1, '=').to_sym] = nil  
287 - end  
288 - derivated_methods 190 + def kind_of?(klass)
  191 + (klass == Person) ? true : super
289 end 192 end
290 end 193 end
app/models/external_profile.rb 0 → 100644
@@ -0,0 +1,126 @@ @@ -0,0 +1,126 @@
  1 +class ExternalProfile < ApplicationRecord
  2 +
  3 + include Followable
  4 +
  5 + SEARCHABLE_FIELDS = {
  6 + :name => {:label => _('Name'), :weight => 10},
  7 + :identifier => {:label => _('Username'), :weight => 5},
  8 + :nickname => {:label => _('Nickname'), :weight => 2},
  9 + }
  10 +
  11 + def name
  12 + "#{self[:name]}@#{self.source}"
  13 + end
  14 +
  15 + class ExternalProfile::Image
  16 + def initialize(path)
  17 + @path = path
  18 + end
  19 +
  20 + def public_filename(size = nil)
  21 + URI.join(@path, size.to_s)
  22 + end
  23 +
  24 + def content_type
  25 + # This is not really going to be used anywhere that matters
  26 + # so we are hardcodding it here.
  27 + 'image/png'
  28 + end
  29 + end
  30 +
  31 + def url
  32 + "http://#{self.source}/profile/#{self.identifier}"
  33 + end
  34 +
  35 + def image
  36 + ExternalProfile::Image.new(avatar)
  37 + end
  38 +
  39 + def profile_custom_icon(gravatar_default=nil)
  40 + self.avatar
  41 + end
  42 +
  43 + def avatar
  44 + "http://#{self.source}/profile/#{self.identifier}/icon/"
  45 + end
  46 +
  47 + # External Profile should respond to all methods in Profile
  48 +def profile_instance_methods
  49 + methods_and_responses = {
  50 + role_assignments: RoleAssignment.none, favorite_enterprises:
  51 + Enterprise.none, memberships: Profile.none, friendships: Profile.none,
  52 + tasks: Task.none, suggested_profiles: ProfileSuggestion.none,
  53 + suggested_people: ProfileSuggestion.none, suggested_communities:
  54 + ProfileSuggestion.none, public_profile: true, nickname: nil, custom_footer:
  55 + '', custom_header: '', address: '', zip_code: '', contact_phone: '',
  56 + image_builder: nil, description: '', closed: false, template_id: nil, lat:
  57 + nil, lng: nil, is_template: false, fields_privacy: {}, preferred_domain_id:
  58 + nil, category_ids: [], country: '', city: '', state: '',
  59 + national_region_code: '', redirect_l10n: false, notification_time: 0,
  60 + custom_url_redirection: nil, email_suggestions: false,
  61 + allow_members_to_invite: false, invite_friends_only: false, secret: false,
  62 + profile_admin_mail_notification: false, redirection_after_login: nil,
  63 + profile_activities: ProfileActivity.none, action_tracker_notifications:
  64 + ActionTrackerNotification.none, tracked_notifications:
  65 + ActionTracker::Record.none, scraps_received: Scrap.none, template:
  66 + Profile.none, comments_received: Comment.none, email_templates:
  67 + EmailTemplate.none, members: Profile.none, members_like: Profile.none,
  68 + members_by: Profile.none, members_by_role: Profile.none, scraps:
  69 + Scrap.none, welcome_page_content: nil, settings: {}, find_in_all_tasks:
  70 + nil, top_level_categorization: {}, interests: Category.none, geolocation:
  71 + '', country_name: '', pending_categorizations: [], add_category: false,
  72 + create_pending_categorizations: false, top_level_articles: Article.none,
  73 + valid_identifier: true, valid_template: false, create_default_set_of_boxes:
  74 + true, copy_blocks_from: nil, default_template: nil,
  75 + template_without_default: nil, template_with_default: nil, apply_template:
  76 + false, iframe_whitelist: [], recent_documents: Article.none, last_articles:
  77 + Article.none, is_validation_entity?: false, hostname: nil, own_hostname:
  78 + nil, article_tags: {}, tagged_with: Article.none,
  79 + insert_default_article_set: false, copy_articles_from: true,
  80 + copy_article_tree: nil, copy_article?: false, add_member: false,
  81 + remove_member: false, add_admin: false, remove_admin: false, add_moderator:
  82 + false, display_info_to?: true, update_category_from_region: nil,
  83 + accept_category?: false, custom_header_expanded: '',
  84 + custom_footer_expanded: '', public?: true, themes: [], find_theme: nil,
  85 + blogs: Blog.none, blog: nil, has_blog?: false, forums: Forum.none, forum:
  86 + nil, has_forum?: false, admins: [], settings_field: {}, setting_changed:
  87 + false, public_content: true, enable_contact?: false, folder_types: [],
  88 + folders: Article.none, image_galleries: Article.none, image_valid: true,
  89 + update_header_and_footer: nil, update_theme: nil, update_layout_template:
  90 + nil, recent_actions: ActionTracker::Record.none, recent_notifications:
  91 + ActionTracker::Record.none, more_active_label: _('no activity'),
  92 + more_popular_label: _('no members'), profile_custom_image: nil,
  93 + is_on_homepage?: false, activities: ProfileActivity.none,
  94 + may_display_field_to?: true, may_display_location_to?: true, public_fields:
  95 + {}, display_private_info_to?: true, can_view_field?:
  96 + true, remove_from_suggestion_list: nil, layout_template: 'default',
  97 + is_admin?: false, add_friend: false, is_a_friend?: false,
  98 + already_request_friendship?: false, tracked_actions: ActionTracker::Record.none
  99 + }
  100 +
  101 + derivated_methods = generate_derivated_methods(methods_and_responses)
  102 + derivated_methods.merge(methods_and_responses)
  103 + end
  104 +
  105 + def method_missing(method, *args, &block)
  106 + if profile_instance_methods.keys.include? method
  107 + return profile_instance_methods[method]
  108 + end
  109 + raise NoMethodError, "undefined method #{method} for #{self}"
  110 + end
  111 +
  112 + def respond_to_missing?(method_name, include_private = false)
  113 + profile_instance_methods.keys.include?(method_name) || super
  114 + end
  115 +
  116 + private
  117 +
  118 + def generate_derivated_methods(methods)
  119 + derivated_methods = {}
  120 + methods.keys.each do |method|
  121 + derivated_methods[method.to_s.insert(-1, '?').to_sym] = false
  122 + derivated_methods[method.to_s.insert(-1, '=').to_sym] = nil
  123 + end
  124 + derivated_methods
  125 + end
  126 +end
app/models/favorite_enterprise_person.rb
@@ -8,7 +8,7 @@ class FavoriteEnterprisePerson &lt; ApplicationRecord @@ -8,7 +8,7 @@ class FavoriteEnterprisePerson &lt; ApplicationRecord
8 belongs_to :person 8 belongs_to :person
9 9
10 after_create do |favorite| 10 after_create do |favorite|
11 - favorite.person.follow(favorite.enterprise, Circle.find_or_create_by(:person => favorite.person, :name =>_('favorites'), :profile_type => 'Enterprise')) 11 + favorite.person.follow(favorite.enterprise, Circle.find_or_create_by(:owner => favorite.person, :name =>_('favorites'), :profile_type => 'Enterprise'))
12 end 12 end
13 13
14 protected 14 protected
app/models/friendship.rb
@@ -12,7 +12,7 @@ class Friendship &lt; ApplicationRecord @@ -12,7 +12,7 @@ class Friendship &lt; ApplicationRecord
12 12
13 circles = friendship.group.blank? ? ['friendships'] : friendship.group.split(',').map(&:strip) 13 circles = friendship.group.blank? ? ['friendships'] : friendship.group.split(',').map(&:strip)
14 circles.each do |circle| 14 circles.each do |circle|
15 - friendship.person.follow(friendship.friend, Circle.find_or_create_by(:person => friendship.person, :name => circle, :profile_type => 'Person')) 15 + friendship.person.follow(friendship.friend, Circle.find_or_create_by(:owner => friendship.person, :name => circle, :profile_type => 'Person'))
16 end 16 end
17 end 17 end
18 18
@@ -22,7 +22,7 @@ class Friendship &lt; ApplicationRecord @@ -22,7 +22,7 @@ class Friendship &lt; ApplicationRecord
22 22
23 groups = friendship.group.blank? ? ['friendships'] : friendship.group.split(',').map(&:strip) 23 groups = friendship.group.blank? ? ['friendships'] : friendship.group.split(',').map(&:strip)
24 groups.each do |group| 24 groups.each do |group|
25 - circle = Circle.find_by(:person => friendship.person, :name => group ) 25 + circle = Circle.find_by(:owner => friendship.person, :name => group )
26 friendship.person.remove_profile_from_circle(friendship.friend, circle) if circle 26 friendship.person.remove_profile_from_circle(friendship.friend, circle) if circle
27 end 27 end
28 end 28 end
app/models/person.rb
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 class Person < Profile 2 class Person < Profile
3 3
4 include Human 4 include Human
  5 + include Follower
5 6
6 attr_accessible :organization, :contact_information, :sex, :birth_date, :cell_phone, :comercial_phone, :jabber_id, :personal_website, :nationality, :address_reference, :district, :schooling, :schooling_status, :formation, :custom_formation, :area_of_study, :custom_area_of_study, :professional_activity, :organization_website, :following_articles 7 attr_accessible :organization, :contact_information, :sex, :birth_date, :cell_phone, :comercial_phone, :jabber_id, :personal_website, :nationality, :address_reference, :district, :schooling, :schooling_status, :formation, :custom_formation, :area_of_study, :custom_area_of_study, :professional_activity, :organization_website, :following_articles
7 8
@@ -93,7 +94,6 @@ class Person &lt; Profile @@ -93,7 +94,6 @@ class Person &lt; Profile
93 has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article 94 has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article
94 has_many :friendships, :dependent => :destroy 95 has_many :friendships, :dependent => :destroy
95 has_many :friends, :class_name => 'Person', :through => :friendships 96 has_many :friends, :class_name => 'Person', :through => :friendships
96 - has_many :circles  
97 97
98 scope :online, -> { 98 scope :online, -> {
99 joins(:user).where("users.chat_status != '' AND users.chat_status_at >= ?", DateTime.now - User.expires_chat_status_every.minutes) 99 joins(:user).where("users.chat_status != '' AND users.chat_status_at >= ?", DateTime.now - User.expires_chat_status_every.minutes)
@@ -183,33 +183,6 @@ class Person &lt; Profile @@ -183,33 +183,6 @@ class Person &lt; Profile
183 end 183 end
184 end 184 end
185 185
186 - def follow(profile, circles)  
187 - circles = [circles] unless circles.is_a?(Array)  
188 - circles.each do |new_circle|  
189 - ProfileFollower.create(profile: profile, circle: new_circle)  
190 - end  
191 - end  
192 -  
193 - def update_profile_circles(profile, new_circles)  
194 - profile_circles = ProfileFollower.with_profile(profile).with_follower(self).map(&:circle)  
195 - circles_to_add = new_circles - profile_circles  
196 - circles_to_remove = profile_circles - new_circles  
197 - circles_to_add.each do |new_circle|  
198 - ProfileFollower.create(profile: profile, circle: new_circle)  
199 - end  
200 -  
201 - ProfileFollower.where('circle_id IN (?) AND profile_id = ?',  
202 - circles_to_remove.map(&:id), profile.id).destroy_all  
203 - end  
204 -  
205 - def unfollow(profile)  
206 - ProfileFollower.with_follower(self).with_profile(profile).destroy_all  
207 - end  
208 -  
209 - def remove_profile_from_circle(profile, circle)  
210 - ProfileFollower.with_profile(profile).with_circle(circle).destroy_all  
211 - end  
212 -  
213 def already_request_friendship?(person) 186 def already_request_friendship?(person)
214 person.tasks.where(requestor_id: self.id, type: 'AddFriend', status: Task::Status::ACTIVE).first 187 person.tasks.where(requestor_id: self.id, type: 'AddFriend', status: Task::Status::ACTIVE).first
215 end 188 end
@@ -494,11 +467,6 @@ class Person &lt; Profile @@ -494,11 +467,6 @@ class Person &lt; Profile
494 profile.members.include?(self) 467 profile.members.include?(self)
495 end 468 end
496 469
497 - def follows?(profile)  
498 - return false if profile.nil?  
499 - profile.followed_by?(self)  
500 - end  
501 -  
502 def each_friend(offset=0) 470 def each_friend(offset=0)
503 while friend = self.friends.order(:id).offset(offset).first 471 while friend = self.friends.order(:id).offset(offset).first
504 yield friend 472 yield friend
@@ -603,10 +571,6 @@ class Person &lt; Profile @@ -603,10 +571,6 @@ class Person &lt; Profile
603 } 571 }
604 end 572 end
605 573
606 - def followed_profiles  
607 - Profile.followed_by self  
608 - end  
609 -  
610 def in_social_circle?(person) 574 def in_social_circle?(person)
611 self.is_a_friend?(person) || super 575 self.is_a_friend?(person) || super
612 end 576 end
app/models/profile.rb
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 class Profile < ApplicationRecord 4 class Profile < ApplicationRecord
5 5
6 include ProfileEntity 6 include ProfileEntity
  7 + include Followable
7 8
8 attr_accessible :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, 9 attr_accessible :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time,
9 :custom_url_redirection, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :profile_admin_mail_notification, :redirection_after_login, :allow_followers 10 :custom_url_redirection, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :profile_admin_mail_notification, :redirection_after_login, :allow_followers
@@ -222,20 +223,6 @@ class Profile &lt; ApplicationRecord @@ -222,20 +223,6 @@ class Profile &lt; ApplicationRecord
222 scope :more_active, -> { order 'activities_count DESC' } 223 scope :more_active, -> { order 'activities_count DESC' }
223 scope :more_recent, -> { order "created_at DESC" } 224 scope :more_recent, -> { order "created_at DESC" }
224 225
225 - scope :followed_by, -> person{  
226 - distinct.select('profiles.*').  
227 - joins('left join profiles_circles ON profiles_circles.profile_id = profiles.id').  
228 - joins('left join circles ON circles.id = profiles_circles.circle_id').  
229 - where('circles.person_id = ?', person.id)  
230 - }  
231 -  
232 - scope :in_circle, -> circle{  
233 - distinct.select('profiles.*').  
234 - joins('left join profiles_circles ON profiles_circles.profile_id = profiles.id').  
235 - joins('left join circles ON circles.id = profiles_circles.circle_id').  
236 - where('circles.id = ?', circle.id)  
237 - }  
238 -  
239 settings_items :allow_followers, :type => :boolean, :default => true 226 settings_items :allow_followers, :type => :boolean, :default => true
240 alias_method :allow_followers?, :allow_followers 227 alias_method :allow_followers?, :allow_followers
241 228
@@ -251,8 +238,7 @@ class Profile &lt; ApplicationRecord @@ -251,8 +238,7 @@ class Profile &lt; ApplicationRecord
251 238
252 has_many :email_templates, :foreign_key => :owner_id 239 has_many :email_templates, :foreign_key => :owner_id
253 240
254 - has_many :profile_followers  
255 - has_many :followers, -> { uniq }, :class_name => 'Person', :through => :profile_followers, :source => :person 241 + # has_many :followers, -> { uniq }, :through => :profile_followers, :source => :person
256 242
257 # Although this should be a has_one relation, there are no non-silly names for 243 # Although this should be a has_one relation, there are no non-silly names for
258 # a foreign key on article to reference the template to which it is 244 # a foreign key on article to reference the template to which it is
@@ -729,7 +715,7 @@ private :generate_url, :url_options @@ -729,7 +715,7 @@ private :generate_url, :url_options
729 else 715 else
730 self.affiliate(person, Profile::Roles.admin(environment.id), attributes) if members.count == 0 716 self.affiliate(person, Profile::Roles.admin(environment.id), attributes) if members.count == 0
731 self.affiliate(person, Profile::Roles.member(environment.id), attributes) 717 self.affiliate(person, Profile::Roles.member(environment.id), attributes)
732 - person.follow(self, Circle.find_or_create_by(:person => person, :name =>_('memberships'), :profile_type => 'Community')) 718 + person.follow(self, Circle.find_or_create_by(:owner => person, :name =>_('memberships'), :profile_type => self.class.name))
733 end 719 end
734 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel } 720 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel }
735 remove_from_suggestion_list person 721 remove_from_suggestion_list person
@@ -1011,10 +997,6 @@ private :generate_url, :url_options @@ -1011,10 +997,6 @@ private :generate_url, :url_options
1011 self.active_fields 997 self.active_fields
1012 end 998 end
1013 999
1014 - def followed_by?(person)  
1015 - (person == self) || (person.in? self.followers)  
1016 - end  
1017 -  
1018 def in_social_circle?(person) 1000 def in_social_circle?(person)
1019 (person == self) || (person.is_member_of?(self)) 1001 (person == self) || (person.is_member_of?(self))
1020 end 1002 end
@@ -1058,7 +1040,4 @@ private :generate_url, :url_options @@ -1058,7 +1040,4 @@ private :generate_url, :url_options
1058 person.kind_of?(Profile) && person.has_permission?('destroy_profile', self) 1040 person.kind_of?(Profile) && person.has_permission?('destroy_profile', self)
1059 end 1041 end
1060 1042
1061 - def in_circle?(circle, follower)  
1062 - ProfileFollower.with_follower(follower).with_circle(circle).with_profile(self).present?  
1063 - end  
1064 end 1043 end
app/models/profile_follower.rb
@@ -4,17 +4,24 @@ class ProfileFollower &lt; ApplicationRecord @@ -4,17 +4,24 @@ class ProfileFollower &lt; ApplicationRecord
4 4
5 attr_accessible :profile, :circle 5 attr_accessible :profile, :circle
6 6
7 - belongs_to :profile 7 + #TODO -> user being followed
  8 + belongs_to :profile, :polymorphic => true
8 belongs_to :circle 9 belongs_to :circle
9 10
10 - has_one :person, through: :circle  
11 - alias follower person 11 + #TODO -> circle owner
  12 + # has_one :person, through: :circle, source_type: "ProfileFollower"
  13 +
  14 + def circle_owner
  15 + self.circle.owner
  16 + end
  17 +
  18 + alias follower circle_owner
12 19
13 validates_presence_of :profile_id, :circle_id 20 validates_presence_of :profile_id, :circle_id
14 validates :profile_id, :uniqueness => {:scope => :circle_id, :message => "can't put a profile in the same circle twice"} 21 validates :profile_id, :uniqueness => {:scope => :circle_id, :message => "can't put a profile in the same circle twice"}
15 22
16 scope :with_follower, -> person{ 23 scope :with_follower, -> person{
17 - joins(:circle).where('circles.person_id = ?', person.id) 24 + joins(:circle).where('circles.owner_id = ?', person.id)
18 } 25 }
19 26
20 scope :with_profile, -> profile{ 27 scope :with_profile, -> profile{
app/views/blocks/profile_info_actions/_select_circles.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <div id="circles-checkboxes"> 3 <div id="circles-checkboxes">
4 <% circles.each do |circle| %> 4 <% circles.each do |circle| %>
5 <div class="circle"> 5 <div class="circle">
6 - <%= labelled_check_box circle.name, "circles[#{circle.name}]", circle.id, followed_profile.in_circle?(circle, follower) %> 6 + <%= labelled_check_box circle.name, "circles[#{circle.name}]", circle.id, followed_profile.in_circle?(circle) %>
7 </div> 7 </div>
8 <% end %> 8 <% end %>
9 </div> 9 </div>
app/views/followers/_profile_list.html.erb
1 <ul class="profile-list"> 1 <ul class="profile-list">
  2 + <h1>Aqui</h1>
2 <% profiles.each do |followed_profile| %> 3 <% profiles.each do |followed_profile| %>
3 <li> 4 <li>
4 <%= link_to_profile profile_image(followed_profile) + tag('br') + followed_profile.short_name, 5 <%= link_to_profile profile_image(followed_profile) + tag('br') + followed_profile.short_name,
app/views/profile/_profile_comment_form.html.erb
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 :rows => 1, 10 :rows => 1,
11 :class => 'submit-with-keypress', 11 :class => 'submit-with-keypress',
12 :title => _('Leave your comment'), 12 :title => _('Leave your comment'),
13 - :onfocus => ("if(this.value==this.title){this.value='';this.style.color='#000'};this.style.backgroundImage='url(" + profile_icon(current_person, :icon, false) + ")'" if logged_in?), 13 + :onfocus => ("if(this.value==this.title){this.value='';this.style.color='#000'};this.style.backgroundImage='url(" + profile_icon(current_person, :icon, false).to_s + ")'" if logged_in?),
14 :onblur => ("if(this.value==''){this.value=this.title;this.style.color='#ccc'};this.style.backgroundImage='none'" if logged_in?), 14 :onblur => ("if(this.value==''){this.value=this.title;this.style.color='#ccc'};this.style.backgroundImage='none'" if logged_in?),
15 :value => _('Leave your comment'), 15 :value => _('Leave your comment'),
16 :style => 'color: #ccc' %> 16 :style => 'color: #ccc' %>
db/migrate/20160810131138_adds_person_type_to_circles.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class AddsPersonTypeToCircles < ActiveRecord::Migration
  2 + def up
  3 + add_column :circles, :person_type, :string, default: "Person"
  4 + add_index :circles, [:person_id, :person_type]
  5 + end
  6 +
  7 + def down
  8 + remove_column :circles, :person_type
  9 + remove_index :circles, [:person_id, :person_type]
  10 + end
  11 +end
db/migrate/20160822174619_adds_profile_type_to_profile_followers.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class AddsProfileTypeToProfileFollowers < ActiveRecord::Migration
  2 + def up
  3 + add_column :profiles_circles, :profile_type, :string, default: "Person"
  4 + add_index :profiles_circles, [:profile_id, :profile_type]
  5 + end
  6 +
  7 + def down
  8 + remove_column :profiles_circles, :profile_type
  9 + remove_index :profiles_circles, [:profile_id, :profile_type]
  10 + end
  11 +end
db/migrate/20160822184703_rename_person_id_from_circles.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class RenamePersonIdFromCircles < ActiveRecord::Migration
  2 + def up
  3 + rename_column :circles, :person_id, :owner_id
  4 + rename_column :circles, :person_type, :owner_type
  5 + end
  6 +
  7 + def down
  8 + rename_column :circles, :owner_id, :person_id
  9 + rename_column :circles, :owner_type, :person_type
  10 + end
  11 +end
db/migrate/20160829170524_rename_external_people_to_external_profiles.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class RenameExternalPeopleToExternalProfiles < ActiveRecord::Migration
  2 + def up
  3 + rename_table :external_people, :external_profiles
  4 + end
  5 +
  6 + def down
  7 + rename_table :external_profiles, :external_people
  8 + end
  9 +end
db/migrate/20160829185118_add_type_to_external_profile.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddTypeToExternalProfile < ActiveRecord::Migration
  2 + def up
  3 + add_column :external_profiles, :type, :string, default: "ExternalProfile"
  4 + end
  5 +
  6 + def down
  7 + remove_column :external_profiles, :type
  8 + end
  9 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended that you check this file into your version control system. 12 # It's strongly recommended that you check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(version: 20160705162914) do 14 +ActiveRecord::Schema.define(version: 20160829185118) do
15 15
16 # These are extensions that must be enabled in order to support this database 16 # These are extensions that must be enabled in order to support this database
17 enable_extension "plpgsql" 17 enable_extension "plpgsql"
@@ -277,11 +277,13 @@ ActiveRecord::Schema.define(version: 20160705162914) do @@ -277,11 +277,13 @@ ActiveRecord::Schema.define(version: 20160705162914) do
277 277
278 create_table "circles", force: :cascade do |t| 278 create_table "circles", force: :cascade do |t|
279 t.string "name" 279 t.string "name"
280 - t.integer "person_id"  
281 - t.string "profile_type", null: false 280 + t.integer "owner_id"
  281 + t.string "profile_type", null: false
  282 + t.string "owner_type", default: "Person"
282 end 283 end
283 284
284 - add_index "circles", ["person_id", "name"], name: "circles_composite_key_index", unique: true, using: :btree 285 + add_index "circles", ["owner_id", "name"], name: "circles_composite_key_index", unique: true, using: :btree
  286 + add_index "circles", ["owner_id", "owner_type"], name: "index_circles_on_owner_id_and_owner_type", using: :btree
285 287
286 create_table "comments", force: :cascade do |t| 288 create_table "comments", force: :cascade do |t|
287 t.string "title" 289 t.string "title"
@@ -439,7 +441,7 @@ ActiveRecord::Schema.define(version: 20160705162914) do @@ -439,7 +441,7 @@ ActiveRecord::Schema.define(version: 20160705162914) do
439 add_index "external_feeds", ["enabled"], name: "index_external_feeds_on_enabled", using: :btree 441 add_index "external_feeds", ["enabled"], name: "index_external_feeds_on_enabled", using: :btree
440 add_index "external_feeds", ["fetched_at"], name: "index_external_feeds_on_fetched_at", using: :btree 442 add_index "external_feeds", ["fetched_at"], name: "index_external_feeds_on_fetched_at", using: :btree
441 443
442 - create_table "external_people", force: :cascade do |t| 444 + create_table "external_profiles", force: :cascade do |t|
443 t.string "name" 445 t.string "name"
444 t.string "identifier" 446 t.string "identifier"
445 t.string "source" 447 t.string "source"
@@ -448,6 +450,7 @@ ActiveRecord::Schema.define(version: 20160705162914) do @@ -448,6 +450,7 @@ ActiveRecord::Schema.define(version: 20160705162914) do
448 t.boolean "visible", default: true 450 t.boolean "visible", default: true
449 t.datetime "created_at" 451 t.datetime "created_at"
450 t.datetime "updated_at" 452 t.datetime "updated_at"
  453 + t.string "type", default: "ExternalProfile"
451 end 454 end
452 455
453 create_table "favorite_enterprise_people", force: :cascade do |t| 456 create_table "favorite_enterprise_people", force: :cascade do |t|
@@ -686,9 +689,11 @@ ActiveRecord::Schema.define(version: 20160705162914) do @@ -686,9 +689,11 @@ ActiveRecord::Schema.define(version: 20160705162914) do
686 t.integer "circle_id" 689 t.integer "circle_id"
687 t.datetime "created_at" 690 t.datetime "created_at"
688 t.datetime "updated_at" 691 t.datetime "updated_at"
  692 + t.string "profile_type", default: "Person"
689 end 693 end
690 694
691 add_index "profiles_circles", ["profile_id", "circle_id"], name: "profiles_circles_composite_key_index", unique: true, using: :btree 695 add_index "profiles_circles", ["profile_id", "circle_id"], name: "profiles_circles_composite_key_index", unique: true, using: :btree
  696 + add_index "profiles_circles", ["profile_id", "profile_type"], name: "index_profiles_circles_on_profile_id_and_profile_type", using: :btree
692 697
693 create_table "qualifier_certifiers", force: :cascade do |t| 698 create_table "qualifier_certifiers", force: :cascade do |t|
694 t.integer "qualifier_id" 699 t.integer "qualifier_id"
features/step_definitions/followers_steps.rb
1 Given /^the user "(.+)" has the following circles$/ do |user_name,table| 1 Given /^the user "(.+)" has the following circles$/ do |user_name,table|
2 person = User.find_by(:login => user_name).person 2 person = User.find_by(:login => user_name).person
3 table.hashes.each do |circle| 3 table.hashes.each do |circle|
4 - Circle.create!(:person => person, :name => circle[:name], :profile_type => circle[:profile_type]) 4 + Circle.create!(:owner => person, :name => circle[:name], :profile_type => circle[:profile_type])
5 end 5 end
6 end 6 end
7 7
@@ -11,7 +11,7 @@ Then /^&quot;(.+)&quot; should be a follower of &quot;(.+)&quot; in circle &quot;(.+)&quot;$/ do |person, prof @@ -11,7 +11,7 @@ Then /^&quot;(.+)&quot; should be a follower of &quot;(.+)&quot; in circle &quot;(.+)&quot;$/ do |person, prof
11 person = Person.find_by(identifier: person) 11 person = Person.find_by(identifier: person)
12 followers.should include(person) 12 followers.should include(person)
13 13
14 - circle = Circle.find_by(:name => circle, :person => person) 14 + circle = Circle.find_by(:name => circle, :owner => person)
15 ProfileFollower.find_by(:circle => circle, :profile => profile).should_not == nil 15 ProfileFollower.find_by(:circle => circle, :profile => profile).should_not == nil
16 end 16 end
17 17
@@ -25,11 +25,11 @@ end @@ -25,11 +25,11 @@ end
25 Given /^"(.+)" is a follower of "(.+)" in circle "(.+)"$/ do |person, profile, circle| 25 Given /^"(.+)" is a follower of "(.+)" in circle "(.+)"$/ do |person, profile, circle|
26 profile = Profile.find_by(identifier: profile) 26 profile = Profile.find_by(identifier: profile)
27 person = Person.find_by(identifier: person) 27 person = Person.find_by(identifier: person)
28 - circle = Circle.find_by(:name => circle, :person => person) 28 + circle = Circle.find_by(:name => circle, :owner => person)
29 ProfileFollower.create!(:circle => circle, :profile => profile) 29 ProfileFollower.create!(:circle => circle, :profile => profile)
30 end 30 end
31 31
32 Then /^"(.+)" should have the circle "(.+)" with profile type "(.+)"$/ do |user_name, circle, profile_type| 32 Then /^"(.+)" should have the circle "(.+)" with profile type "(.+)"$/ do |user_name, circle, profile_type|
33 person = User.find_by(:login => user_name).person 33 person = User.find_by(:login => user_name).person
34 - Circle.find_by(:name => circle, :person => person, :profile_type => profile_type).should_not == nil 34 + Circle.find_by(:name => circle, :owner => person, :profile_type => profile_type).should_not == nil
35 end 35 end
test/functional/circles_controller_test.rb
@@ -10,8 +10,8 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -10,8 +10,8 @@ class CirclesControllerTest &lt; ActionController::TestCase
10 end 10 end
11 11
12 should 'return all circles of a profile' do 12 should 'return all circles of a profile' do
13 - circle1 = Circle.create!(:name => "circle1", :person => @person, :profile_type => 'Person')  
14 - circle2 = Circle.create!(:name => "circle2", :person => @person, :profile_type => 'Person') 13 + circle1 = Circle.create!(:name => "circle1", :owner => @person, :profile_type => 'Person')
  14 + circle2 = Circle.create!(:name => "circle2", :owner => @person, :profile_type => 'Person')
15 get :index, :profile => @person.identifier 15 get :index, :profile => @person.identifier
16 16
17 assert_equivalent [circle1, circle2], assigns[:circles] 17 assert_equivalent [circle1, circle2], assigns[:circles]
@@ -24,7 +24,7 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -24,7 +24,7 @@ class CirclesControllerTest &lt; ActionController::TestCase
24 end 24 end
25 25
26 should 'create a new circle' do 26 should 'create a new circle' do
27 - assert_difference '@person.circles.count' do 27 + assert_difference '@person.owned_circles.count' do
28 post :create, :profile => @person.identifier, 28 post :create, :profile => @person.identifier,
29 :circle => { :name => 'circle' , :profile_type => Person.name} 29 :circle => { :name => 'circle' , :profile_type => Person.name}
30 end 30 end
@@ -32,14 +32,14 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -32,14 +32,14 @@ class CirclesControllerTest &lt; ActionController::TestCase
32 end 32 end
33 33
34 should 'not create a circle without a name' do 34 should 'not create a circle without a name' do
35 - assert_no_difference '@person.circles.count' do 35 + assert_no_difference '@person.owned_circles.count' do
36 post :create, :profile => @person.identifier, :circle => { :name => nil } 36 post :create, :profile => @person.identifier, :circle => { :name => nil }
37 end 37 end
38 assert_template :new 38 assert_template :new
39 end 39 end
40 40
41 should 'retrieve an existing circle when editing' do 41 should 'retrieve an existing circle when editing' do
42 - circle = Circle.create!(:name => "circle", :person => @person, :profile_type => 'Person') 42 + circle = Circle.create!(:name => "circle", :owner => @person, :profile_type => 'Person')
43 get :edit, :profile => @person.identifier, :id => circle.id 43 get :edit, :profile => @person.identifier, :id => circle.id
44 assert_equal circle.name, assigns[:circle].name 44 assert_equal circle.name, assigns[:circle].name
45 end 45 end
@@ -50,7 +50,7 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -50,7 +50,7 @@ class CirclesControllerTest &lt; ActionController::TestCase
50 end 50 end
51 51
52 should 'update an existing circle' do 52 should 'update an existing circle' do
53 - circle = Circle.create!(:name => "circle", :person => @person, :profile_type => 'Person') 53 + circle = Circle.create!(:name => "circle", :owner => @person, :profile_type => 'Person')
54 post :update, :profile => @person.identifier, :id => circle.id, 54 post :update, :profile => @person.identifier, :id => circle.id,
55 :circle => { :name => "new name" } 55 :circle => { :name => "new name" }
56 56
@@ -60,7 +60,7 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -60,7 +60,7 @@ class CirclesControllerTest &lt; ActionController::TestCase
60 end 60 end
61 61
62 should 'not update an existing circle without a name' do 62 should 'not update an existing circle without a name' do
63 - circle = Circle.create!(:name => "circle", :person => @person, :profile_type => 'Person') 63 + circle = Circle.create!(:name => "circle", :owner => @person, :profile_type => 'Person')
64 post :update, :profile => @person.identifier, :id => circle.id, 64 post :update, :profile => @person.identifier, :id => circle.id,
65 :circle => { :name => nil } 65 :circle => { :name => nil }
66 66
@@ -75,18 +75,18 @@ class CirclesControllerTest &lt; ActionController::TestCase @@ -75,18 +75,18 @@ class CirclesControllerTest &lt; ActionController::TestCase
75 end 75 end
76 76
77 should 'destroy an existing circle and remove related profiles' do 77 should 'destroy an existing circle and remove related profiles' do
78 - circle = Circle.create!(:name => "circle", :person => @person, :profile_type => 'Person') 78 + circle = Circle.create!(:name => "circle", :owner => @person, :profile_type => 'Person')
79 fast_create(ProfileFollower, :profile_id => fast_create(Person).id, :circle_id => circle.id) 79 fast_create(ProfileFollower, :profile_id => fast_create(Person).id, :circle_id => circle.id)
80 80
81 - assert_difference ["@person.circles.count", 'ProfileFollower.count'], -1 do 81 + assert_difference ["@person.owned_circles.count", 'ProfileFollower.count'], -1 do
82 post :destroy, :profile => @person.identifier, :id => circle.id 82 post :destroy, :profile => @person.identifier, :id => circle.id
83 end 83 end
84 end 84 end
85 85
86 should 'not destroy an existing circle if action is not post' do 86 should 'not destroy an existing circle if action is not post' do
87 - circle = Circle.create!(:name => "circle", :person => @person, :profile_type => 'Person') 87 + circle = Circle.create!(:name => "circle", :owner => @person, :profile_type => 'Person')
88 88
89 - assert_no_difference "@person.circles.count" do 89 + assert_no_difference "@person.owned_circles.count" do
90 get :destroy, :profile => @person.identifier, :id => circle.id 90 get :destroy, :profile => @person.identifier, :id => circle.id
91 end 91 end
92 assert_response 404 92 assert_response 404
test/functional/followers_controller_test.rb
@@ -9,8 +9,8 @@ class FollowersControllerTest &lt; ActionController::TestCase @@ -9,8 +9,8 @@ class FollowersControllerTest &lt; ActionController::TestCase
9 should 'return followed people list' do 9 should 'return followed people list' do
10 login_as(@profile.identifier) 10 login_as(@profile.identifier)
11 person = fast_create(Person) 11 person = fast_create(Person)
12 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
13 - fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 12 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  13 + ProfileFollower.create(:profile => person, :circle => circle)
14 14
15 get :index, :profile => @profile.identifier 15 get :index, :profile => @profile.identifier
16 assert_includes assigns(:followed_people), person 16 assert_includes assigns(:followed_people), person
@@ -20,10 +20,10 @@ class FollowersControllerTest &lt; ActionController::TestCase @@ -20,10 +20,10 @@ class FollowersControllerTest &lt; ActionController::TestCase
20 login_as(@profile.identifier) 20 login_as(@profile.identifier)
21 person = fast_create(Person) 21 person = fast_create(Person)
22 community = fast_create(Community) 22 community = fast_create(Community)
23 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
24 - circle2 = Circle.create!(:person=> @profile, :name => "Teams", :profile_type => 'Community')  
25 - fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id)  
26 - fast_create(ProfileFollower, :profile_id => community.id, :circle_id => circle2.id) 23 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  24 + circle2 = Circle.create!(:owner=> @profile, :name => "Teams", :profile_type => 'Community')
  25 + ProfileFollower.create(:profile => person, :circle => circle)
  26 + ProfileFollower.create(:profile => community, :circle => circle2)
27 27
28 get :index, :profile => @profile.identifier, :filter => "Community" 28 get :index, :profile => @profile.identifier, :filter => "Community"
29 assert_equal assigns(:followed_people), [community] 29 assert_equal assigns(:followed_people), [community]
@@ -47,8 +47,8 @@ class FollowersControllerTest &lt; ActionController::TestCase @@ -47,8 +47,8 @@ class FollowersControllerTest &lt; ActionController::TestCase
47 should 'update followed person category' do 47 should 'update followed person category' do
48 login_as(@profile.identifier) 48 login_as(@profile.identifier)
49 person = fast_create(Person) 49 person = fast_create(Person)
50 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
51 - circle2 = Circle.create!(:person=> @profile, :name => "DotA", :profile_type => 'Person') 50 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  51 + circle2 = Circle.create!(:owner=> @profile, :name => "DotA", :profile_type => 'Person')
52 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 52 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id)
53 53
54 post :update_category, :profile => @profile.identifier, :circles => {"DotA"=> circle2.id}, :followed_profile_id => person.id 54 post :update_category, :profile => @profile.identifier, :circles => {"DotA"=> circle2.id}, :followed_profile_id => person.id
test/functional/profile_controller_test.rb
@@ -773,7 +773,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -773,7 +773,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
773 end 773 end
774 774
775 should 'not see the followers activities in the current profile' do 775 should 'not see the followers activities in the current profile' do
776 - circle = Circle.create!(:person=> profile, :name => "Zombies", :profile_type => 'Person') 776 + circle = Circle.create!(:owner=> profile, :name => "Zombies", :profile_type => 'Person')
777 777
778 p2 = create_user.person 778 p2 = create_user.person
779 refute profile.follows?(p2) 779 refute profile.follows?(p2)
@@ -969,7 +969,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -969,7 +969,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
969 login_as(profile.identifier) 969 login_as(profile.identifier)
970 p1= fast_create(Person) 970 p1= fast_create(Person)
971 971
972 - circle = Circle.create!(:person=> profile, :name => "Zombies", :profile_type => 'Person') 972 + circle = Circle.create!(:owner=> profile, :name => "Zombies", :profile_type => 'Person')
973 973
974 profile.follow(p1, circle) 974 profile.follow(p1, circle)
975 975
@@ -1993,7 +1993,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1993,7 +1993,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1993 login_as(@profile.identifier) 1993 login_as(@profile.identifier)
1994 person = fast_create(Person) 1994 person = fast_create(Person)
1995 1995
1996 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person') 1996 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
1997 1997
1998 assert_difference 'ProfileFollower.count' do 1998 assert_difference 'ProfileFollower.count' do
1999 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id} 1999 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id}
@@ -2004,8 +2004,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2004,8 +2004,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2004 login_as(@profile.identifier) 2004 login_as(@profile.identifier)
2005 person = fast_create(Person) 2005 person = fast_create(Person)
2006 2006
2007 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2008 - circle2 = Circle.create!(:person=> @profile, :name => "Brainsss", :profile_type => 'Person') 2007 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2008 + circle2 = Circle.create!(:owner=> @profile, :name => "Brainsss", :profile_type => 'Person')
2009 2009
2010 assert_difference 'ProfileFollower.count', 2 do 2010 assert_difference 'ProfileFollower.count', 2 do
2011 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id, "Brainsss"=> circle2.id} 2011 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id, "Brainsss"=> circle2.id}
@@ -2016,8 +2016,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2016,8 +2016,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2016 login_as(@profile.identifier) 2016 login_as(@profile.identifier)
2017 person = fast_create(Person) 2017 person = fast_create(Person)
2018 2018
2019 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2020 - circle2 = Circle.create!(:person=> @profile, :name => "Brainsss", :profile_type => 'Person') 2019 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2020 + circle2 = Circle.create!(:owner=> @profile, :name => "Brainsss", :profile_type => 'Person')
2021 2021
2022 assert_no_difference 'ProfileFollower.count' do 2022 assert_no_difference 'ProfileFollower.count' do
2023 post :follow, :profile => person.identifier, :circles => {"Zombies" => "0", "Brainsss" => "0"} 2023 post :follow, :profile => person.identifier, :circles => {"Zombies" => "0", "Brainsss" => "0"}
@@ -2030,11 +2030,11 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2030,11 +2030,11 @@ class ProfileControllerTest &lt; ActionController::TestCase
2030 login_as(@profile.identifier) 2030 login_as(@profile.identifier)
2031 person = fast_create(Person) 2031 person = fast_create(Person)
2032 2032
2033 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2034 - fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2033 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2034 + ProfileFollower.create(:profile => person, :circle => circle)
2035 2035
2036 assert_no_difference 'ProfileFollower.count' do 2036 assert_no_difference 'ProfileFollower.count' do
2037 - post :follow, :profile => person.identifier, :follow => { :circles => {"Zombies" => circle.id} } 2037 + post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id}
2038 end 2038 end
2039 assert_response 400 2039 assert_response 400
2040 end 2040 end
@@ -2050,8 +2050,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2050,8 +2050,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2050 login_as(@profile.identifier) 2050 login_as(@profile.identifier)
2051 person = fast_create(Person) 2051 person = fast_create(Person)
2052 2052
2053 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2054 - follower = fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2053 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2054 + follower = ProfileFollower.create!(:profile => person, circle: circle)
2055 2055
2056 assert_not_nil follower 2056 assert_not_nil follower
2057 2057
@@ -2073,7 +2073,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2073,7 +2073,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2073 login_as(@profile.identifier) 2073 login_as(@profile.identifier)
2074 person = fast_create(Person) 2074 person = fast_create(Person)
2075 2075
2076 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person') 2076 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
2077 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2077 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id)
2078 2078
2079 post :unfollow, :profile => person.identifier, :redirect_to => "/some/url" 2079 post :unfollow, :profile => person.identifier, :redirect_to => "/some/url"
@@ -2082,8 +2082,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2082,8 +2082,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2082 2082
2083 should "search followed people or circles" do 2083 should "search followed people or circles" do
2084 login_as(@profile.identifier) 2084 login_as(@profile.identifier)
2085 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person)  
2086 - c2 = Circle.create!(:name => 'Work', :person => @profile, :profile_type => Person) 2085 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
  2086 + c2 = Circle.create!(:name => 'Work', :owner => @profile, :profile_type => Person)
2087 p1 = create_user('emily').person 2087 p1 = create_user('emily').person
2088 p2 = create_user('wollie').person 2088 p2 = create_user('wollie').person
2089 p3 = create_user('mary').person 2089 p3 = create_user('mary').person
@@ -2115,7 +2115,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2115,7 +2115,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2115 2115
2116 should 'treat followed entries' do 2116 should 'treat followed entries' do
2117 login_as(@profile.identifier) 2117 login_as(@profile.identifier)
2118 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2118 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2119 p1 = create_user('emily').person 2119 p1 = create_user('emily').person
2120 p2 = create_user('wollie').person 2120 p2 = create_user('wollie').person
2121 p3 = create_user('mary').person 2121 p3 = create_user('mary').person
@@ -2132,7 +2132,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2132,7 +2132,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2132 2132
2133 should 'return empty followed entries if the user is not on his wall' do 2133 should 'return empty followed entries if the user is not on his wall' do
2134 login_as(@profile.identifier) 2134 login_as(@profile.identifier)
2135 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2135 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2136 p1 = create_user('emily').person 2136 p1 = create_user('emily').person
2137 p2 = create_user('wollie').person 2137 p2 = create_user('wollie').person
2138 p3 = create_user('mary').person 2138 p3 = create_user('mary').person
@@ -2149,7 +2149,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2149,7 +2149,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2149 2149
2150 should 'leave private scrap' do 2150 should 'leave private scrap' do
2151 login_as(@profile.identifier) 2151 login_as(@profile.identifier)
2152 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2152 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2153 p1 = create_user('emily').person 2153 p1 = create_user('emily').person
2154 p2 = create_user('wollie').person 2154 p2 = create_user('wollie').person
2155 ProfileFollower.create!(:profile => p1, :circle => c1) 2155 ProfileFollower.create!(:profile => p1, :circle => c1)
@@ -2165,7 +2165,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2165,7 +2165,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2165 end 2165 end
2166 2166
2167 should 'list private scraps on wall for marked people' do 2167 should 'list private scraps on wall for marked people' do
2168 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2168 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2169 p1 = create_user('emily').person 2169 p1 = create_user('emily').person
2170 ProfileFollower.create!(:profile => p1, :circle => c1) 2170 ProfileFollower.create!(:profile => p1, :circle => c1)
2171 p1.add_friend(@profile) 2171 p1.add_friend(@profile)
@@ -2179,7 +2179,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2179,7 +2179,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2179 end 2179 end
2180 2180
2181 should 'not list private scraps on wall for not marked people' do 2181 should 'not list private scraps on wall for not marked people' do
2182 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2182 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2183 p1 = create_user('emily').person 2183 p1 = create_user('emily').person
2184 p2 = create_user('wollie').person 2184 p2 = create_user('wollie').person
2185 not_marked = create_user('jack').person 2185 not_marked = create_user('jack').person
@@ -2197,7 +2197,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2197,7 +2197,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2197 end 2197 end
2198 2198
2199 should 'list private scraps on wall for creator' do 2199 should 'list private scraps on wall for creator' do
2200 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2200 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2201 p1 = create_user('emily').person 2201 p1 = create_user('emily').person
2202 ProfileFollower.create!(:profile => p1, :circle => c1) 2202 ProfileFollower.create!(:profile => p1, :circle => c1)
2203 scrap = Scrap.create!(:content => 'Secret message.', :sender_id => @profile.id, :receiver_id => @profile.id, :marked_people => [p1]) 2203 scrap = Scrap.create!(:content => 'Secret message.', :sender_id => @profile.id, :receiver_id => @profile.id, :marked_people => [p1])
@@ -2210,7 +2210,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2210,7 +2210,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2210 end 2210 end
2211 2211
2212 should 'list private scraps on wall for environment administrator' do 2212 should 'list private scraps on wall for environment administrator' do
2213 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2213 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2214 p1 = create_user('emily').person 2214 p1 = create_user('emily').person
2215 admin = create_user('env-admin').person 2215 admin = create_user('env-admin').person
2216 env = @profile.environment 2216 env = @profile.environment
@@ -2227,7 +2227,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2227,7 +2227,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2227 end 2227 end
2228 2228
2229 should 'list private scraps on network for marked people' do 2229 should 'list private scraps on network for marked people' do
2230 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2230 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2231 p1 = create_user('emily').person 2231 p1 = create_user('emily').person
2232 p2 = create_user('wollie').person 2232 p2 = create_user('wollie').person
2233 p2.add_friend(p1) 2233 p2.add_friend(p1)
@@ -2245,7 +2245,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2245,7 +2245,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2245 end 2245 end
2246 2246
2247 should 'not list private scraps on network for not marked people' do 2247 should 'not list private scraps on network for not marked people' do
2248 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2248 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2249 p1 = create_user('emily').person 2249 p1 = create_user('emily').person
2250 not_marked = create_user('jack').person 2250 not_marked = create_user('jack').person
2251 not_marked.add_friend(p1) 2251 not_marked.add_friend(p1)
@@ -2262,7 +2262,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2262,7 +2262,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2262 end 2262 end
2263 2263
2264 should 'list private scraps on network for creator' do 2264 should 'list private scraps on network for creator' do
2265 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2265 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2266 p1 = create_user('emily').person 2266 p1 = create_user('emily').person
2267 p1.add_friend(@profile) 2267 p1.add_friend(@profile)
2268 ProfileFollower.create!(:profile => p1, :circle => c1) 2268 ProfileFollower.create!(:profile => p1, :circle => c1)
@@ -2277,7 +2277,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2277,7 +2277,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2277 end 2277 end
2278 2278
2279 should 'list private scraps on network for environment admin' do 2279 should 'list private scraps on network for environment admin' do
2280 - c1 = Circle.create!(:name => 'Family', :person => @profile, :profile_type => Person) 2280 + c1 = Circle.create!(:name => 'Family', :owner => @profile, :profile_type => Person)
2281 p1 = create_user('emily').person 2281 p1 = create_user('emily').person
2282 admin = create_user('env-admin').person 2282 admin = create_user('env-admin').person
2283 env = @profile.environment 2283 env = @profile.environment
test/unit/article_test.rb
@@ -1101,7 +1101,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1101,7 +1101,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1101 1101
1102 should 'create notifications to followers when creating an article' do 1102 should 'create notifications to followers when creating an article' do
1103 friend = fast_create(Person) 1103 friend = fast_create(Person)
1104 - circle = Circle.create!(:person=> friend, :name => "Zombies", :profile_type => 'Person') 1104 + circle = Circle.create!(:owner=> friend, :name => "Zombies", :profile_type => 'Person')
1105 friend.follow(profile, circle) 1105 friend.follow(profile, circle)
1106 Article.destroy_all 1106 Article.destroy_all
1107 ActionTracker::Record.destroy_all 1107 ActionTracker::Record.destroy_all
@@ -1115,7 +1115,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1115,7 +1115,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1115 1115
1116 should 'create the notification to the follower when one follower has the notification and the other no' do 1116 should 'create the notification to the follower when one follower has the notification and the other no' do
1117 f1 = fast_create(Person) 1117 f1 = fast_create(Person)
1118 - circle = Circle.create!(:person=> f1, :name => "Zombies", :profile_type => 'Person') 1118 + circle = Circle.create!(:owner=> f1, :name => "Zombies", :profile_type => 'Person')
1119 f1.follow(profile, circle) 1119 f1.follow(profile, circle)
1120 1120
1121 User.current = profile.user 1121 User.current = profile.user
@@ -1125,7 +1125,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1125,7 +1125,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1125 assert_equal 2, ActionTrackerNotification.where(action_tracker_id: article.activity.id).count 1125 assert_equal 2, ActionTrackerNotification.where(action_tracker_id: article.activity.id).count
1126 1126
1127 f2 = fast_create(Person) 1127 f2 = fast_create(Person)
1128 - circle2 = Circle.create!(:person=> f2, :name => "Zombies", :profile_type => 'Person') 1128 + circle2 = Circle.create!(:owner=> f2, :name => "Zombies", :profile_type => 'Person')
1129 f2.follow(profile, circle2) 1129 f2.follow(profile, circle2)
1130 1130
1131 article2 = create TinyMceArticle, :name => 'Tracked Article 2', :profile_id => profile.id 1131 article2 = create TinyMceArticle, :name => 'Tracked Article 2', :profile_id => profile.id
@@ -1137,7 +1137,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1137,7 +1137,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1137 should 'destroy activity and notifications of followers when destroying an article' do 1137 should 'destroy activity and notifications of followers when destroying an article' do
1138 friend = fast_create(Person) 1138 friend = fast_create(Person)
1139 1139
1140 - circle = Circle.create!(:person=> friend, :name => "Zombies", :profile_type => 'Person') 1140 + circle = Circle.create!(:owner=> friend, :name => "Zombies", :profile_type => 'Person')
1141 1141
1142 friend.follow(profile, circle) 1142 friend.follow(profile, circle)
1143 1143
test/unit/external_person_test.rb
@@ -134,4 +134,30 @@ class ExternalPersonTest &lt; ActiveSupport::TestCase @@ -134,4 +134,30 @@ class ExternalPersonTest &lt; ActiveSupport::TestCase
134 assert_respond_to ExternalPerson.new, method.to_sym unless method =~ /^autosave_.*|validate_.*|^before_.*|^after_.*|^assignment_.*|^(city|state)_.*/ 134 assert_respond_to ExternalPerson.new, method.to_sym unless method =~ /^autosave_.*|validate_.*|^before_.*|^after_.*|^assignment_.*|^(city|state)_.*/
135 end 135 end
136 end 136 end
  137 +
  138 + should 'raise error if method is not in Person or Profile' do
  139 + assert_raise NoMethodError do
  140 + ExternalPerson.new.send(:this_method_does_not_exist_right?)
  141 + end
  142 + end
  143 +
  144 + should 'be able to follow people' do
  145 + person = fast_create(Person, :environment_id => Environment.default.id)
  146 + circle = Circle.create(owner: @external_person, profile_type: "Person", name: "FRIENDSSS")
  147 +
  148 + assert_difference "@external_person.followed_profiles.count" do
  149 + @external_person.follow(person, circle)
  150 + end
  151 + end
  152 +
  153 + should 'be able to unfolllow people' do
  154 + person = fast_create(Person, :environment_id => Environment.default.id)
  155 + circle = Circle.create(owner: @external_person, profile_type: "Person", name: "FRIENDSSS")
  156 + @external_person.follow(person, circle)
  157 +
  158 + assert_difference "@external_person.followed_profiles.count", -1 do
  159 + @external_person.unfollow(person)
  160 + end
  161 + end
  162 +
137 end 163 end
test/unit/followable_test.rb 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class FollowableTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @person1 = create_user('perso-test-1').person
  7 + @person2 = create_user('person-test-2').person
  8 + @external_person = ExternalPerson.create!(identifier: 'johnlocke',
  9 + name: 'John Locke',
  10 + source: 'anerenvironment.org',
  11 + email: 'locke@island.org',
  12 + created_at: Date.yesterday)
  13 +
  14 + @circle1 = Circle.create!(owner: @person1, name: "Zombies", profile_type: 'Person')
  15 + @circle2 = Circle.create!(owner: @person1, name: "Humans", profile_type: 'Person')
  16 + @circle3 = Circle.create!(owner: @external_person, name: "Crypt", profile_type: 'Person')
  17 +
  18 + @external_profile = ExternalProfile.create
  19 + end
  20 +
  21 + should 'return all unique circles and followers of a profile' do
  22 + @person1.follow(@person2, @circle1)
  23 + @person1.follow(@person2, @circle2)
  24 + @external_person.follow(@person2, @circle3)
  25 +
  26 + assert_equivalent [@circle1, @circle2, @circle3], @person2.circles
  27 + assert_equivalent [@person1, @external_person], @person2.followers
  28 + end
  29 +
  30 + should 'return all unique circles and followers of a external profile' do
  31 + Circle.any_instance.stubs(:profile_type).returns("ExternalProfile")
  32 + @person1.follow(@external_profile, @circle1)
  33 + @person1.follow(@external_profile, @circle2)
  34 + @external_person.follow(@external_profile, @circle3)
  35 +
  36 + assert_equivalent [@circle1, @circle2, @circle3], @external_profile.circles
  37 + assert_equivalent [@person1, @external_person], @external_profile.followers
  38 + end
  39 +
  40 + should 'onlyreturn true if profile is in circle' do
  41 + @person1.follow(@person2, @circle1)
  42 + @external_person.follow(@person2, @circle3)
  43 +
  44 + assert @person2.in_circle? @circle1
  45 + assert @person2.in_circle? @circle3
  46 + refute @person2.in_circle? @circle2
  47 + end
  48 +
  49 + should 'only return true if external profile is in circle' do
  50 + Circle.any_instance.stubs(:profile_type).returns("ExternalProfile")
  51 + @person1.follow(@external_profile, @circle1)
  52 + @external_person.follow(@external_profile, @circle3)
  53 +
  54 + assert @external_profile.in_circle? @circle1
  55 + assert @external_profile.in_circle? @circle3
  56 + refute @external_profile.in_circle? @circle2
  57 + end
  58 +
  59 +end
test/unit/follower_test.rb 0 → 100644
@@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class FollowerTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @person1 = create_user('perso-test-1').person
  7 + @person2 = create_user('person-test-2').person
  8 +
  9 + @circle1 = Circle.create!(owner: @person1, name: "Zombies", profile_type: 'Person')
  10 + @circle2 = Circle.create!(owner: @person1, name: "Humans", profile_type: 'Person')
  11 + @circle3 = Circle.create!(owner: @person1, name: "Crypt", profile_type: 'Community')
  12 +
  13 + @external_person = ExternalPerson.create!(identifier: 'johnlocke',
  14 + name: 'John Locke',
  15 + source: 'anerenvironment.org',
  16 + email: 'locke@island.org',
  17 + created_at: Date.yesterday)
  18 + end
  19 +
  20 + should 'follows? return false when no profile is passed as parameter' do
  21 + assert_equal false, @person1.follows?(nil)
  22 + end
  23 +
  24 + should 'follow person with regular user' do
  25 + assert_difference '@person1.followed_profiles.count' do
  26 + @person1.follow(@person2, @circle1)
  27 + end
  28 + assert @person1.follows?(@person2)
  29 + end
  30 +
  31 + should 'follow a community' do
  32 + community = fast_create(Community)
  33 + circle = Circle.create!(owner: @person1, name: "Terminus", profile_type: 'Community')
  34 +
  35 + assert_difference '@person1.followed_profiles.count' do
  36 + @person1.follow(community, circle)
  37 + end
  38 + assert @person1.follows?(community)
  39 + end
  40 +
  41 + should 'not follow person if the user is not the owner of the circle' do
  42 + person3 = create_user('perso-test-3').person
  43 +
  44 + assert_no_difference '@circle1.owner.followed_profiles.count' do
  45 + person3.follow(@person2, @circle1)
  46 + end
  47 + assert_not @circle1.owner.follows?(@person2)
  48 + end
  49 +
  50 + should 'not follow a community if circle profile type does not match' do
  51 + community = fast_create(Community)
  52 +
  53 + assert_no_difference '@person1.followed_profiles.count' do
  54 + @person1.follow(community, @circle1)
  55 + end
  56 + assert_not @person1.follows?(community)
  57 + end
  58 +
  59 + should 'follow person with external user' do
  60 + @circle1.update_attributes(owner: @external_person)
  61 +
  62 + assert_difference '@external_person.followed_profiles.count' do
  63 + @external_person.follow(@person2, @circle1)
  64 + end
  65 + assert @external_person.follows?(@person2)
  66 + end
  67 +
  68 + should 'unfollow person with regular user' do
  69 + @person1.follow(@person2, @circle1)
  70 +
  71 + assert_difference '@person1.followed_profiles.count', -1 do
  72 + @person1.unfollow(@person2)
  73 + end
  74 + assert_not @person1.follows?(@person2)
  75 + end
  76 +
  77 + should 'unfollow person with external user' do
  78 + @circle1.update_attributes(owner: @external_person)
  79 + @external_person.follow(@person2, @circle1)
  80 +
  81 + assert_difference '@external_person.followed_profiles.count', -1 do
  82 + @external_person.unfollow(@person2)
  83 + end
  84 + assert_not @external_person.follows?(@person2)
  85 + end
  86 +
  87 + should 'get the followed profiles for a regular user' do
  88 + community = fast_create(Community)
  89 +
  90 + @person1.follow(@person2, @circle1)
  91 + @person1.follow(@external_person, @circle1)
  92 + @person1.follow(community, @circle3)
  93 + assert_equivalent [@person2, @external_person, community],
  94 + @person1.followed_profiles
  95 + end
  96 +
  97 + should 'get the followed profiles for an external user' do
  98 + person3 = create_user('person-test-3').person
  99 + community = fast_create(Community)
  100 + @circle1.update_attributes(owner: @external_person)
  101 + @circle3.update_attributes(owner: @external_person)
  102 +
  103 + @external_person.follow(@person2, @circle1)
  104 + @external_person.follow(person3, @circle1)
  105 + @external_person.follow(community, @circle3)
  106 + assert_equivalent [@person2, person3, community],
  107 + @external_person.followed_profiles
  108 + end
  109 +
  110 + should 'not follow same person twice even with different circles' do
  111 + circle4 = Circle.create!(owner: @person1, name: "Free Folk", profile_type: 'Person')
  112 +
  113 + @person1.follow(@person2, @circle1)
  114 + @person1.follow(@person2, @circle2)
  115 + @person1.follow(@person2, circle4)
  116 + assert_equivalent [@person2], @person1.followed_profiles
  117 + end
  118 +
  119 + should 'display an error if a person is already being followed' do
  120 + @person1.follow(@person2, @circle1)
  121 + profile_follower = ProfileFollower.new(circle: @circle1, profile: @person2)
  122 +
  123 + profile_follower.valid?
  124 + assert profile_follower.errors.messages[:profile_id].present?
  125 + end
  126 +
  127 + should 'update profile circles for a person' do
  128 + circle4 = Circle.create!(owner: @person1, name: "Brains", profile_type: 'Person')
  129 + @person1.follow(@person2, [@circle1, @circle2])
  130 +
  131 + @person1.update_profile_circles(@person2, [@circle2, circle4])
  132 + assert_equivalent [@circle2, circle4], @person2.circles
  133 + end
  134 +
  135 + should 'keep other follower circles after update' do
  136 + person3 = create_user('person-test-3').person
  137 + circle4 = Circle.create!(owner: person3, name: "Humans", profile_type: 'Person')
  138 + @person1.follow(@person2, @circle1)
  139 + person3.follow(@person2, circle4)
  140 +
  141 + @person1.update_profile_circles(@person2, [@circle1, @circle2])
  142 + assert_equivalent [@circle1, @circle2, circle4], @person2.circles
  143 + end
  144 +
  145 + should 'remove a person from a circle' do
  146 + @person1.follow(@person2, [@circle1, @circle2])
  147 +
  148 + @person1.remove_profile_from_circle(@person2, @circle2)
  149 + assert @person2.in_circle? @circle1
  150 + assert_not @person2.in_circle? @circle2
  151 + end
  152 +
  153 + should 'not remove a person from a circle if the user is not the owner' do
  154 + person3 = create_user('person-test-3').person
  155 + @person1.follow(@person2, [@circle1, @circle2])
  156 +
  157 + person3.remove_profile_from_circle(@person2, @circle2)
  158 + assert @person2.in_circle? @circle1
  159 + assert @person2.in_circle? @circle2
  160 + end
  161 +
  162 + should 'follow external profile' do
  163 + external_profile = ExternalProfile.create
  164 + @circle1.stubs(:profile_type).returns("ExternalProfile")
  165 +
  166 + assert_difference '@person1.followed_profiles.count' do
  167 + @person1.follow(external_profile, @circle1)
  168 + end
  169 + assert @person1.follows? external_profile
  170 + assert_equivalent [external_profile], @person1.followed_profiles
  171 + end
  172 +
  173 + should 'unfollow external profile' do
  174 + external_profile = ExternalProfile.create
  175 + @circle1.stubs(:profile_type).returns("ExternalProfile")
  176 + @person1.follow(external_profile, @circle1)
  177 +
  178 + assert_difference '@person1.followed_profiles.count', -1 do
  179 + @person1.unfollow(external_profile)
  180 + end
  181 + assert_not @person1.follows?(@person2)
  182 + end
  183 +
  184 +end
test/unit/friendship_test.rb
@@ -81,8 +81,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase @@ -81,8 +81,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase
81 p2.add_friend(p1, 'friends') 81 p2.add_friend(p1, 'friends')
82 end 82 end
83 83
84 - assert_includes p1.followers(true), p2  
85 - assert_includes p2.followers(true), p1 84 + assert_includes p1.followers, p2
  85 + assert_includes p2.followers, p1
86 end 86 end
87 87
88 should 'remove follower when a friend removal occurs' do 88 should 'remove follower when a friend removal occurs' do
@@ -94,8 +94,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase @@ -94,8 +94,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase
94 94
95 Friendship.remove_friendship(p1, p2) 95 Friendship.remove_friendship(p1, p2)
96 96
97 - assert_not_includes p1.followers(true), p2  
98 - assert_not_includes p2.followers(true), p1 97 + assert_not_includes p1.followers, p2
  98 + assert_not_includes p2.followers, p1
99 end 99 end
100 100
101 should 'keep friendship intact when stop following' do 101 should 'keep friendship intact when stop following' do
@@ -115,8 +115,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase @@ -115,8 +115,8 @@ class FriendshipTest &lt; ActiveSupport::TestCase
115 p1 = create_user('testuser1').person 115 p1 = create_user('testuser1').person
116 p2 = create_user('testuser2').person 116 p2 = create_user('testuser2').person
117 117
118 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
119 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person') 118 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
  119 + circle2 = Circle.create!(:owner=> p2, :name => "Zombies", :profile_type => 'Person')
120 p1.follow(p2, circle1) 120 p1.follow(p2, circle1)
121 p2.follow(p1, circle2) 121 p2.follow(p1, circle2)
122 122
test/unit/notify_activity_to_profiles_job_test.rb
@@ -31,9 +31,9 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -31,9 +31,9 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
31 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb) 31 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)
32 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person) 32 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)
33 33
34 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
35 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person')  
36 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Person') 34 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
  35 + circle2 = Circle.create!(:owner=> p2, :name => "Zombies", :profile_type => 'Person')
  36 + circle = Circle.create!(:owner=> person, :name => "Zombies", :profile_type => 'Person')
37 37
38 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id) 38 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id)
39 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle2.id) 39 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle2.id)
@@ -54,7 +54,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -54,7 +54,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
54 54
55 should 'notify only marked people on marked scraps' do 55 should 'notify only marked people on marked scraps' do
56 profile = create_user('scrap-creator').person 56 profile = create_user('scrap-creator').person
57 - c1 = Circle.create!(:name => 'Family', :person => profile, :profile_type => Person) 57 + c1 = Circle.create!(:name => 'Family', :owner => profile, :profile_type => Person)
58 p1 = create_user('emily').person 58 p1 = create_user('emily').person
59 p2 = create_user('wollie').person 59 p2 = create_user('wollie').person
60 not_marked = create_user('jack').person 60 not_marked = create_user('jack').person
@@ -100,7 +100,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -100,7 +100,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
100 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb) 100 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)
101 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person) 101 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)
102 102
103 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person') 103 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
104 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id) 104 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id)
105 105
106 fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id) 106 fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id)
@@ -148,8 +148,8 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -148,8 +148,8 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
148 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb) 148 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)
149 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person) 149 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)
150 150
151 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
152 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person') 151 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
  152 + circle2 = Circle.create!(:owner=> p2, :name => "Zombies", :profile_type => 'Person')
153 153
154 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id) 154 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id)
155 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle2.id) 155 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle2.id)
test/unit/organization_test.rb
@@ -267,9 +267,9 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -267,9 +267,9 @@ class OrganizationTest &lt; ActiveSupport::TestCase
267 o.add_member(p3) 267 o.add_member(p3)
268 assert p3.is_member_of?(o) 268 assert p3.is_member_of?(o)
269 269
270 - assert_equal true, o.send(:followed_by?,p1)  
271 - assert_equal true, o.send(:followed_by?,p3)  
272 - assert_equal false, o.send(:followed_by?,p2) 270 + assert o.followed_by? p1
  271 + assert o.followed_by? p3
  272 + refute o.followed_by? p2
273 end 273 end
274 274
275 should "compose bare jabber id by identifier plus 'conference' and default hostname" do 275 should "compose bare jabber id by identifier plus 'conference' and default hostname" do
test/unit/person_test.rb
@@ -843,8 +843,8 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -843,8 +843,8 @@ class PersonTest &lt; ActiveSupport::TestCase
843 p3 = fast_create(Person) 843 p3 = fast_create(Person)
844 p4 = fast_create(Person) 844 p4 = fast_create(Person)
845 845
846 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person')  
847 - circle4 = Circle.create!(:person=> p4, :name => "Zombies", :profile_type => 'Person') 846 + circle2 = Circle.create!(:owner => p2, :name => "Zombies", :profile_type => 'Person')
  847 + circle4 = Circle.create!(:owner => p4, :name => "Zombies", :profile_type => 'Person')
848 848
849 p2.follow(p1, circle2) 849 p2.follow(p1, circle2)
850 assert p2.follows?(p1) 850 assert p2.follows?(p1)
@@ -889,8 +889,8 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -889,8 +889,8 @@ class PersonTest &lt; ActiveSupport::TestCase
889 p3 = fast_create(Person) 889 p3 = fast_create(Person)
890 p4 = fast_create(Person) 890 p4 = fast_create(Person)
891 891
892 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person')  
893 - circle4 = Circle.create!(:person=> p4, :name => "Zombies", :profile_type => 'Person') 892 + circle2 = Circle.create!(:owner => p2, :name => "Zombies", :profile_type => 'Person')
  893 + circle4 = Circle.create!(:owner => p4, :name => "Zombies", :profile_type => 'Person')
894 p2.follow(p1, circle2) 894 p2.follow(p1, circle2)
895 assert p2.follows?(p1) 895 assert p2.follows?(p1)
896 refute p3.follows?(p1) 896 refute p3.follows?(p1)
@@ -1640,11 +1640,6 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1640,11 +1640,6 @@ class PersonTest &lt; ActiveSupport::TestCase
1640 assert person.can_change_homepage? 1640 assert person.can_change_homepage?
1641 end 1641 end
1642 1642
1643 - should 'follow? return false when no profile is passed as parameter' do  
1644 - person = Person.new  
1645 - assert_equal false, person.follows?(nil)  
1646 - end  
1647 -  
1648 should 'allow posting content when has post_content permission' do 1643 should 'allow posting content when has post_content permission' do
1649 person = create_user('person').person 1644 person = create_user('person').person
1650 profile = mock 1645 profile = mock
@@ -1957,53 +1952,4 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1957,53 +1952,4 @@ class PersonTest &lt; ActiveSupport::TestCase
1957 person.user.expects(:save!).never 1952 person.user.expects(:save!).never
1958 person.save! 1953 person.save!
1959 end 1954 end
1960 -  
1961 - should 'update profile circles for a person' do  
1962 - person = create_user('testuser').person  
1963 - community = fast_create(Community)  
1964 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Community')  
1965 - circle2 = Circle.create!(:person=> person, :name => "Dota", :profile_type => 'Community')  
1966 - circle3 = Circle.create!(:person=> person, :name => "Quadrado", :profile_type => 'Community')  
1967 - person.follow(community, [circle, circle2])  
1968 - person.update_profile_circles(community, [circle2, circle3])  
1969 - assert_equivalent [circle2, circle3], ProfileFollower.with_profile(community).with_follower(person).map(&:circle)  
1970 - end  
1971 -  
1972 - should 'a person follow a profile' do  
1973 - person = create_user('testuser').person  
1974 - community = fast_create(Community)  
1975 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Community')  
1976 - person.follow(community, circle)  
1977 - assert_includes person.followed_profiles, community  
1978 - end  
1979 -  
1980 - should 'a person follow a profile with more than one circle' do  
1981 - person = create_user('testuser').person  
1982 - community = fast_create(Community)  
1983 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Community')  
1984 - circle2 = Circle.create!(:person=> person, :name => "Dota", :profile_type => 'Community')  
1985 - person.follow(community, [circle, circle2])  
1986 - assert_includes person.followed_profiles, community  
1987 - assert_equivalent [circle, circle2], ProfileFollower.with_profile(community).with_follower(person).map(&:circle)  
1988 - end  
1989 -  
1990 - should 'a person unfollow a profile' do  
1991 - person = create_user('testuser').person  
1992 - community = fast_create(Community)  
1993 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Community')  
1994 - person.follow(community, circle)  
1995 - person.unfollow(community)  
1996 - assert_not_includes person.followed_profiles, community  
1997 - end  
1998 -  
1999 - should 'a person remove a profile from a circle' do  
2000 - person = create_user('testuser').person  
2001 - community = fast_create(Community)  
2002 - circle = Circle.create!(:person=> person, :name => "Zombies", :profile_type => 'Community')  
2003 - circle2 = Circle.create!(:person=> person, :name => "Dota", :profile_type => 'Community')  
2004 - person.follow(community, [circle, circle2])  
2005 - person.remove_profile_from_circle(community, circle)  
2006 - assert_equivalent [circle2], ProfileFollower.with_profile(community).with_follower(person).map(&:circle)  
2007 - end  
2008 -  
2009 end 1955 end
test/unit/profile_followers_test.rb
@@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
1 -require_relative "../test_helper"  
2 -  
3 -class ProfileFollowersTest < ActiveSupport::TestCase  
4 -  
5 - should 'a person follow another' do  
6 - p1 = create_user('person_test').person  
7 - p2 = create_user('person_test_2').person  
8 - circle = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
9 -  
10 - assert_difference 'ProfileFollower.count' do  
11 - p1.follow(p2, circle)  
12 - end  
13 -  
14 - assert_includes p2.followers(true), p1  
15 - assert_not_includes p1.followers(true), p2  
16 - end  
17 -  
18 - should 'a person unfollow another person' do  
19 - p1 = create_user('person_test').person  
20 - p2 = create_user('person_test_2').person  
21 - circle = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
22 -  
23 - p1.follow(p2,circle)  
24 -  
25 - assert_difference 'ProfileFollower.count', -1 do  
26 - p1.unfollow(p2)  
27 - end  
28 -  
29 - assert_not_includes p2.followers(true), p1  
30 - end  
31 -  
32 - should 'get the followed persons for a profile' do  
33 - p1 = create_user('person_test').person  
34 - p2 = create_user('person_test_2').person  
35 - p3 = create_user('person_test_3').person  
36 - circle = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
37 -  
38 - p1.follow(p2, circle)  
39 - p1.follow(p3, circle)  
40 -  
41 - assert_equivalent p1.followed_profiles, [p2,p3]  
42 - assert_equivalent Profile.followed_by(p1), [p2,p3]  
43 - end  
44 -  
45 - should 'not follow same person twice' do  
46 - p1 = create_user('person_test').person  
47 - p2 = create_user('person_test_2').person  
48 - circle = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
49 -  
50 - assert_difference 'ProfileFollower.count' do  
51 - p1.follow(p2, circle)  
52 - p1.follow(p2, circle)  
53 - end  
54 -  
55 - assert_equivalent p1.followed_profiles, [p2]  
56 - assert_equivalent p2.followers, [p1]  
57 - end  
58 -  
59 - should 'show the correct message when a profile is followed by the same person' do  
60 - p1 = create_user('person_test').person  
61 - p2 = create_user('person_test_2').person  
62 - circle = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
63 -  
64 - p1.follow(p2, circle)  
65 - profile_follower = ProfileFollower.new  
66 - profile_follower.circle = circle  
67 - profile_follower.profile = p2  
68 - profile_follower.valid?  
69 -  
70 - assert_includes profile_follower.errors.messages[:profile_id],  
71 - "can't put a profile in the same circle twice"  
72 - end  
73 -end