Compare View

switch
from
...
to
 
Commits (19)
Showing 38 changed files   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 < MyProfileController @@ -3,7 +3,7 @@ class CirclesController < 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 < MyProfileController @@ -11,7 +11,7 @@ class CirclesController < 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 < MyProfileController @@ -21,7 +21,7 @@ class CirclesController < 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 < MyProfileController @@ -4,11 +4,11 @@ class FollowersController < 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 < MyProfileController @@ -17,7 +17,7 @@ class FollowersController < 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
@@ -69,6 +69,8 @@ class ProfileController < PublicController @@ -69,6 +69,8 @@ class ProfileController < PublicController
69 69
70 def following 70 def following
71 @followed_people = profile.followed_profiles.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followed_profiles.count) 71 @followed_people = profile.followed_profiles.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followed_profiles.count)
  72 + puts "FOLLOWED_PEOPLE: #{@followed_people.map(&:name)}"
  73 + return @followed_people
72 end 74 end
73 75
74 def followed 76 def followed
@@ -165,6 +167,7 @@ class ProfileController < PublicController @@ -165,6 +167,7 @@ class ProfileController < PublicController
165 if profile.followed_by?(current_person) 167 if profile.followed_by?(current_person)
166 render :text => _("You are already following %s.") % profile.name, :status => 400 168 render :text => _("You are already following %s.") % profile.name, :status => 400
167 else 169 else
  170 + params[:circles] ||= []
168 selected_circles = params[:circles].map{ |circle_name, circle_id| Circle.find_by(:id => circle_id) }.select{ |c| c.present? } 171 selected_circles = params[:circles].map{ |circle_name, circle_id| Circle.find_by(:id => circle_id) }.select{ |c| c.present? }
169 if selected_circles.present? 172 if selected_circles.present?
170 current_person.follow(profile, selected_circles) 173 current_person.follow(profile, selected_circles)
@@ -176,7 +179,7 @@ class ProfileController < PublicController @@ -176,7 +179,7 @@ class ProfileController < PublicController
176 end 179 end
177 180
178 def find_profile_circles 181 def find_profile_circles
179 - circles = Circle.where(:person => current_person, :profile_type => profile.class.name) 182 + circles = Circle.where(:owner => current_person, :profile_type => profile.class.name)
180 render :partial => 'blocks/profile_info_actions/circles', :locals => { :circles => circles, :profile_types => Circle.profile_types.to_a } 183 render :partial => 'blocks/profile_info_actions/circles', :locals => { :circles => circles, :profile_types => Circle.profile_types.to_a }
181 end 184 end
182 185
app/jobs/notify_activity_to_profiles_job.rb
@@ -20,7 +20,7 @@ class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id) @@ -20,7 +20,7 @@ class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id)
20 ActionTrackerNotification.create(:profile_id => tracked_action.user.id, :action_tracker_id => tracked_action.id) 20 ActionTrackerNotification.create(:profile_id => tracked_action.user.id, :action_tracker_id => tracked_action.id)
21 21
22 # Notify all followers 22 # Notify all followers
23 - 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}))") 23 + 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}))")
24 24
25 if tracked_action.user.is_a? Organization 25 if tracked_action.user.is_a? Organization
26 ActionTrackerNotification.connection.execute "insert into action_tracker_notifications(profile_id, action_tracker_id) " + 26 ActionTrackerNotification.connection.execute "insert into action_tracker_notifications(profile_id, action_tracker_id) " +
app/models/add_member.rb
@@ -22,7 +22,7 @@ class AddMember < Task @@ -22,7 +22,7 @@ class AddMember < 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
1 class Circle < ApplicationRecord 1 class Circle < ApplicationRecord
  2 + #TODO -> n:m with profile, item in the circle
2 has_many :profile_followers 3 has_many :profile_followers
3 - belongs_to :person 4 + #TODO -> owner
  5 + belongs_to :owner, polymorphic: true
