Commit 45c0df82cf8ce0fa3d49810da8f225415f7da412
Committed by
Rodrigo Souto
1 parent
c95e0983
Exists in
master
and in
12 other branches
Add feature: Article Followers
- Every article can be followed so the user can receive notifications without having to comment on it Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com> Signed-off-by: Marcos Ramos <ms.ramos@outlook.com> Signed-off-by: Gustavo Coelho <gust.rod.coelho@gmail.com> Signed-off-by: Joenio Costa <joenio@colivre.coop.br> Signed-off-by: Carlos Purificacao <carloseugenio@gmail.com> Signed-off-by: Victor Costa <vfcosta@gmail.com> Signed-off-by: Caio SBA <caio@colivre.coop.br> Signed-off-by: Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> Signed-off-by: Michel Felipe de Oliveira Ferreira <michel.ferreira@serpro.gov.br> Signed-off-by: Evandro Jr <evandrojr@gmail.com>
Showing
21 changed files
with
269 additions
and
43 deletions
Show diff stats
app/controllers/public/profile_controller.rb
... | ... | @@ -155,6 +155,18 @@ class ProfileController < PublicController |
155 | 155 | end |
156 | 156 | end |
157 | 157 | |
158 | + def follow_article | |
159 | + article = profile.environment.articles.find params[:article_id] | |
160 | + article.person_followers << user | |
161 | + redirect_to article.url | |
162 | + end | |
163 | + | |
164 | + def unfollow_article | |
165 | + article = profile.environment.articles.find params[:article_id] | |
166 | + article.person_followers.delete(user) | |
167 | + redirect_to article.url | |
168 | + end | |
169 | + | |
158 | 170 | def unblock |
159 | 171 | if current_user.person.is_admin?(profile.environment) |
160 | 172 | profile.unblock | ... | ... |
app/helpers/article_helper.rb
... | ... | @@ -155,4 +155,30 @@ module ArticleHelper |
155 | 155 | _('Edit') |
156 | 156 | end |
157 | 157 | |
158 | + def follow_button_text(article) | |
159 | + if article.event? | |
160 | + _('Attend') | |
161 | + else | |
162 | + _('Follow') | |
163 | + end | |
164 | + end | |
165 | + | |
166 | + def unfollow_button_text(article) | |
167 | + if article.event? | |
168 | + _('Unattend') | |
169 | + else | |
170 | + _('Unfollow') | |
171 | + end | |
172 | + end | |
173 | + | |
174 | + def following_button(page, user) | |
175 | + if !user.blank? and user != page.author | |
176 | + if page.is_followed_by? user | |
177 | + button :cancel, unfollow_button_text(page), {:controller => 'profile', :action => 'unfollow_article', :article_id => page.id} | |
178 | + else | |
179 | + button :add, follow_button_text(page), {:controller => 'profile', :action => 'follow_article', :article_id => page.id} | |
180 | + end | |
181 | + end | |
182 | + end | |
183 | + | |
158 | 184 | end | ... | ... |
app/models/article.rb
... | ... | @@ -9,7 +9,7 @@ class Article < ActiveRecord::Base |
9 | 9 | :highlighted, :notify_comments, :display_hits, :slug, |
10 | 10 | :external_feed_builder, :display_versions, :external_link, |
11 | 11 | :image_builder, :show_to_followers, |
12 | - :author, :display_preview, :published_at | |
12 | + :author, :display_preview, :published_at, :person_followers | |
13 | 13 | |
14 | 14 | acts_as_having_image |
15 | 15 | |
... | ... | @@ -77,8 +77,15 @@ class Article < ActiveRecord::Base |
77 | 77 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
78 | 78 | belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id' |
79 | 79 | |
80 | +<<<<<<< 6fa2f904983046ed816efe293ba9dcad19a67a4b | |
80 | 81 | has_many :comments, :class_name => 'Comment', :as => 'source', :dependent => :destroy, :order => 'created_at asc' |
81 | 82 | |
83 | +======= | |
84 | + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' | |
85 | + has_many :article_followers, :dependent => :destroy | |
86 | + has_many :person_followers, :class_name => 'Person', :through => :article_followers, :source => :person | |
87 | + has_many :person_followers_emails, :class_name => 'User', :through => :person_followers, :source => :user, :select => :email | |
88 | +>>>>>>> Add feature: Article Followers | |
82 | 89 | has_many :article_categorizations, -> { where 'articles_categories.virtual = ?', false } |
83 | 90 | has_many :categories, :through => :article_categorizations |
84 | 91 | |
... | ... | @@ -91,7 +98,6 @@ class Article < ActiveRecord::Base |
91 | 98 | settings_items :author_name, :type => :string, :default => "" |
92 | 99 | settings_items :allow_members_to_edit, :type => :boolean, :default => false |
93 | 100 | settings_items :moderate_comments, :type => :boolean, :default => false |
94 | - settings_items :followers, :type => Array, :default => [] | |
95 | 101 | has_and_belongs_to_many :article_privacy_exceptions, :class_name => 'Person', :join_table => 'article_privacy_exceptions' |
96 | 102 | |
97 | 103 | belongs_to :reference_article, :class_name => "Article", :foreign_key => 'reference_article_id' |
... | ... | @@ -167,7 +173,6 @@ class Article < ActiveRecord::Base |
167 | 173 | end |
168 | 174 | end |
169 | 175 | |
170 | - | |
171 | 176 | def is_trackable? |
172 | 177 | self.published? && self.notifiable? && self.advertise? && self.profile.public_profile |
173 | 178 | end |
... | ... | @@ -368,6 +373,10 @@ class Article < ActiveRecord::Base |
368 | 373 | self.parent and self.parent.forum? |
369 | 374 | end |
370 | 375 | |
376 | + def person_followers_email_list | |
377 | + person_followers_emails.map{|p|p.email} | |
378 | + end | |
379 | + | |
371 | 380 | def info_from_last_update |
372 | 381 | last_comment = comments.last |
373 | 382 | if last_comment |
... | ... | @@ -407,6 +416,10 @@ class Article < ActiveRecord::Base |
407 | 416 | (not self.uploaded_file? and self.mime_type != 'text/html') |
408 | 417 | end |
409 | 418 | |
419 | + def is_followed_by?(user) | |
420 | + self.person_followers.include? user | |
421 | + end | |
422 | + | |
410 | 423 | def download_headers |
411 | 424 | {} |
412 | 425 | end | ... | ... |
app/models/comment.rb
... | ... | @@ -6,13 +6,14 @@ class Comment < ActiveRecord::Base |
6 | 6 | :body => {:label => _('Content'), :weight => 2}, |
7 | 7 | } |
8 | 8 | |
9 | - attr_accessible :body, :author, :name, :email, :title, :reply_of_id, :source | |
9 | + attr_accessible :body, :author, :name, :email, :title, :reply_of_id, :source, :follow_article | |
10 | 10 | |
11 | 11 | validates_presence_of :body |
12 | 12 | |
13 | 13 | belongs_to :source, :counter_cache => true, :polymorphic => true |
14 | 14 | alias :article :source |
15 | 15 | alias :article= :source= |
16 | + attr_accessor :follow_article | |
16 | 17 | |
17 | 18 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' |
18 | 19 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
... | ... | @@ -100,10 +101,9 @@ class Comment < ActiveRecord::Base |
100 | 101 | |
101 | 102 | after_create :new_follower |
102 | 103 | def new_follower |
103 | - if source.kind_of?(Article) | |
104 | - article.followers += [author_email] | |
105 | - article.followers -= article.profile.notification_emails | |
106 | - article.followers.uniq! | |
104 | + if source.kind_of?(Article) and !author.nil? and @follow_article | |
105 | + article.person_followers += [author] | |
106 | + article.person_followers.uniq! | |
107 | 107 | article.save |
108 | 108 | end |
109 | 109 | end |
... | ... | @@ -145,7 +145,7 @@ class Comment < ActiveRecord::Base |
145 | 145 | if !notification_emails.empty? |
146 | 146 | CommentNotifier.notification(self).deliver |
147 | 147 | end |
148 | - emails = article.followers - [author_email] | |
148 | + emails = article.person_followers_email_list - [author_email] | |
149 | 149 | if !emails.empty? |
150 | 150 | CommentNotifier.mail_to_followers(self, emails).deliver |
151 | 151 | end | ... | ... |
app/models/person.rb
1 | 1 | # A person is the profile of an user holding all relationships with the rest of the system |
2 | 2 | class Person < Profile |
3 | 3 | |
4 | - 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 | |
4 | + 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 | |
5 | 5 | |
6 | 6 | SEARCH_FILTERS = { |
7 | 7 | :order => %w[more_recent more_popular more_active], |
... | ... | @@ -84,7 +84,8 @@ class Person < Profile |
84 | 84 | end |
85 | 85 | |
86 | 86 | has_many :comments, :foreign_key => :author_id |
87 | - | |
87 | + has_many :article_followers, :dependent => :destroy | |
88 | + has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article | |
88 | 89 | has_many :friendships, :dependent => :destroy |
89 | 90 | has_many :friends, :class_name => 'Person', :through => :friendships |
90 | 91 | ... | ... |
app/views/comment/_comment_form.html.erb
... | ... | @@ -77,6 +77,10 @@ function check_captcha(button, confirm_action) { |
77 | 77 | <%= labelled_form_field(_('Title'), f.text_field(:title)) %> |
78 | 78 | <%= required labelled_form_field(_('Enter your comment'), f.text_area(:body, :rows => 5)) %> |
79 | 79 | |
80 | + <% if logged_in? %> | |
81 | + <%= labelled_form_field check_box(:comment, :follow_article, {}, true, false) + _('Follow this article'), '' %> | |
82 | + <% end%> | |
83 | + | |
80 | 84 | <%= hidden_field_tag(:confirm, 'false') %> |
81 | 85 | <%= hidden_field_tag(:view, params[:view])%> |
82 | 86 | <%= f.hidden_field(:reply_of_id) %> | ... | ... |
app/views/content_viewer/_article_toolbar.html.erb
app/views/content_viewer/_publishing_info.html.erb
... | ... | @@ -10,6 +10,24 @@ |
10 | 10 | <%= (" - %s") % link_to_comments(@page)%> |
11 | 11 | </span> |
12 | 12 | <% end %> |
13 | + | |
14 | +<span class="followers-count"> | |
15 | +| | |
16 | +<% if @page.event? %> | |
17 | + <% if @page.person_followers.size > 0 %> | |
18 | + <%= _("%s will attend this event.") % [ pluralize(@page.person_followers.size, _("person"))]%> | |
19 | + <% else %> | |
20 | + <%= _("No one attending this event yet.") %> | |
21 | + <% end %> | |
22 | +<% else %> | |
23 | + <% if @page.person_followers.size > 0 %> | |
24 | + <%= _("%s following this article.") % [ pluralize(@page.person_followers.size, _("person"))]%> | |
25 | + <% else %> | |
26 | + <%= _("No one following this article yet.") %> | |
27 | + <% end %> | |
28 | +<% end %> | |
29 | +</span> | |
30 | + | |
13 | 31 | </span> |
14 | 32 | |
15 | 33 | <% if @page.display_hits? || @page.license.present? %> | ... | ... |
db/migrate/20151210230319_add_followers_count_to_article.rb
0 → 100644
... | ... | @@ -0,0 +1,13 @@ |
1 | +class AddFollowersCountToArticle < ActiveRecord::Migration | |
2 | + | |
3 | + def self.up | |
4 | + add_column :articles, :followers_count, :integer, :default => 0 | |
5 | + | |
6 | + execute "update articles set followers_count = (select count(*) from article_followers where article_followers.article_id = articles.id)" | |
7 | + end | |
8 | + | |
9 | + def self.down | |
10 | + remove_column :articles, :followers_count | |
11 | + end | |
12 | + | |
13 | +end | ... | ... |
db/schema.rb
... | ... | @@ -51,6 +51,18 @@ ActiveRecord::Schema.define(version: 20160202142247) do |
51 | 51 | add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], name: "index_action_tracker_notif_on_prof_id_act_tracker_id", unique: true, using: :btree |
52 | 52 | add_index "action_tracker_notifications", ["profile_id"], name: "index_action_tracker_notifications_on_profile_id", using: :btree |
53 | 53 | |
54 | + create_table "article_followers", force: :cascade do |t| | |
55 | + t.integer "person_id", null: false | |
56 | + t.integer "article_id", null: false | |
57 | + t.datetime "since" | |
58 | + t.datetime "created_at" | |
59 | + t.datetime "updated_at" | |
60 | + end | |
61 | + | |
62 | + add_index "article_followers", ["article_id"], name: "index_article_followers_on_article_id", using: :btree | |
63 | + add_index "article_followers", ["person_id", "article_id"], name: "index_article_followers_on_person_id_and_article_id", unique: true, using: :btree | |
64 | + add_index "article_followers", ["person_id"], name: "index_article_followers_on_person_id", using: :btree | |
65 | + | |
54 | 66 | create_table "article_privacy_exceptions", id: false, force: :cascade do |t| |
55 | 67 | t.integer "article_id" |
56 | 68 | t.integer "person_id" |
... | ... | @@ -101,6 +113,7 @@ ActiveRecord::Schema.define(version: 20160202142247) do |
101 | 113 | t.integer "spam_comments_count", default: 0 |
102 | 114 | t.integer "author_id" |
103 | 115 | t.integer "created_by_id" |
116 | + t.integer "followers_count" | |
104 | 117 | end |
105 | 118 | |
106 | 119 | add_index "article_versions", ["article_id"], name: "index_article_versions_on_article_id", using: :btree |
... | ... | @@ -154,6 +167,7 @@ ActiveRecord::Schema.define(version: 20160202142247) do |
154 | 167 | t.integer "author_id" |
155 | 168 | t.integer "created_by_id" |
156 | 169 | t.boolean "show_to_followers", default: true |
170 | + t.integer "followers_count", default: 0 | |
157 | 171 | end |
158 | 172 | |
159 | 173 | add_index "articles", ["comments_count"], name: "index_articles_on_comments_count", using: :btree | ... | ... |
lib/noosfero/api/entities.rb
lib/noosfero/api/v1/articles.rb
... | ... | @@ -112,6 +112,37 @@ module Noosfero |
112 | 112 | {:vote => vote.save} |
113 | 113 | end |
114 | 114 | |
115 | + desc "Returns the total followers for the article" do | |
116 | + detail 'Get the followers of a specific article by id' | |
117 | + failure [[403, 'Forbidden']] | |
118 | + named 'ArticleFollowers' | |
119 | + end | |
120 | + get ':id/followers' do | |
121 | + article = find_article(environment.articles, params[:id]) | |
122 | + total = article.person_followers.count | |
123 | + {:total_followers => total} | |
124 | + end | |
125 | + | |
126 | + desc "Add a follower for the article" do | |
127 | + detail 'Add the current user identified by private token, like a follower of a article' | |
128 | + params Noosfero::API::Entities::UserLogin.documentation | |
129 | + failure [[401, 'Unauthorized']] | |
130 | + named 'ArticleFollow' | |
131 | + end | |
132 | + post ':id/follow' do | |
133 | + authenticate! | |
134 | + article = find_article(environment.articles, params[:id]) | |
135 | + if article.article_followers.exists?(:person_id => current_person.id) | |
136 | + {:success => false, :already_follow => true} | |
137 | + else | |
138 | + article_follower = ArticleFollower.new | |
139 | + article_follower.article = article | |
140 | + article_follower.person = current_person | |
141 | + article_follower.save! | |
142 | + {:success => true} | |
143 | + end | |
144 | + end | |
145 | + | |
115 | 146 | desc 'Return the children of a article identified by id' do |
116 | 147 | detail 'Get all children articles of a specific article' |
117 | 148 | params Noosfero::API::Entities::Article.documentation | ... | ... |
test/functional/comment_controller_test.rb
... | ... | @@ -387,10 +387,26 @@ class CommentControllerTest < ActionController::TestCase |
387 | 387 | Article.record_timestamps = true |
388 | 388 | |
389 | 389 | login_as @profile.identifier |
390 | - xhr :post, :create, :profile => profile.identifier, :id => page.id, :comment => { :title => 'crap!', :body => 'I think that this article is crap' }, :confirm => 'true' | |
390 | + xhr :post, :create, :profile => profile.identifier, :id => page.id, :comment => {:title => 'crap!', :body => 'I think that this article is crap' }, :confirm => 'true' | |
391 | 391 | assert_not_equal yesterday, page.reload.updated_at |
392 | 392 | end |
393 | 393 | |
394 | + should 'follow article when commenting' do | |
395 | + page = create(Article, :profile => profile, :name => 'myarticle', :body => 'the body of the text') | |
396 | + login_as @profile.identifier | |
397 | + | |
398 | + xhr :post, :create, :profile => profile.identifier, :id => page.id, :comment => {:title => 'crap!', :body => 'I think that this article is crap', :follow_article => true}, :confirm => 'true' | |
399 | + assert_includes page.person_followers, @profile | |
400 | + end | |
401 | + | |
402 | + should 'not follow article when commenting' do | |
403 | + page = create(Article, :profile => profile, :name => 'myarticle', :body => 'the body of the text') | |
404 | + login_as @profile.identifier | |
405 | + | |
406 | + xhr :post, :create, :profile => profile.identifier, :id => page.id, :comment => {:title => 'crap!', :body => 'I think that this article is crap', :follow_article => false }, :confirm => 'true' | |
407 | + assert_not_includes page.person_followers, @profile | |
408 | + end | |
409 | + | |
394 | 410 | should 'be able to mark comments as spam' do |
395 | 411 | login_as profile.identifier |
396 | 412 | article = fast_create(Article, :profile_id => profile.id) | ... | ... |
test/functional/content_viewer_controller_test.rb
... | ... | @@ -1278,18 +1278,6 @@ class ContentViewerControllerTest < ActionController::TestCase |
1278 | 1278 | assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :title => 'This button is expired.', :class => 'button with-text icon-edit disabled' } } |
1279 | 1279 | end |
1280 | 1280 | |
1281 | - should 'remove email from article followers when unfollow' do | |
1282 | - profile = create_user('testuser').person | |
1283 | - follower_email = 'john@doe.br' | |
1284 | - article = profile.articles.create(:name => 'test') | |
1285 | - article.followers = [follower_email] | |
1286 | - article.save | |
1287 | - | |
1288 | - assert_includes Article.find(article.id).followers, follower_email | |
1289 | - post :view_page, :profile => profile.identifier, :page => [article.name], :unfollow => 'commit', :email => follower_email | |
1290 | - assert_not_includes Article.find(article.id).followers, follower_email | |
1291 | - end | |
1292 | - | |
1293 | 1281 | should 'not display comments marked as spam' do |
1294 | 1282 | article = fast_create(Article, :profile_id => profile.id) |
1295 | 1283 | ham = fast_create(Comment, :source_id => article.id, :source_type => 'Article', :title => 'some content') | ... | ... |
test/functional/profile_controller_test.rb
... | ... | @@ -18,6 +18,19 @@ class ProfileControllerTest < ActionController::TestCase |
18 | 18 | assert assigns(:friends) |
19 | 19 | end |
20 | 20 | |
21 | + should 'remove person from article followers when unfollow' do | |
22 | + profile = create_user('testuser').person | |
23 | + follower = create_user('follower').person | |
24 | + article = profile.articles.create(:name => 'test') | |
25 | + article.person_followers = [follower] | |
26 | + article.save | |
27 | + login_as('follower') | |
28 | + article.reload | |
29 | + assert_includes Article.find(article.id).person_followers, follower | |
30 | + post :unfollow_article, :article_id => article.id | |
31 | + assert_not_includes Article.find(article.id).person_followers, follower | |
32 | + end | |
33 | + | |
21 | 34 | should 'point to manage friends in user is seeing his own friends' do |
22 | 35 | login_as('testuser') |
23 | 36 | get :friends |
... | ... | @@ -1338,6 +1351,24 @@ class ProfileControllerTest < ActionController::TestCase |
1338 | 1351 | assert_equivalent [scrap,activity], assigns(:activities).map(&:activity) |
1339 | 1352 | end |
1340 | 1353 | |
1354 | + should "follow an article" do | |
1355 | + article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') | |
1356 | + login_as(@profile.identifier) | |
1357 | + post :follow_article, :profile => profile.identifier, :article_id => article.id | |
1358 | + assert_includes article.person_followers, @profile | |
1359 | + end | |
1360 | + | |
1361 | + should "unfollow an article" do | |
1362 | + article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') | |
1363 | + article.person_followers << @profile | |
1364 | + article.save! | |
1365 | + assert_includes article.person_followers, @profile | |
1366 | + | |
1367 | + login_as(@profile.identifier) | |
1368 | + post :unfollow_article, :profile => profile.identifier, :article_id => article.id | |
1369 | + assert_not_includes article.person_followers, @profile | |
1370 | + end | |
1371 | + | |
1341 | 1372 | should "be logged in to leave comment on an activity" do |
1342 | 1373 | article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') |
1343 | 1374 | activity = ActionTracker::Record.last | ... | ... |
test/unit/api/articles_test.rb
... | ... | @@ -39,6 +39,41 @@ class ArticlesTest < ActiveSupport::TestCase |
39 | 39 | assert_equal 403, last_response.status |
40 | 40 | end |
41 | 41 | |
42 | + should 'follow a article identified by id' do | |
43 | + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") | |
44 | + post "/api/v1/articles/#{article.id}/follow?#{params.to_query}" | |
45 | + json = JSON.parse(last_response.body) | |
46 | + | |
47 | + assert_not_equal 401, last_response.status | |
48 | + assert_equal true, json['success'] | |
49 | + end | |
50 | + | |
51 | + should 'return the followers count of an article' do | |
52 | + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") | |
53 | + article.person_followers << @person | |
54 | + | |
55 | + get "/api/v1/articles/#{article.id}?#{params.to_query}" | |
56 | + json = JSON.parse(last_response.body) | |
57 | + | |
58 | + assert_equal 200, last_response.status | |
59 | + assert_equal 1, json['article']['followers_count'] | |
60 | + end | |
61 | + | |
62 | + should 'return the followers of a article identified by id' do | |
63 | + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") | |
64 | + | |
65 | + article_follower = ArticleFollower.new | |
66 | + article_follower.article = article | |
67 | + article_follower.person = @person | |
68 | + article_follower.save! | |
69 | + | |
70 | + get "/api/v1/articles/#{article.id}/followers?#{params.to_query}" | |
71 | + json = JSON.parse(last_response.body) | |
72 | + | |
73 | + assert_equal 200, last_response.status | |
74 | + assert_equal 1, json['total_followers'] | |
75 | + end | |
76 | + | |
42 | 77 | should 'list article children' do |
43 | 78 | article = fast_create(Article, :profile_id => user.person.id, :name => "Some thing") |
44 | 79 | child1 = fast_create(Article, :parent_id => article.id, :profile_id => user.person.id, :name => "Some thing") | ... | ... |
test/unit/article_test.rb
... | ... | @@ -22,6 +22,21 @@ class ArticleTest < ActiveSupport::TestCase |
22 | 22 | refute a.errors[:profile_id.to_s].present? |
23 | 23 | end |
24 | 24 | |
25 | + should 'keep unique users in list of followers' do | |
26 | + person1 = create_user('article_owner').person | |
27 | + person2 = create_user('article_follower').person | |
28 | + | |
29 | + article = fast_create(Article, :profile_id => person1.id) | |
30 | + | |
31 | + article.person_followers=[person2] | |
32 | + article.save | |
33 | + article.reload | |
34 | + article.person_followers=[person2] | |
35 | + article.save | |
36 | + | |
37 | + assert_equal 1, article.reload.person_followers.size | |
38 | + end | |
39 | + | |
25 | 40 | should 'require value for name' do |
26 | 41 | a = Article.new |
27 | 42 | a.valid? |
... | ... | @@ -1700,7 +1715,7 @@ class ArticleTest < ActiveSupport::TestCase |
1700 | 1715 | |
1701 | 1716 | should 'has a empty list of followers by default' do |
1702 | 1717 | a = Article.new |
1703 | - assert_equal [], a.followers | |
1718 | + assert_equal [], a.person_followers | |
1704 | 1719 | end |
1705 | 1720 | |
1706 | 1721 | should 'get first image from lead' do | ... | ... |
test/unit/comment_notifier_test.rb
... | ... | @@ -60,7 +60,7 @@ class CommentNotifierTest < ActiveSupport::TestCase |
60 | 60 | should "deliver mail to followers" do |
61 | 61 | author = create_user('follower_author').person |
62 | 62 | follower = create_user('follower').person |
63 | - @article.followers += [follower.email] | |
63 | + @article.person_followers += [follower] | |
64 | 64 | @article.save! |
65 | 65 | create_comment_and_notify(:source => @article, :author => author, :title => 'comment title', :body => 'comment body') |
66 | 66 | assert_includes ActionMailer::Base.deliveries.map(&:bcc).flatten, follower.email | ... | ... |
test/unit/comment_test.rb
... | ... | @@ -328,34 +328,27 @@ class CommentTest < ActiveSupport::TestCase |
328 | 328 | assert c.rejected? |
329 | 329 | end |
330 | 330 | |
331 | - should 'subscribe user as follower of an article on new comment' do | |
331 | + should 'not subscribe user as follower of an article automatically on new comment' do | |
332 | 332 | owner = create_user('owner_of_article').person |
333 | 333 | person = create_user('follower').person |
334 | 334 | article = fast_create(Article, :profile_id => owner.id) |
335 | - assert_not_includes article.followers, person.email | |
335 | + assert_not_includes article.person_followers, person | |
336 | 336 | create(Comment, :source => article, :author => person, :title => 'new comment', :body => 'new comment') |
337 | - assert_includes article.reload.followers, person.email | |
337 | + assert_not_includes article.reload.person_followers, person | |
338 | 338 | end |
339 | 339 | |
340 | - should 'subscribe guest user as follower of an article on new comment' do | |
340 | + should 'not subscribe guest user as follower of an article on new comment' do | |
341 | 341 | article = fast_create(Article, :profile_id => create_user('article_owner').person.id) |
342 | - assert_not_includes article.followers, 'follower@example.com' | |
342 | + old_num_followers = article.reload.person_followers.size | |
343 | 343 | create(Comment, :source => article, :name => 'follower', :email => 'follower@example.com', :title => 'new comment', :body => 'new comment') |
344 | - assert_includes article.reload.followers, 'follower@example.com' | |
345 | - end | |
346 | - | |
347 | - should 'keep unique emails in list of followers' do | |
348 | - article = fast_create(Article, :profile_id => create_user('article_owner').person.id) | |
349 | - create(Comment, :source => article, :name => 'follower one', :email => 'follower@example.com', :title => 'new comment', :body => 'new comment') | |
350 | - create(Comment, :source => article, :name => 'follower two', :email => 'follower@example.com', :title => 'another comment', :body => 'new comment') | |
351 | - assert_equal 1, article.reload.followers.select{|v| v == 'follower@example.com'}.count | |
344 | + assert_equal old_num_followers, article.reload.person_followers.size | |
352 | 345 | end |
353 | 346 | |
354 | 347 | should 'not subscribe owner as follower of an article on new comment' do |
355 | 348 | owner = create_user('owner_of_article').person |
356 | 349 | article = fast_create(Article, :profile_id => owner.id) |
357 | 350 | create(Comment, :source => article, :author => owner, :title => 'new comment', :body => 'new comment') |
358 | - assert_not_includes article.reload.followers, owner.email | |
351 | + assert_not_includes article.reload.person_followers, owner | |
359 | 352 | end |
360 | 353 | |
361 | 354 | should 'not subscribe admins as follower of an article on new comment' do |
... | ... | @@ -366,8 +359,13 @@ class CommentTest < ActiveSupport::TestCase |
366 | 359 | article = fast_create(Article, :profile_id => owner.id) |
367 | 360 | create(Comment, :source => article, :author => follower, :title => 'new comment', :body => 'new comment') |
368 | 361 | create(Comment, :source => article, :author => admin, :title => 'new comment', :body => 'new comment') |
369 | - assert_not_includes article.reload.followers, admin.email | |
370 | - assert_includes article.followers, follower.email | |
362 | + | |
363 | + article.person_followers += [follower] | |
364 | + article.save! | |
365 | + article.reload | |
366 | + | |
367 | + assert_not_includes article.reload.person_followers, admin | |
368 | + assert_includes article.reload.person_followers, follower | |
371 | 369 | end |
372 | 370 | |
373 | 371 | should 'update article activity when add a comment' do | ... | ... |
test/unit/person_notifier_test.rb
... | ... | @@ -49,7 +49,8 @@ class PersonNotifierTest < ActiveSupport::TestCase |
49 | 49 | should 'display author name in delivered mail' do |
50 | 50 | @community.add_member(@member) |
51 | 51 | User.current = @admin.user |
52 | - Comment.create!(:author => @admin, :title => 'test comment', :body => 'body!', :source => @article) | |
52 | + comment = Comment.create!(:author => @admin, :title => 'test comment', :body => 'body!', :source => @article) | |
53 | + comment.save! | |
53 | 54 | process_delayed_job_queue |
54 | 55 | notify |
55 | 56 | sent = ActionMailer::Base.deliveries.last | ... | ... |