4 6
5 - attr_accessible :name, :person, :profile_type 7 + attr_accessible :name, :owner, :profile_type
6 8
7 validates :name, presence: true 9 validates :name, presence: true
8 - validates :person_id, presence: true 10 + validates :owner_id, presence: true
9 validates :profile_type, presence: true 11 validates :profile_type, presence: true
10 - validates :person_id, :uniqueness => {:scope => :name, :message => "can't add two circles with the same name"} 12 + validates :owner_id, :uniqueness => {:scope => :name, :message => "can't add two circles with the same name"}
11 13
12 validate :profile_type_must_be_in_list 14 validate :profile_type_must_be_in_list
13 15
@@ -23,7 +25,8 @@ class Circle &lt; ApplicationRecord @@ -23,7 +25,8 @@ class Circle &lt; ApplicationRecord
23 { 25 {
24 _("Person") => Person.name, 26 _("Person") => Person.name,
25 _("Community") => Community.name, 27 _("Community") => Community.name,
26 - _("Enterprise") => Enterprise.name 28 + _("Enterprise") => Enterprise.name,
  29 + _("Organization") => Organization.name
27 } 30 }
28 end 31 end
29 32
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,47 @@ @@ -0,0 +1,47 @@
  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 followed_profiles
  26 + external_people = ExternalProfile.joins(:circles).where("circles.owner_id = ?", self.id)
  27 + profiles = Profile.joins(:circles).where("circles.owner_id = ?", self.id)
  28 +
  29 + external_people.uniq + profiles.uniq
  30 + end
  31 +
  32 + def update_profile_circles(profile, new_circles)
  33 + profile_circles = ProfileFollower.with_profile(profile).with_follower(self).map(&:circle)
  34 + circles_to_add = new_circles - profile_circles
  35 + self.follow(profile, circles_to_add)
  36 +
  37 + circles_to_remove = profile_circles - new_circles
  38 + ProfileFollower.where('circle_id IN (?) AND profile_id = ?',
  39 + circles_to_remove.map(&:id), profile.id).destroy_all
  40 + end
  41 +
  42 + def remove_profile_from_circle(profile, circle)
  43 + return if circle.owner != self
  44 + ProfileFollower.with_profile(profile).with_circle(circle).destroy_all
  45 + end
  46 +
  47 +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,120 @@ @@ -0,0 +1,120 @@
  1 +class ExternalProfile < ActiveRecord::Base
  2 +
  3 + include Followable
  4 +
  5 + def name
  6 + "#{self[:name]}@#{self.source}"
  7 + end
  8 +
  9 + class ExternalProfile::Image
  10 + def initialize(path)
  11 + @path = path
  12 + end
  13 +
  14 + def public_filename(size = nil)
  15 + URI.join(@path, size.to_s)
  16 + end
  17 +
  18 + def content_type
  19 + # This is not really going to be used anywhere that matters
  20 + # so we are hardcodding it here.
  21 + 'image/png'
  22 + end
  23 + end
  24 +
  25 + def url
  26 + "http://#{self.source}/profile/#{self.identifier}"
  27 + end
  28 +
  29 + def image
  30 + ExternalProfile::Image.new(avatar)
  31 + end
  32 +
  33 + def profile_custom_icon(gravatar_default=nil)
  34 + self.avatar
  35 + end
  36 +
  37 + def avatar
  38 + "http://#{self.source}/profile/#{self.identifier}/icon/"
  39 + end
  40 +
  41 + # External Profile should respond to all methods in Profile
  42 +def profile_instance_methods
  43 + methods_and_responses = {
  44 + role_assignments: RoleAssignment.none, favorite_enterprises:
  45 + Enterprise.none, memberships: Profile.none, friendships: Profile.none,
  46 + tasks: Task.none, suggested_profiles: ProfileSuggestion.none,
  47 + suggested_people: ProfileSuggestion.none, suggested_communities:
  48 + ProfileSuggestion.none, public_profile: true, nickname: nil, custom_footer:
  49 + '', custom_header: '', address: '', zip_code: '', contact_phone: '',
  50 + image_builder: nil, description: '', closed: false, template_id: nil, lat:
  51 + nil, lng: nil, is_template: false, fields_privacy: {}, preferred_domain_id:
  52 + nil, category_ids: [], country: '', city: '', state: '',
  53 + national_region_code: '', redirect_l10n: false, notification_time: 0,
  54 + custom_url_redirection: nil, email_suggestions: false,
  55 + allow_members_to_invite: false, invite_friends_only: false, secret: false,
  56 + profile_admin_mail_notification: false, redirection_after_login: nil,
  57 + profile_activities: ProfileActivity.none, action_tracker_notifications:
  58 + ActionTrackerNotification.none, tracked_notifications:
  59 + ActionTracker::Record.none, scraps_received: Scrap.none, template:
  60 + Profile.none, comments_received: Comment.none, email_templates:
  61 + EmailTemplate.none, members: Profile.none, members_like: Profile.none,
  62 + members_by: Profile.none, members_by_role: Profile.none, scraps:
  63 + Scrap.none, welcome_page_content: nil, settings: {}, find_in_all_tasks:
  64 + nil, top_level_categorization: {}, interests: Category.none, geolocation:
  65 + '', country_name: '', pending_categorizations: [], add_category: false,
  66 + create_pending_categorizations: false, top_level_articles: Article.none,
  67 + valid_identifier: true, valid_template: false, create_default_set_of_boxes:
  68 + true, copy_blocks_from: nil, default_template: nil,
  69 + template_without_default: nil, template_with_default: nil, apply_template:
  70 + false, iframe_whitelist: [], recent_documents: Article.none, last_articles:
  71 + Article.none, is_validation_entity?: false, hostname: nil, own_hostname:
  72 + nil, article_tags: {}, tagged_with: Article.none,
  73 + insert_default_article_set: false, copy_articles_from: true,
  74 + copy_article_tree: nil, copy_article?: false, add_member: false,
  75 + remove_member: false, add_admin: false, remove_admin: false, add_moderator:
  76 + false, display_info_to?: true, update_category_from_region: nil,
  77 + accept_category?: false, custom_header_expanded: '',
  78 + custom_footer_expanded: '', public?: true, themes: [], find_theme: nil,
  79 + blogs: Blog.none, blog: nil, has_blog?: false, forums: Forum.none, forum:
  80 + nil, has_forum?: false, admins: [], settings_field: {}, setting_changed:
  81 + false, public_content: true, enable_contact?: false, folder_types: [],
  82 + folders: Article.none, image_galleries: Article.none, image_valid: true,
  83 + update_header_and_footer: nil, update_theme: nil, update_layout_template:
  84 + nil, recent_actions: ActionTracker::Record.none, recent_notifications:
  85 + ActionTracker::Record.none, more_active_label: _('no activity'),
  86 + more_popular_label: _('no members'), profile_custom_image: nil,
  87 + is_on_homepage?: false, activities: ProfileActivity.none,
  88 + may_display_field_to?: true, may_display_location_to?: true, public_fields:
  89 + {}, display_private_info_to?: true, can_view_field?:
  90 + true, remove_from_suggestion_list: nil, layout_template: 'default',
  91 + is_admin?: false, add_friend: false, is_a_friend?: false,
  92 + already_request_friendship?: false, tracked_actions: ActionTracker::Record.none
  93 + }
  94 +
  95 + derivated_methods = generate_derivated_methods(methods_and_responses)
  96 + derivated_methods.merge(methods_and_responses)
  97 + end
  98 +
  99 + def method_missing(method, *args, &block)
  100 + if profile_instance_methods.keys.include? method
  101 + return profile_instance_methods[method]
  102 + end
  103 + raise NoMethodError, "undefined method #{method} for #{self}"
  104 + end
  105 +
  106 + def respond_to_missing?(method_name, include_private = false)
  107 + profile_instance_methods.keys.include?(method_name) || super
  108 + end
  109 +
  110 + private
  111 +
  112 + def generate_derivated_methods(methods)
  113 + derivated_methods = {}
  114 + methods.keys.each do |method|
  115 + derivated_methods[method.to_s.insert(-1, '?').to_sym] = false
  116 + derivated_methods[method.to_s.insert(-1, '=').to_sym] = nil
  117 + end
  118 + derivated_methods
  119 + end
  120 +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)
@@ -181,33 +181,6 @@ class Person &lt; Profile @@ -181,33 +181,6 @@ class Person &lt; Profile
181 end 181 end
182 end 182 end
183 183
184 - def follow(profile, circles)  
185 - circles = [circles] unless circles.is_a?(Array)  
186 - circles.each do |new_circle|  
187 - ProfileFollower.create(profile: profile, circle: new_circle)  
188 - end  
189 - end  
190 -  
191 - def update_profile_circles(profile, new_circles)  
192 - profile_circles = ProfileFollower.with_profile(profile).with_follower(self).map(&:circle)  
193 - circles_to_add = new_circles - profile_circles  
194 - circles_to_remove = profile_circles - new_circles  
195 - circles_to_add.each do |new_circle|  
196 - ProfileFollower.create(profile: profile, circle: new_circle)  
197 - end  
198 -  
199 - ProfileFollower.where('circle_id IN (?) AND profile_id = ?',  
200 - circles_to_remove.map(&:id), profile.id).destroy_all  
201 - end  
202 -  
203 - def unfollow(profile)  
204 - ProfileFollower.with_follower(self).with_profile(profile).destroy_all  
205 - end  
206 -  
207 - def remove_profile_from_circle(profile, circle)  
208 - ProfileFollower.with_profile(profile).with_circle(circle).destroy_all  
209 - end  
210 -  
211 def already_request_friendship?(person) 184 def already_request_friendship?(person)
212 person.tasks.where(requestor_id: self.id, type: 'AddFriend', status: Task::Status::ACTIVE).first 185 person.tasks.where(requestor_id: self.id, type: 'AddFriend', status: Task::Status::ACTIVE).first
213 end 186 end
@@ -492,11 +465,6 @@ class Person &lt; Profile @@ -492,11 +465,6 @@ class Person &lt; Profile
492 profile.members.include?(self) 465 profile.members.include?(self)
493 end 466 end
494 467
495 - def follows?(profile)  
496 - return false if profile.nil?  
497 - profile.followed_by?(self)  
498 - end  
499 -  
500 def each_friend(offset=0) 468 def each_friend(offset=0)
501 while friend = self.friends.order(:id).offset(offset).first 469 while friend = self.friends.order(:id).offset(offset).first
502 yield friend 470 yield friend
@@ -601,10 +569,6 @@ class Person &lt; Profile @@ -601,10 +569,6 @@ class Person &lt; Profile
601 } 569 }
602 end 570 end
603 571
604 - def followed_profiles  
605 - Profile.followed_by self  
606 - end  
607 -  
608 def in_social_circle?(person) 572 def in_social_circle?(person)
609 self.is_a_friend?(person) || super 573 self.is_a_friend?(person) || super
610 end 574 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
@@ -219,20 +220,6 @@ class Profile &lt; ApplicationRecord @@ -219,20 +220,6 @@ class Profile &lt; ApplicationRecord
219 scope :more_active, -> { order 'activities_count DESC' } 220 scope :more_active, -> { order 'activities_count DESC' }
220 scope :more_recent, -> { order "created_at DESC" } 221 scope :more_recent, -> { order "created_at DESC" }
221 222
222 - scope :followed_by, -> person{  
223 - distinct.select('profiles.*').  
224 - joins('left join profiles_circles ON profiles_circles.profile_id = profiles.id').  
225 - joins('left join circles ON circles.id = profiles_circles.circle_id').  
226 - where('circles.person_id = ?', person.id)  
227 - }  
228 -  
229 - scope :in_circle, -> circle{  
230 - distinct.select('profiles.*').  
231 - joins('left join profiles_circles ON profiles_circles.profile_id = profiles.id').  
232 - joins('left join circles ON circles.id = profiles_circles.circle_id').  
233 - where('circles.id = ?', circle.id)  
234 - }  
235 -  
236 settings_items :allow_followers, :type => :boolean, :default => true 223 settings_items :allow_followers, :type => :boolean, :default => true
237 alias_method :allow_followers?, :allow_followers 224 alias_method :allow_followers?, :allow_followers
238 225
@@ -248,8 +235,7 @@ class Profile &lt; ApplicationRecord @@ -248,8 +235,7 @@ class Profile &lt; ApplicationRecord
248 235
249 has_many :email_templates, :foreign_key => :owner_id 236 has_many :email_templates, :foreign_key => :owner_id
250 237
251 - has_many :profile_followers  
252 - has_many :followers, -> { uniq }, :class_name => 'Person', :through => :profile_followers, :source => :person 238 + # has_many :followers, -> { uniq }, :through => :profile_followers, :source => :person
253 239
254 # Although this should be a has_one relation, there are no non-silly names for 240 # Although this should be a has_one relation, there are no non-silly names for
255 # a foreign key on article to reference the template to which it is 241 # a foreign key on article to reference the template to which it is
@@ -726,7 +712,7 @@ private :generate_url, :url_options @@ -726,7 +712,7 @@ private :generate_url, :url_options
726 else 712 else
727 self.affiliate(person, Profile::Roles.admin(environment.id), attributes) if members.count == 0 713 self.affiliate(person, Profile::Roles.admin(environment.id), attributes) if members.count == 0
728 self.affiliate(person, Profile::Roles.member(environment.id), attributes) 714 self.affiliate(person, Profile::Roles.member(environment.id), attributes)
729 - person.follow(self, Circle.find_or_create_by(:person => person, :name =>_('memberships'), :profile_type => 'Community')) 715 + person.follow(self, Circle.find_or_create_by(:owner => person, :name =>_('memberships'), :profile_type => self.class.name))
730 end 716 end
731 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel } 717 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel }
732 remove_from_suggestion_list person 718 remove_from_suggestion_list person
@@ -1008,10 +994,6 @@ private :generate_url, :url_options @@ -1008,10 +994,6 @@ private :generate_url, :url_options
1008 self.active_fields 994 self.active_fields
1009 end 995 end
1010 996
1011 - def followed_by?(person)  
1012 - (person == self) || (person.in? self.followers)  
1013 - end  
1014 -  
1015 def in_social_circle?(person) 997 def in_social_circle?(person)
1016 (person == self) || (person.is_member_of?(self)) 998 (person == self) || (person.is_member_of?(self))
1017 end 999 end
@@ -1055,7 +1037,4 @@ private :generate_url, :url_options @@ -1055,7 +1037,4 @@ private :generate_url, :url_options
1055 person.kind_of?(Profile) && person.has_permission?('destroy_profile', self) 1037 person.kind_of?(Profile) && person.has_permission?('destroy_profile', self)
1056 end 1038 end
1057 1039
1058 - def in_circle?(circle, follower)  
1059 - ProfileFollower.with_follower(follower).with_circle(circle).with_profile(self).present?  
1060 - end  
1061 end 1040 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: 20160608123748) do 14 +ActiveRecord::Schema.define(version: 20160822184703) 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: 20160608123748) do @@ -277,11 +277,13 @@ ActiveRecord::Schema.define(version: 20160608123748) 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"
@@ -553,6 +555,11 @@ ActiveRecord::Schema.define(version: 20160608123748) do @@ -553,6 +555,11 @@ ActiveRecord::Schema.define(version: 20160608123748) do
553 t.datetime "updated_at" 555 t.datetime "updated_at"
554 end 556 end
555 557
  558 + create_table "private_scraps", force: :cascade do |t|
  559 + t.integer "person_id"
  560 + t.integer "scrap_id"
  561 + end
  562 +
556 create_table "product_qualifiers", force: :cascade do |t| 563 create_table "product_qualifiers", force: :cascade do |t|
557 t.integer "product_id" 564 t.integer "product_id"
558 t.integer "qualifier_id" 565 t.integer "qualifier_id"
@@ -681,9 +688,11 @@ ActiveRecord::Schema.define(version: 20160608123748) do @@ -681,9 +688,11 @@ ActiveRecord::Schema.define(version: 20160608123748) do
681 t.integer "circle_id" 688 t.integer "circle_id"
682 t.datetime "created_at" 689 t.datetime "created_at"
683 t.datetime "updated_at" 690 t.datetime "updated_at"
  691 + t.string "profile_type", default: "Person"
684 end 692 end
685 693
686 add_index "profiles_circles", ["profile_id", "circle_id"], name: "profiles_circles_composite_key_index", unique: true, using: :btree 694 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", "profile_type"], name: "index_profiles_circles_on_profile_id_and_profile_type", using: :btree
687 696
688 create_table "qualifier_certifiers", force: :cascade do |t| 697 create_table "qualifier_certifiers", force: :cascade do |t|
689 t.integer "qualifier_id" 698 t.integer "qualifier_id"
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
@@ -772,7 +772,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -772,7 +772,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
772 end 772 end
773 773
774 should 'not see the followers activities in the current profile' do 774 should 'not see the followers activities in the current profile' do
775 - circle = Circle.create!(:person=> profile, :name => "Zombies", :profile_type => 'Person') 775 + circle = Circle.create!(:owner=> profile, :name => "Zombies", :profile_type => 'Person')
776 776
777 p2 = create_user.person 777 p2 = create_user.person
778 refute profile.follows?(p2) 778 refute profile.follows?(p2)
@@ -968,7 +968,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -968,7 +968,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
968 login_as(profile.identifier) 968 login_as(profile.identifier)
969 p1= fast_create(Person) 969 p1= fast_create(Person)
970 970
971 - circle = Circle.create!(:person=> profile, :name => "Zombies", :profile_type => 'Person') 971 + circle = Circle.create!(:owner=> profile, :name => "Zombies", :profile_type => 'Person')
972 972
973 profile.follow(p1, circle) 973 profile.follow(p1, circle)
974 974
@@ -1992,7 +1992,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1992,7 +1992,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1992 login_as(@profile.identifier) 1992 login_as(@profile.identifier)
1993 person = fast_create(Person) 1993 person = fast_create(Person)
1994 1994
1995 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person') 1995 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
1996 1996
1997 assert_difference 'ProfileFollower.count' do 1997 assert_difference 'ProfileFollower.count' do
1998 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id} 1998 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id}
@@ -2003,8 +2003,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2003,8 +2003,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2003 login_as(@profile.identifier) 2003 login_as(@profile.identifier)
2004 person = fast_create(Person) 2004 person = fast_create(Person)
2005 2005
2006 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2007 - circle2 = Circle.create!(:person=> @profile, :name => "Brainsss", :profile_type => 'Person') 2006 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2007 + circle2 = Circle.create!(:owner=> @profile, :name => "Brainsss", :profile_type => 'Person')
2008 2008
2009 assert_difference 'ProfileFollower.count', 2 do 2009 assert_difference 'ProfileFollower.count', 2 do
2010 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id, "Brainsss"=> circle2.id} 2010 post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id, "Brainsss"=> circle2.id}
@@ -2015,8 +2015,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2015,8 +2015,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2015 login_as(@profile.identifier) 2015 login_as(@profile.identifier)
2016 person = fast_create(Person) 2016 person = fast_create(Person)
2017 2017
2018 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2019 - circle2 = Circle.create!(:person=> @profile, :name => "Brainsss", :profile_type => 'Person') 2018 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2019 + circle2 = Circle.create!(:owner=> @profile, :name => "Brainsss", :profile_type => 'Person')
2020 2020
2021 assert_no_difference 'ProfileFollower.count' do 2021 assert_no_difference 'ProfileFollower.count' do
2022 post :follow, :profile => person.identifier, :circles => {"Zombies" => "0", "Brainsss" => "0"} 2022 post :follow, :profile => person.identifier, :circles => {"Zombies" => "0", "Brainsss" => "0"}
@@ -2029,11 +2029,11 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2029,11 +2029,11 @@ class ProfileControllerTest &lt; ActionController::TestCase
2029 login_as(@profile.identifier) 2029 login_as(@profile.identifier)
2030 person = fast_create(Person) 2030 person = fast_create(Person)
2031 2031
2032 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2033 - fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2032 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2033 + ProfileFollower.create(:profile => person, :circle => circle)
2034 2034
2035 assert_no_difference 'ProfileFollower.count' do 2035 assert_no_difference 'ProfileFollower.count' do
2036 - post :follow, :profile => person.identifier, :follow => { :circles => {"Zombies" => circle.id} } 2036 + post :follow, :profile => person.identifier, :circles => {"Zombies" => circle.id}
2037 end 2037 end
2038 assert_response 400 2038 assert_response 400
2039 end 2039 end
@@ -2049,8 +2049,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2049,8 +2049,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
2049 login_as(@profile.identifier) 2049 login_as(@profile.identifier)
2050 person = fast_create(Person) 2050 person = fast_create(Person)
2051 2051
2052 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person')  
2053 - follower = fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2052 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
  2053 + follower = ProfileFollower.create!(:profile => person, circle: circle)
2054 2054
2055 assert_not_nil follower 2055 assert_not_nil follower
2056 2056
@@ -2072,7 +2072,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -2072,7 +2072,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
2072 login_as(@profile.identifier) 2072 login_as(@profile.identifier)
2073 person = fast_create(Person) 2073 person = fast_create(Person)
2074 2074
2075 - circle = Circle.create!(:person=> @profile, :name => "Zombies", :profile_type => 'Person') 2075 + circle = Circle.create!(:owner=> @profile, :name => "Zombies", :profile_type => 'Person')
2076 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id) 2076 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle.id)
2077 2077
2078 post :unfollow, :profile => person.identifier, :redirect_to => "/some/url" 2078 post :unfollow, :profile => person.identifier, :redirect_to => "/some/url"
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 FollowerTest < 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)
@@ -79,7 +79,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -79,7 +79,7 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
79 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb) 79 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)
80 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person) 80 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)
81 81
82 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person') 82 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
83 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id) 83 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id)
84 84
85 fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id) 85 fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id)
@@ -127,8 +127,8 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -127,8 +127,8 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
127 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb) 127 refute NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)
128 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person) 128 p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)
129 129
130 - circle1 = Circle.create!(:person=> p1, :name => "Zombies", :profile_type => 'Person')  
131 - circle2 = Circle.create!(:person=> p2, :name => "Zombies", :profile_type => 'Person') 130 + circle1 = Circle.create!(:owner=> p1, :name => "Zombies", :profile_type => 'Person')
  131 + circle2 = Circle.create!(:owner=> p2, :name => "Zombies", :profile_type => 'Person')
132 132
133 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id) 133 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle1.id)
134 fast_create(ProfileFollower, :profile_id => person.id, :circle_id => circle2.id) 134 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