Commit f644224ed4f27658c1370dac099c76ecead439f3

Authored by Victor Costa
2 parents 2547177c 23636102

Merge branch 'master' into rails3

Conflicts:
	plugins/display_content/test/unit/display_content_block_test.rb
Showing 75 changed files with 1725 additions and 477 deletions   Show diff stats
app/controllers/admin/environment_design_controller.rb
@@ -5,7 +5,7 @@ class EnvironmentDesignController < BoxOrganizerController @@ -5,7 +5,7 @@ class EnvironmentDesignController < BoxOrganizerController
5 def available_blocks 5 def available_blocks
6 # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from 6 # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
7 # the Noosfero core soon, see ActionItem3045 7 # the Noosfero core soon, see ActionItem3045
8 - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 8 + @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) 9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
10 end 10 end
11 11
app/controllers/my_profile/cms_controller.rb
@@ -144,6 +144,7 @@ class CmsController < MyProfileController @@ -144,6 +144,7 @@ class CmsController < MyProfileController
144 144
145 @article.profile = profile 145 @article.profile = profile
146 @article.last_changed_by = user 146 @article.last_changed_by = user
  147 + @article.created_by = user
147 148
148 translations if @article.translatable? 149 translations if @article.translatable?
149 150
app/controllers/my_profile/profile_design_controller.rb
@@ -9,14 +9,8 @@ class ProfileDesignController < BoxOrganizerController @@ -9,14 +9,8 @@ class ProfileDesignController < BoxOrganizerController
9 9
10 blocks += plugins.dispatch(:extra_blocks) 10 blocks += plugins.dispatch(:extra_blocks)
11 11
12 - # blocks exclusive for organizations  
13 - if profile.has_members?  
14 - blocks << MembersBlock  
15 - end  
16 -  
17 # blocks exclusive to people 12 # blocks exclusive to people
18 if profile.person? 13 if profile.person?
19 - blocks << FriendsBlock  
20 blocks << FavoriteEnterprisesBlock 14 blocks << FavoriteEnterprisesBlock
21 blocks << CommunitiesBlock 15 blocks << CommunitiesBlock
22 blocks << EnterprisesBlock 16 blocks << EnterprisesBlock
app/helpers/sweeper_helper.rb
@@ -18,9 +18,7 @@ module SweeperHelper @@ -18,9 +18,7 @@ module SweeperHelper
18 expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) 18 expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s))
19 end 19 end
20 20
21 - # friends blocks  
22 - blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)}  
23 - BlockSweeper.expire_blocks(blocks) 21 + expire_blocks_cache(profile, [:profile])
24 end 22 end
25 23
26 def expire_communities(profile) 24 def expire_communities(profile)
app/models/approve_article.rb
@@ -48,7 +48,7 @@ class ApproveArticle &lt; Task @@ -48,7 +48,7 @@ class ApproveArticle &lt; Task
48 end 48 end
49 49
50 def perform 50 def perform
51 - article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.author_id) 51 + article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.last_changed_by_id, :created_by_id => article.created_by_id)
52 end 52 end
53 53
54 def title 54 def title
app/models/article.rb
@@ -40,12 +40,6 @@ class Article &lt; ActiveRecord::Base @@ -40,12 +40,6 @@ class Article &lt; ActiveRecord::Base
40 # xss_terminate plugin can't sanitize array fields 40 # xss_terminate plugin can't sanitize array fields
41 before_save :sanitize_tag_list 41 before_save :sanitize_tag_list
42 42
43 - before_create do |article|  
44 - if article.last_changed_by_id  
45 - article.author_name = Person.find(article.last_changed_by_id).name  
46 - end  
47 - end  
48 -  
49 belongs_to :profile 43 belongs_to :profile
50 validates_presence_of :profile_id, :name 44 validates_presence_of :profile_id, :name
51 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? } 45 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? }
@@ -55,6 +49,7 @@ class Article &lt; ActiveRecord::Base @@ -55,6 +49,7 @@ class Article &lt; ActiveRecord::Base
55 validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } 49 validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? }
56 50
57 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' 51 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
  52 + belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id'
58 53
59 has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' 54 has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc'
60 55
@@ -89,6 +84,11 @@ class Article &lt; ActiveRecord::Base @@ -89,6 +84,11 @@ class Article &lt; ActiveRecord::Base
89 article.parent = article.profile.blog 84 article.parent = article.profile.blog
90 end 85 end
91 end 86 end
  87 +
  88 + if article.created_by
  89 + article.author_name = article.created_by.name
  90 + end
  91 +
92 end 92 end
93 93
94 after_destroy :destroy_activity 94 after_destroy :destroy_activity
@@ -205,6 +205,10 @@ class Article &lt; ActiveRecord::Base @@ -205,6 +205,10 @@ class Article &lt; ActiveRecord::Base
205 acts_as_versioned 205 acts_as_versioned
206 self.non_versioned_columns << 'setting' 206 self.non_versioned_columns << 'setting'
207 207
  208 + def version_condition_met?
  209 + (['name', 'body', 'abstract', 'filename', 'start_date', 'end_date', 'image_id', 'license_id'] & changed).length > 0
  210 + end
  211 +
208 def comment_data 212 def comment_data
209 comments.map {|item| [item.title, item.body].join(' ') }.join(' ') 213 comments.map {|item| [item.title, item.body].join(' ') }.join(' ')
210 end 214 end
@@ -630,17 +634,13 @@ class Article &lt; ActiveRecord::Base @@ -630,17 +634,13 @@ class Article &lt; ActiveRecord::Base
630 634
631 def author(version_number = nil) 635 def author(version_number = nil)
632 if version_number 636 if version_number
633 - version = versions.find_by_version(version_number) 637 + version = self.versions.find_by_version(version_number)
634 author_id = version.last_changed_by_id if version 638 author_id = version.last_changed_by_id if version
635 - Person.exists?(author_id) ? Person.find(author_id) : nil  
636 else 639 else
637 - if versions.empty?  
638 - last_changed_by  
639 - else  
640 - author_id = versions.first.last_changed_by_id  
641 - Person.exists?(author_id) ? Person.find(author_id) : nil  
642 - end 640 + author_id = self.created_by_id
643 end 641 end
  642 +
  643 + environment.people.find_by_id(author_id)
644 end 644 end
645 645
646 def author_name(version_number = nil) 646 def author_name(version_number = nil)
app/models/box.rb
@@ -34,14 +34,11 @@ class Box &lt; ActiveRecord::Base @@ -34,14 +34,11 @@ class Box &lt; ActiveRecord::Base
34 FansBlock, 34 FansBlock,
35 FavoriteEnterprisesBlock, 35 FavoriteEnterprisesBlock,
36 FeedReaderBlock, 36 FeedReaderBlock,
37 - FriendsBlock,  
38 HighlightsBlock, 37 HighlightsBlock,
39 LinkListBlock, 38 LinkListBlock,
40 LoginBlock, 39 LoginBlock,
41 MainBlock, 40 MainBlock,
42 - MembersBlock,  
43 MyNetworkBlock, 41 MyNetworkBlock,
44 - PeopleBlock,  
45 ProfileImageBlock, 42 ProfileImageBlock,
46 RawHTMLBlock, 43 RawHTMLBlock,
47 RecentDocumentsBlock, 44 RecentDocumentsBlock,
@@ -63,14 +60,11 @@ class Box &lt; ActiveRecord::Base @@ -63,14 +60,11 @@ class Box &lt; ActiveRecord::Base
63 FavoriteEnterprisesBlock, 60 FavoriteEnterprisesBlock,
64 FeaturedProductsBlock, 61 FeaturedProductsBlock,
65 FeedReaderBlock, 62 FeedReaderBlock,
66 - FriendsBlock,  
67 HighlightsBlock, 63 HighlightsBlock,
68 LinkListBlock, 64 LinkListBlock,
69 LocationBlock, 65 LocationBlock,
70 LoginBlock, 66 LoginBlock,
71 - MembersBlock,  
72 MyNetworkBlock, 67 MyNetworkBlock,
73 - PeopleBlock,  
74 ProductsBlock, 68 ProductsBlock,
75 ProductCategoriesBlock, 69 ProductCategoriesBlock,
76 ProfileImageBlock, 70 ProfileImageBlock,
app/models/community.rb
@@ -85,10 +85,6 @@ class Community &lt; Organization @@ -85,10 +85,6 @@ class Community &lt; Organization
85 recent_documents(limit, ["articles.type != ? AND articles.highlighted = ?", 'Folder', highlight]) 85 recent_documents(limit, ["articles.type != ? AND articles.highlighted = ?", 'Folder', highlight])
86 end 86 end
87 87
88 - def blocks_to_expire_cache  
89 - [MembersBlock]  
90 - end  
91 -  
92 def each_member(offset=0) 88 def each_member(offset=0)
93 while member = self.members.first(:order => :id, :offset => offset) 89 while member = self.members.first(:order => :id, :offset => offset)
94 yield member 90 yield member
app/models/environment.rb
@@ -182,7 +182,6 @@ class Environment &lt; ActiveRecord::Base @@ -182,7 +182,6 @@ class Environment &lt; ActiveRecord::Base
182 182
183 # "right" area 183 # "right" area
184 env.boxes[2].blocks << CommunitiesBlock.new(:limit => 6) 184 env.boxes[2].blocks << CommunitiesBlock.new(:limit => 6)
185 - env.boxes[2].blocks << PeopleBlock.new(:limit => 6)  
186 end 185 end
187 186
188 # One Environment can be reached by many domains 187 # One Environment can be reached by many domains
app/models/friends_block.rb
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -class FriendsBlock < ProfileListBlock  
2 -  
3 - def self.description  
4 - _('Friends')  
5 - end  
6 -  
7 - def default_title  
8 - n_('{#} friend', '{#} friends', profile_count)  
9 - end  
10 -  
11 - def help  
12 - _('This block displays your friends.')  
13 - end  
14 -  
15 - def footer  
16 - owner_id = owner.identifier  
17 - proc do  
18 - link_to s_('friends|View all'), :profile => owner_id, :controller => 'profile', :action => 'friends'  
19 - end  
20 - end  
21 -  
22 - def profiles  
23 - owner.friends  
24 - end  
25 -  
26 -end  
app/models/members_block.rb
@@ -1,52 +0,0 @@ @@ -1,52 +0,0 @@
1 -class MembersBlock < ProfileListBlock  
2 - settings_items :show_join_leave_button, :type => :boolean, :default => false  
3 -  
4 - attr_accessible :show_join_leave_button  
5 -  
6 - def self.description  
7 - _('Members')  
8 - end  
9 -  
10 - def default_title  
11 - _('{#} members')  
12 - end  
13 -  
14 - def help  
15 - _('This block presents the members of a collective.')  
16 - end  
17 -  
18 - def footer  
19 - profile = self.owner  
20 - s = show_join_leave_button  
21 -  
22 - proc do  
23 - render :file => 'blocks/members', :locals => { :profile => profile, :show_join_leave_button => s}  
24 - end  
25 - end  
26 -  
27 - def profiles  
28 - owner.members  
29 - end  
30 -  
31 - def extra_option  
32 - data = {  
33 - :human_name => _("Show join leave button"),  
34 - :name => 'block[show_join_leave_button]',  
35 - :value => true,  
36 - :checked => show_join_leave_button,  
37 - :options => {}  
38 - }  
39 - end  
40 -  
41 - def cache_key(language='en', user=nil)  
42 - logged = ''  
43 - if user  
44 - logged += '-logged-in'  
45 - if user.is_member_of? self.owner  
46 - logged += '-member'  
47 - end  
48 - end  
49 - super + logged  
50 - end  
51 -  
52 -end  
app/models/organization.rb
@@ -123,7 +123,7 @@ class Organization &lt; Profile @@ -123,7 +123,7 @@ class Organization &lt; Profile
123 [ 123 [
124 [MainBlock.new], 124 [MainBlock.new],
125 [ProfileImageBlock.new, LinkListBlock.new(:links => links)], 125 [ProfileImageBlock.new, LinkListBlock.new(:links => links)],
126 - [MembersBlock.new, RecentDocumentsBlock.new] 126 + [RecentDocumentsBlock.new]
127 ] 127 ]
128 end 128 end
129 129
app/models/people_block.rb
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -class PeopleBlock < ProfileListBlock  
2 -  
3 - def default_title  
4 - _('People')  
5 - end  
6 -  
7 - def help  
8 - _('Clicking a person takes you to his/her homepage')  
9 - end  
10 -  
11 - def self.description  
12 - _('Random people')  
13 - end  
14 -  
15 - def profiles  
16 - owner.people  
17 - end  
18 -  
19 - def footer  
20 - lambda do |context|  
21 - link_to _('View all'), :controller => 'search', :action => 'people'  
22 - end  
23 - end  
24 -  
25 -end  
app/models/person.rb
@@ -269,7 +269,7 @@ class Person &lt; Profile @@ -269,7 +269,7 @@ class Person &lt; Profile
269 [ 269 [
270 [MainBlock.new], 270 [MainBlock.new],
271 [ProfileImageBlock.new(:show_name => true), LinkListBlock.new(:links => links), RecentDocumentsBlock.new], 271 [ProfileImageBlock.new(:show_name => true), LinkListBlock.new(:links => links), RecentDocumentsBlock.new],
272 - [FriendsBlock.new, CommunitiesBlock.new] 272 + [CommunitiesBlock.new]
273 ] 273 ]
274 end 274 end
275 275
app/sweepers/friendship_sweeper.rb
@@ -34,8 +34,7 @@ protected @@ -34,8 +34,7 @@ protected
34 expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) 34 expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s))
35 end 35 end
36 36
37 - blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)}  
38 - BlockSweeper.expire_blocks(blocks) 37 + expire_blocks_cache(profile, [:profile])
39 end 38 end
40 39
41 end 40 end
app/views/blocks/members.html.erb
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -<%= link_to _('View all'), :profile => profile.identifier, :controller => 'profile', :action => 'members' %>  
2 -  
3 -<% if show_join_leave_button %>  
4 - <%= render :partial => 'blocks/profile_info_actions/join_leave_community' %>  
5 -<% end %>  
app/views/layouts/application-ng.html.erb
@@ -83,5 +83,10 @@ @@ -83,5 +83,10 @@
83 <%= noosfero_layout_features %> 83 <%= noosfero_layout_features %>
84 <%= theme_javascript_ng %> 84 <%= theme_javascript_ng %>
85 <%= addthis_javascript %> 85 <%= addthis_javascript %>
  86 + <%=
  87 + @plugins.dispatch(:body_ending).map do |content|
  88 + if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end
  89 + end.join("\n")
  90 + %>
86 </body> 91 </body>
87 </html> 92 </html>
config/application.rb
@@ -20,7 +20,7 @@ module Noosfero @@ -20,7 +20,7 @@ module Noosfero
20 require 'noosfero/plugin' 20 require 'noosfero/plugin'
21 21
22 # Adds custom attributes to the Set of allowed html attributes for the #sanitize helper 22 # Adds custom attributes to the Set of allowed html attributes for the #sanitize helper
23 - config.action_view.sanitized_allowed_attributes = 'align', 'border', 'alt', 'vspace', 'hspace', 'width', 'heigth', 'value', 'type', 'data', 'style', 'target', 'codebase', 'archive', 'classid', 'code', 'flashvars', 'scrolling', 'frameborder', 'controls', 'autoplay' 23 + config.action_view.sanitized_allowed_attributes = 'align', 'border', 'alt', 'vspace', 'hspace', 'width', 'heigth', 'value', 'type', 'data', 'style', 'target', 'codebase', 'archive', 'classid', 'code', 'flashvars', 'scrolling', 'frameborder', 'controls', 'autoplay', 'colspan', 'rowspan'
24 24
25 # Adds custom tags to the Set of allowed html tags for the #sanitize helper 25 # Adds custom tags to the Set of allowed html tags for the #sanitize helper
26 config.action_view.sanitized_allowed_tags = 'object', 'embed', 'param', 'table', 'tr', 'th', 'td', 'applet', 'comment', 'iframe', 'audio', 'video', 'source' 26 config.action_view.sanitized_allowed_tags = 'object', 'embed', 'param', 'table', 'tr', 'th', 'td', 'applet', 'comment', 'iframe', 'audio', 'video', 'source'
config/plugins/people_block 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../plugins/people_block
0 \ No newline at end of file 2 \ No newline at end of file
db/migrate/20140415125414_add_created_by_to_article.rb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +class AddCreatedByToArticle < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :created_by_id, :integer
  4 + add_column :article_versions, :created_by_id, :integer
  5 +
  6 + execute("UPDATE article_versions SET created_by_id = last_changed_by_id")
  7 +
  8 + execute("UPDATE articles SET created_by_id = article_versions.created_by_id
  9 +FROM article_versions WHERE article_versions.article_id = articles.id AND
  10 +article_versions.version = 1")
  11 + end
  12 +
  13 + def self.down
  14 + remove_column :articles, :created_by_id
  15 + remove_column :article_versions, :created_by_id
  16 + end
  17 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20140408172149) do 14 +ActiveRecord::Schema.define(:version => 20140415125414) do
15 15
16 create_table "abuse_reports", :force => true do |t| 16 create_table "abuse_reports", :force => true do |t|
17 t.integer "reporter_id" 17 t.integer "reporter_id"
@@ -95,6 +95,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140408172149) do @@ -95,6 +95,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140408172149) do
95 t.integer "license_id" 95 t.integer "license_id"
96 t.integer "image_id" 96 t.integer "image_id"
97 t.integer "position" 97 t.integer "position"
  98 + t.integer "created_by_id"
98 end 99 end
99 100
100 add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id" 101 add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id"
@@ -140,6 +141,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140408172149) do @@ -140,6 +141,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140408172149) do
140 t.integer "license_id" 141 t.integer "license_id"
141 t.integer "image_id" 142 t.integer "image_id"
142 t.integer "position" 143 t.integer "position"
  144 + t.integer "created_by_id"
143 end 145 end
144 146
145 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count" 147 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
features/my_network_block.feature
@@ -9,9 +9,11 @@ Feature: my_network_block @@ -9,9 +9,11 @@ Feature: my_network_block
9 And the following blocks 9 And the following blocks
10 | owner | type | 10 | owner | type |
11 | joaosilva | MyNetworkBlock | 11 | joaosilva | MyNetworkBlock |
  12 + | joaosilva | FriendsBlock |
12 And the following communities 13 And the following communities
13 | identifier | name | public_profile | 14 | identifier | name | public_profile |
14 | public-community | Public Community | true | 15 | public-community | Public Community | true |
  16 + And plugin FriendsBlock is enabled on environment
15 17
16 @selenium 18 @selenium
17 Scenario: display how many public/private communities I am member 19 Scenario: display how many public/private communities I am member
@@ -46,6 +48,10 @@ Feature: my_network_block @@ -46,6 +48,10 @@ Feature: my_network_block
46 | login | name | public_profile | 48 | login | name | public_profile |
47 | mariasilva | Maria Silva | true | 49 | mariasilva | Maria Silva | true |
48 | josesilva | Jose Silva | false | 50 | josesilva | Jose Silva | false |
  51 + And the following blocks
  52 + | owner | type |
  53 + | mariasilva | FriendsBlock |
  54 + | josesilva | FriendsBlock |
49 And "joaosilva" is friend of "mariasilva" 55 And "joaosilva" is friend of "mariasilva"
50 And I am logged in as "joaosilva" 56 And I am logged in as "joaosilva"
51 And I am on joaosilva's homepage 57 And I am on joaosilva's homepage
@@ -59,6 +65,10 @@ Feature: my_network_block @@ -59,6 +65,10 @@ Feature: my_network_block
59 | login | name | 65 | login | name |
60 | mariasilva | Maria Silva | 66 | mariasilva | Maria Silva |
61 | josesilva | Jose Silva | 67 | josesilva | Jose Silva |
  68 + And the following blocks
  69 + | owner | type |
  70 + | mariasilva | FriendsBlock |
  71 + | josesilva | FriendsBlock |
62 And "josesilva" is invisible 72 And "josesilva" is invisible
63 And "joaosilva" is friend of "mariasilva" 73 And "joaosilva" is friend of "mariasilva"
64 And I am logged in as "joaosilva" 74 And I am logged in as "joaosilva"
lib/noosfero/plugin.rb
@@ -277,6 +277,12 @@ class Noosfero::Plugin @@ -277,6 +277,12 @@ class Noosfero::Plugin
277 nil 277 nil
278 end 278 end
279 279
  280 + # -> Adds content to the ending of the page
  281 + # returns = lambda block that creates html code or raw rhtml/html.erb
  282 + def body_ending
  283 + nil
  284 + end
  285 +
280 # -> Adds content to the ending of the page head 286 # -> Adds content to the ending of the page head
281 # returns = lambda block that creates html code or raw rhtml/html.erb 287 # returns = lambda block that creates html code or raw rhtml/html.erb
282 def head_ending 288 def head_ending
plugins/display_content/lib/display_content_block.rb
@@ -102,7 +102,7 @@ class DisplayContentBlock &lt; Block @@ -102,7 +102,7 @@ class DisplayContentBlock &lt; Block
102 end 102 end
103 103
104 def parent_nodes 104 def parent_nodes
105 - @parent_nodes ||= self.holder.articles.find(nodes).map { |article| get_parent(article) }.compact.flatten 105 + @parent_nodes ||= self.holder.articles.where(:id => nodes).map { |article| get_parent(article) }.compact.flatten
106 end 106 end
107 107
108 VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum'] 108 VALID_CONTENT = ['RawHTMLArticle', 'TextArticle', 'TextileArticle', 'TinyMceArticle', 'Folder', 'Blog', 'Forum']
plugins/display_content/test/unit/display_content_block_test.rb
@@ -549,7 +549,7 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase @@ -549,7 +549,7 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase
549 a1 = fast_create(PluginArticle, :name => 'test article 1', :profile_id => profile.id) 549 a1 = fast_create(PluginArticle, :name => 'test article 1', :profile_id => profile.id)
550 Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) 550 Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
551 env = fast_create(Environment) 551 env = fast_create(Environment)
552 - env.enable_plugin(Plugin1) 552 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([Plugin1.new])
553 553
554 block = DisplayContentBlock.new 554 block = DisplayContentBlock.new
555 box = mock() 555 box = mock()
@@ -632,4 +632,19 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase @@ -632,4 +632,19 @@ class DisplayContentBlockTest &lt; ActiveSupport::TestCase
632 assert_equal [UploadedFile, Event, TinyMceArticle, TextileArticle, RawHTMLArticle, Folder, Blog, Forum, Gallery, RssFeed, SomePluginContent], block.available_content_types 632 assert_equal [UploadedFile, Event, TinyMceArticle, TextileArticle, RawHTMLArticle, Folder, Blog, Forum, Gallery, RssFeed, SomePluginContent], block.available_content_types
633 end 633 end
634 634
  635 + should 'do not fail if a selected article was removed' do
  636 + profile = create_user('testuser').person
  637 + Article.delete_all
  638 + f1 = fast_create(Folder, :name => 'test folder 1', :profile_id => profile.id)
  639 + a1 = fast_create(TextileArticle, :name => 'test article 1', :profile_id => profile.id, :parent_id => f1.id)
  640 +
  641 + checked_articles= {a1.id => true}
  642 +
  643 + block = DisplayContentBlock.new
  644 + block.stubs(:holder).returns(profile)
  645 + block.checked_nodes= checked_articles
  646 + a1.destroy
  647 + assert_equal [], block.parent_nodes
  648 + end
  649 +
635 end 650 end
plugins/people_block/before_disable.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +raise "\nPeopleBlockPlugin shouldn't be enabled/disabled by hand, Noosfero" +
  2 + "\ninstallation already comes with it enabled by default!\n"
plugins/people_block/controllers/people_block_plugin_profile_controller.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class PeopleBlockPluginProfileController < ProfileController
  2 +
  3 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  4 +
  5 + def members
  6 + if is_cache_expired?(profile.members_cache_key(params))
  7 + if(params[:role_key])
  8 + role = Role.find_by_key_and_environment_id(params[:role_key], profile.environment)
  9 + @members = profile.members.with_role(role.id).includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
  10 + @members_title = role.name
  11 + else
  12 + @members = profile.members.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
  13 + @members_title = 'members'
  14 + end
  15 + end
  16 + render "profile/members"
  17 + end
  18 +
  19 +end
plugins/people_block/db/migrate/20140605222753_enable_people_block_plugin.rb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +class EnablePeopleBlockPlugin < ActiveRecord::Migration
  2 + def up
  3 + Environment.all.each do |env|
  4 + env.enabled_plugins << 'PeopleBlockPlugin'
  5 + env.enabled_plugins.uniq!
  6 + env.save!
  7 + end
  8 + end
  9 +
  10 + def down
  11 + Environment.all.each do |env|
  12 + env.enabled_plugins.delete_if {|i| i== 'PeopleBlockPlugin'}
  13 + env.save!
  14 + end
  15 + end
  16 +end
plugins/people_block/lib/ext/person.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +require_dependency 'person'
  2 +
  3 +class Person
  4 +
  5 + scope :with_role, lambda { |role_id|
  6 + { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ["role_assignments.role_id = #{role_id}"] }
  7 + }
  8 +
  9 +end
plugins/people_block/lib/friends_block.rb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +class FriendsBlock < PeopleBlockBase
  2 +
  3 + def self.description
  4 + _('Friends')
  5 + end
  6 +
  7 + def help
  8 + _('Clicking a friend takes you to his/her homepage')
  9 + end
  10 +
  11 + def default_title
  12 + n_('{#} friend', '{#} friends', profile_count)
  13 + end
  14 +
  15 + def profiles
  16 + owner.friends
  17 + end
  18 +
  19 + def footer
  20 + profile = self.owner
  21 + proc do
  22 + render :file => 'blocks/friends', :locals => { :profile => profile }
  23 + end
  24 + end
  25 +
  26 + def self.expire_on
  27 + { :profile => [:profile] }
  28 + end
  29 +
  30 +end
plugins/people_block/lib/members_block.rb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +class MembersBlock < PeopleBlockBase
  2 + settings_items :show_join_leave_button, :type => :boolean, :default => false
  3 + settings_items :visible_role, :type => :string, :default => nil
  4 + attr_accessible :show_join_leave_button, :visible_role
  5 +
  6 + def self.description
  7 + _('Members')
  8 + end
  9 +
  10 + def help
  11 + _('Clicking a member takes you to his/her homepage')
  12 + end
  13 +
  14 + def default_title
  15 + title = role ? role.name : n_('members')
  16 + _('{#} %s') % title
  17 + end
  18 +
  19 + def profiles
  20 + role ? owner.members.with_role(role.id) : owner.members
  21 + end
  22 +
  23 + def footer
  24 + profile = self.owner
  25 + role_key = visible_role
  26 + s = show_join_leave_button
  27 + proc do
  28 + render :file => 'blocks/members', :locals => { :profile => profile, :show_join_leave_button => s, :role_key => role_key}
  29 + end
  30 + end
  31 +
  32 + def role
  33 + visible_role && !visible_role.empty? ? Role.find_by_key_and_environment_id(visible_role, owner.environment) : nil
  34 + end
  35 +
  36 + def roles
  37 + Profile::Roles.organization_member_roles(owner.environment)
  38 + end
  39 +
  40 + def extra_option
  41 + data = {
  42 + :human_name => _("Show join leave button"),
  43 + :name => 'block[show_join_leave_button]',
  44 + :value => true,
  45 + :checked => show_join_leave_button,
  46 + :options => {}
  47 + }
  48 + end
  49 +
  50 +end
plugins/people_block/lib/people_block.rb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +class PeopleBlock < PeopleBlockBase
  2 +
  3 + def self.description
  4 + _('People')
  5 + end
  6 +
  7 + def help
  8 + _('Clicking a person takes you to his/her homepage')
  9 + end
  10 +
  11 + def default_title
  12 + _('{#} People')
  13 + end
  14 +
  15 + def profiles
  16 + owner.people
  17 + end
  18 +
  19 + def footer
  20 + proc do
  21 + render :file => 'blocks/people'
  22 + end
  23 + end
  24 +
  25 +end
plugins/people_block/lib/people_block_base.rb 0 → 100644
@@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
  1 +class PeopleBlockBase < Block
  2 + settings_items :prioritize_profiles_with_image, :type => :boolean, :default => true
  3 + settings_items :limit, :type => :integer, :default => 6
  4 + settings_items :name, :type => String, :default => ""
  5 + settings_items :address, :type => String, :default => ""
  6 + attr_accessible :name, :address, :prioritize_profiles_with_image
  7 +
  8 + def self.description
  9 + _('Random people')
  10 + end
  11 +
  12 + def help
  13 + _('Clicking on the people or groups will take you to their home page.')
  14 + end
  15 +
  16 + def default_title
  17 + _('{#} People')
  18 + end
  19 +
  20 + def view_title
  21 + title.gsub('{#}', profile_count.to_s)
  22 + end
  23 +
  24 + def profiles
  25 + owner.profiles
  26 + end
  27 +
  28 + def profile_list
  29 + result = nil
  30 + visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment])
  31 + if !prioritize_profiles_with_image
  32 + result = visible_profiles.all(:limit => limit, :order => 'updated_at DESC').sort_by{ rand }
  33 + elsif visible_profiles.with_image.count >= limit
  34 + result = visible_profiles.with_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand }
  35 + else
  36 + result = visible_profiles.with_image.sort_by{ rand } + visible_profiles.without_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand }
  37 + end
  38 + result.slice(0..limit-1)
  39 + end
  40 +
  41 + def profile_count
  42 + profiles.visible.count
  43 + end
  44 +
  45 + def content(args={})
  46 + profiles = self.profile_list
  47 + title = self.view_title
  48 +
  49 + if !self.name.blank? && !self.address.blank?
  50 + name = self.name
  51 + expanded_address = expand_address(self.address)
  52 + end
  53 +
  54 + proc do
  55 + count = 0
  56 + list = profiles.map {|item|
  57 + count += 1
  58 + send(:profile_image_link, item, :minor )
  59 + }.join("\n")
  60 + if list.empty?
  61 + list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none'
  62 + else
  63 + if !name.blank? && !expanded_address.blank?
  64 + list << content_tag(
  65 + 'div',
  66 + content_tag(
  67 + 'li',
  68 + content_tag(
  69 + 'div',
  70 + link_to(
  71 + content_tag('span', name, :class => 'banner-span' ),
  72 + expanded_address,
  73 + :title => name
  74 + ),
  75 + :class => 'banner-div'
  76 + ),
  77 + :class => 'vcard'
  78 + ),
  79 + :class => 'common-profile-list-block'
  80 + )
  81 + end
  82 + list = content_tag 'ul', list
  83 + end
  84 + block_title(title) + content_tag('div', list + tag('br', :style => 'clear:both'))
  85 + end
  86 + end
  87 +
  88 + def expand_address(address)
  89 + if address !~ /^[a-z]+:\/\// && address !~ /^\//
  90 + 'http://' + address
  91 + else
  92 + address
  93 + end
  94 + end
  95 +
  96 + def extra_option
  97 + { }
  98 + end
  99 +
  100 +end
plugins/people_block/lib/people_block_plugin.rb 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +class PeopleBlockPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "People Block Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that adds a people block")
  9 + end
  10 +
  11 + def self.extra_blocks
  12 + {
  13 + PeopleBlock => {:type => Environment},
  14 + MembersBlock => {:type => Community},
  15 + FriendsBlock => {:type => Person}
  16 + }
  17 + end
  18 +
  19 + def self.has_admin_url?
  20 + false
  21 + end
  22 +
  23 + def stylesheet?
  24 + true
  25 + end
  26 +
  27 +end
plugins/people_block/public/style.css 0 → 100644
@@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
  1 +/*******************************************************************
  2 + * COMMON *
  3 + *******************************************************************/
  4 +.people-block .block-footer-content a {
  5 + position: absolute;
  6 + top: 2px;
  7 + right: 0px;
  8 + font-size: 11px;
  9 + color: #000;
  10 + text-decoration: none;
  11 + padding-right: 15px;
  12 +}
  13 +
  14 +.people-block .banner-span {
  15 + color: #000;
  16 + font-size: 14pt;
  17 + font-weight: bold;
  18 + background-color: #EEE;
  19 +}
  20 +
  21 +
  22 +/*******************************************************************
  23 + * MAIN BOX - 1 *
  24 + *******************************************************************/
  25 +.box-1 .people-block .banner-div {
  26 + line-height: 112px;
  27 +}
  28 +
  29 +.box-1 .people-block .banner-span {
  30 + width: 204px;
  31 +}
  32 +
  33 +
  34 +/*******************************************************************
  35 + * LEFT/RIGHT BOXES *
  36 + *******************************************************************/
  37 +.box-2 .people-block .banner-div,
  38 +.box-3 .people-block .banner-div {
  39 + line-height: 78px;
  40 +}
  41 +
  42 +.box-2 .people-block .banner-div a,
  43 +.box-3 .people-block .banner-div a {
  44 + height: 78px;
  45 +}
  46 +
  47 +.box-2 .people-block .banner-span,
  48 +.box-3 .people-block .banner-span {
  49 + width: 116px;
  50 +}
  51 +
  52 +.box-2 .people-block ul,
  53 +.box-3 .people-block ul {
  54 + min-width: 196px;
  55 + width: 192px;
  56 + margin: 0px 0px 0px -3px;
  57 + padding: 0px;
  58 +}
  59 +
  60 +/*******************************************************************
  61 + * BLOCKs *
  62 + *******************************************************************/
  63 +#content .friends-block ul,
  64 +#content .members-block ul {
  65 + min-width: 196px;
  66 + width: 192px;
  67 + margin: 0px 0px 0px -3px;
  68 + padding: 0px;
  69 +}
  70 +#content .box-1 .people-block ul,
  71 +#content .box-1 .friends-block ul,
  72 +#content .box-1 .members-block ul {
  73 + width: auto;
  74 + display: block;
  75 +}
  76 +#content .people-block .block-footer-content a,
  77 +#content .friends-block .block-footer-content a,
  78 +#content .members-block .block-footer-content a {
  79 + position: absolute;
  80 + top: 2px;
  81 + right: 0px;
  82 + font-size: 11px;
  83 + color: #000;
  84 + text-decoration: none;
  85 + padding-right: 15px;
  86 +}
  87 +#content .members-block .block-footer-content .join-leave-button a {
  88 + position: relative;
  89 + background-color: #EEE;
  90 + border: 1px solid #CCC;
  91 + color: #555;
  92 + padding-right: inherit;
  93 +}
  94 +#content .members-block .block-footer-content .join-leave-button a:hover {
  95 + color: #FFF;
  96 + background-color: #555;
  97 + border: 1px solid #2e3436;
  98 + text-decoration: none;
  99 +}
  100 +#content .people-block .block-footer-content a.view-all,
  101 +#content .friends-block .block-footer-content a.view-all,
  102 +#content .members-block .block-footer-content a.view-all {
  103 + background: url(/designs/themes/base/imgs/arrow-right-p.png) 100% 50% no-repeat;
  104 +}
plugins/people_block/test/functional/people_block_plugin_environment_design_controller_test.rb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class EnvironmentDesignController; def rescue_action(e) raise e end; end
  5 +
  6 +class EnvironmentDesignControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = EnvironmentDesignController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([PeopleBlockPlugin.new])
  13 + end
  14 +
  15 + should 'be able to edit PeopleBlock' do
  16 + login_as(create_admin_user(Environment.default))
  17 + b = PeopleBlock.create!
  18 + e = Environment.default
  19 + e.boxes.create!
  20 + e.boxes.first.blocks << b
  21 + get :edit, :id => b.id
  22 + assert_tag :tag => 'input', :attributes => { :id => 'block_limit' }
  23 + end
  24 +
  25 +end
plugins/people_block/test/functional/people_block_plugin_profile_controller_test.rb 0 → 100644
@@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/people_block_plugin_profile_controller'
  3 +
  4 +
  5 +# Re-raise errors caught by the controller.
  6 +class PeopleBlockPluginProfileController; def rescue_action(e) raise e end; end
  7 +
  8 +class PeopleBlockPluginProfileControllerTest < ActionController::TestCase
  9 +
  10 + def setup
  11 + @controller = PeopleBlockPluginProfileController.new
  12 + @request = ActionController::TestRequest.new
  13 + @response = ActionController::TestResponse.new
  14 +
  15 + @profile = fast_create(Community)
  16 +
  17 + @environment = @profile.environment
  18 + @environment.enabled_plugins = ['PeopleBlockPlugin']
  19 + @environment.save!
  20 +
  21 + MembersBlock.delete_all
  22 + @block = MembersBlock.new
  23 + @block.box = @profile.boxes.first
  24 + @block.save!
  25 +
  26 + @admin = create_user('adminprofile').person
  27 + @member = create_user('memberprofile').person
  28 + @moderator = create_user('moderatorprofile').person
  29 + @profile.add_moderator(@moderator)
  30 + @profile.add_member(@member)
  31 + @profile.add_admin(@admin)
  32 + end
  33 +
  34 + attr_accessor :profile, :block, :admin, :member, :moderator
  35 +
  36 + should 'list members without role_key' do
  37 + get :members, :profile => profile.identifier
  38 + assert_response :success
  39 + assert_template 'members'
  40 + assert_equivalent [@admin, @member, @moderator], assigns(:members)
  41 + assert_match /adminprofile/, @response.body
  42 + assert_match /memberprofile/, @response.body
  43 + assert_match /moderatorprofile/, @response.body
  44 + end
  45 +
  46 + should 'list members with role_key=nil' do
  47 + get :members, :profile => profile.identifier, :role_key => nil
  48 + assert_response :success
  49 + assert_template 'members'
  50 + assert_equivalent [@admin, @member, @moderator], assigns(:members)
  51 + assert_match /adminprofile/, @response.body
  52 + assert_match /memberprofile/, @response.body
  53 + assert_match /moderatorprofile/, @response.body
  54 + end
  55 +
  56 + should 'list members only' do
  57 + get :members, :profile => profile.identifier, :role_key => Profile::Roles.member(profile.environment.id).key
  58 + assert_response :success
  59 + assert_template 'members'
  60 + assert_equal [@member], assigns(:members)
  61 + assert_no_match /adminprofile/, @response.body
  62 + assert_match /memberprofile/, @response.body
  63 + assert_no_match /moderatorprofile/, @response.body
  64 + end
  65 +
  66 + should 'list moderators only' do
  67 + get :members, :profile => profile.identifier, :role_key => Profile::Roles.moderator(profile.environment.id).key
  68 + assert_response :success
  69 + assert_template 'members'
  70 + assert_equal [@moderator], assigns(:members)
  71 + assert_no_match /adminprofile/, @response.body
  72 + assert_no_match /memberprofile/, @response.body
  73 + assert_match /moderatorprofile/, @response.body
  74 + end
  75 +
  76 +end
plugins/people_block/test/functional/people_block_plugin_profile_design_controller_test.rb 0 → 100644
@@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class ProfileDesignController; def rescue_action(e) raise e end; end
  5 +
  6 +class ProfileDesignControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = ProfileDesignController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 + Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([PeopleBlockPlugin.new])
  13 + end
  14 +
  15 + should 'display *block people-block* class at design blocks page' do
  16 + user = create_user('testinguser')
  17 + login_as(user.login)
  18 +
  19 + @profile = user.person
  20 + @environment = @profile.environment
  21 + @environment.save!
  22 +
  23 + FriendsBlock.delete_all
  24 + @box1 = Box.create!(:owner => @profile)
  25 + @profile.boxes = [@box1]
  26 +
  27 + @block = FriendsBlock.new
  28 + @block.box = @box1
  29 + @block.save!
  30 +
  31 + @profile.blocks<<@block
  32 + @profile.save!
  33 +
  34 + get :index, :profile => @profile.identifier
  35 + assert_tag :div, :attributes => {:class => 'block friends-block'}
  36 + end
  37 +
  38 + should 'the people block is available for person profile' do
  39 + profile = mock
  40 + profile.stubs(:has_members?).returns(false)
  41 + profile.stubs(:person?).returns(true)
  42 + profile.stubs(:community?).returns(false)
  43 + profile.stubs(:enterprise?).returns(false)
  44 + profile.stubs(:has_blog?).returns(false)
  45 + profile.stubs(:is_admin?).with(anything).returns(false)
  46 + environment = mock
  47 + profile.stubs(:environment).returns(environment)
  48 + environment.stubs(:enabled?).returns(false)
  49 + @controller.stubs(:profile).returns(profile)
  50 + @controller.stubs(:user).returns(profile)
  51 + assert_includes @controller.available_blocks, FriendsBlock
  52 + end
  53 +
  54 + should 'the people block is available for community profile' do
  55 + profile = mock
  56 + profile.stubs(:has_members?).returns(true)
  57 + profile.stubs(:person?).returns(false)
  58 + profile.stubs(:community?).returns(true)
  59 + profile.stubs(:enterprise?).returns(false)
  60 + profile.stubs(:has_blog?).returns(false)
  61 + profile.stubs(:is_admin?).with(anything).returns(false)
  62 + environment = mock
  63 + profile.stubs(:environment).returns(environment)
  64 + environment.stubs(:enabled?).returns(false)
  65 + @controller.stubs(:profile).returns(profile)
  66 + @controller.stubs(:user).returns(profile)
  67 + assert_includes @controller.available_blocks, MembersBlock
  68 + end
  69 +
  70 +end
plugins/people_block/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
plugins/people_block/test/unit/friends_block_test.rb 0 → 100644
@@ -0,0 +1,156 @@ @@ -0,0 +1,156 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class FriendsBlockTest < ActiveSupport::TestCase
  4 +
  5 + should 'inherit from Block' do
  6 + assert_kind_of Block, FriendsBlock.new
  7 + end
  8 +
  9 +
  10 + should 'declare its default title' do
  11 + assert_not_equal Block.new.default_title, FriendsBlock.new.default_title
  12 + end
  13 +
  14 +
  15 + should 'describe itself' do
  16 + assert_not_equal Block.description, FriendsBlock.description
  17 + end
  18 +
  19 +
  20 + should 'is editable' do
  21 + block = FriendsBlock.new
  22 + assert block.editable?
  23 + end
  24 +
  25 +
  26 + should 'have field limit' do
  27 + block = FriendsBlock.new
  28 + assert_respond_to block, :limit
  29 + end
  30 +
  31 +
  32 + should 'default value of limit' do
  33 + block = FriendsBlock.new
  34 + assert_equal 6, block.limit
  35 + end
  36 +
  37 +
  38 + should 'have field name' do
  39 + block = FriendsBlock.new
  40 + assert_respond_to block, :name
  41 + end
  42 +
  43 +
  44 + should 'default value of name' do
  45 + block = FriendsBlock.new
  46 + assert_equal "", block.name
  47 + end
  48 +
  49 +
  50 + should 'have field address' do
  51 + block = FriendsBlock.new
  52 + assert_respond_to block, :address
  53 + end
  54 +
  55 +
  56 + should 'default value of address' do
  57 + block = FriendsBlock.new
  58 + assert_equal "", block.address
  59 + end
  60 +
  61 +
  62 + should 'prioritize profiles with image by default' do
  63 + assert FriendsBlock.new.prioritize_people_with_image
  64 + end
  65 +
  66 +
  67 + should 'accept a limit of people to be displayed' do
  68 + block = FriendsBlock.new
  69 + block.limit = 20
  70 + assert_equal 20, block.limit
  71 + end
  72 +
  73 +
  74 + should 'list friends from person' do
  75 + owner = fast_create(Person)
  76 + friend1 = fast_create(Person)
  77 + friend2 = fast_create(Person)
  78 + owner.add_friend(friend1)
  79 + owner.add_friend(friend2)
  80 +
  81 + block = FriendsBlock.new
  82 +
  83 + block.expects(:owner).returns(owner).at_least_once
  84 + expects(:profile_image_link).with(friend1, :minor).returns(friend1.name)
  85 + expects(:profile_image_link).with(friend2, :minor).returns(friend2.name)
  86 + expects(:block_title).with(anything).returns('')
  87 +
  88 + content = instance_eval(&block.content)
  89 +
  90 + assert_match(/#{friend1.name}/, content)
  91 + assert_match(/#{friend2.name}/, content)
  92 + end
  93 +
  94 +
  95 + should 'link to "all friends"' do
  96 + person1 = create_user('mytestperson').person
  97 +
  98 + block = FriendsBlock.new
  99 + block.expects(:owner).returns(person1).at_least_once
  100 +
  101 + expects(:_).with('View all').returns('View all')
  102 + expects(:link_to).with('View all', :profile => 'mytestperson', :controller => 'profile', :action => 'friends').returns('link-to-friends')
  103 +
  104 + assert_equal 'link-to-friends', instance_eval(&block.footer)
  105 + end
  106 +
  107 +
  108 + should 'count number of owner friends' do
  109 + owner = fast_create(Person)
  110 + friend1 = fast_create(Person)
  111 + friend2 = fast_create(Person)
  112 + friend3 = fast_create(Person)
  113 + owner.add_friend(friend1)
  114 + owner.add_friend(friend2)
  115 + owner.add_friend(friend3)
  116 +
  117 + block = FriendsBlock.new
  118 + block.expects(:owner).returns(owner).at_least_once
  119 +
  120 + assert_equal 3, block.profile_count
  121 + end
  122 +
  123 +
  124 + should 'count number of public and private friends' do
  125 + owner = fast_create(Person)
  126 + private_p = fast_create(Person, {:public_profile => false})
  127 + public_p = fast_create(Person, {:public_profile => true})
  128 +
  129 + owner.add_friend(private_p)
  130 + owner.add_friend(public_p)
  131 +
  132 + block = FriendsBlock.new
  133 + block.expects(:owner).returns(owner).at_least_once
  134 +
  135 + assert_equal 2, block.profile_count
  136 + end
  137 +
  138 +
  139 + should 'not count number of invisible friends' do
  140 + owner = fast_create(Person)
  141 + private_p = fast_create(Person, {:visible => false})
  142 + public_p = fast_create(Person, {:visible => true})
  143 +
  144 + owner.add_friend(private_p)
  145 + owner.add_friend(public_p)
  146 +
  147 + block = FriendsBlock.new
  148 + block.expects(:owner).returns(owner).at_least_once
  149 +
  150 + assert_equal 1, block.profile_count
  151 + end
  152 +
  153 + protected
  154 + include NoosferoTestHelper
  155 +
  156 +end
plugins/people_block/test/unit/members_block_test.rb 0 → 100644
@@ -0,0 +1,252 @@ @@ -0,0 +1,252 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class MembersBlockTest < ActiveSupport::TestCase
  4 +
  5 + should 'inherit from Block' do
  6 + assert_kind_of Block, MembersBlock.new
  7 + end
  8 +
  9 +
  10 + should 'declare its default title' do
  11 + assert_not_equal Block.new.default_title, MembersBlock.new.default_title
  12 + end
  13 +
  14 +
  15 + should 'describe itself' do
  16 + assert_not_equal Block.description, MembersBlock.description
  17 + end
  18 +
  19 +
  20 + should 'is editable' do
  21 + block = MembersBlock.new
  22 + assert block.editable?
  23 + end
  24 +
  25 +
  26 + should 'have field limit' do
  27 + block = MembersBlock.new
  28 + assert_respond_to block, :limit
  29 + end
  30 +
  31 +
  32 + should 'default value of limit' do
  33 + block = MembersBlock.new
  34 + assert_equal 6, block.limit
  35 + end
  36 +
  37 +
  38 + should 'have field name' do
  39 + block = MembersBlock.new
  40 + assert_respond_to block, :name
  41 + end
  42 +
  43 +
  44 + should 'default value of name' do
  45 + block = MembersBlock.new
  46 + assert_equal "", block.name
  47 + end
  48 +
  49 +
  50 + should 'have field address' do
  51 + block = MembersBlock.new
  52 + assert_respond_to block, :address
  53 + end
  54 +
  55 +
  56 + should 'default value of address' do
  57 + block = MembersBlock.new
  58 + assert_equal "", block.address
  59 + end
  60 +
  61 +
  62 + should 'prioritize profiles with image by default' do
  63 + assert MembersBlock.new.prioritize_people_with_image
  64 + end
  65 +
  66 +
  67 + should 'respect limit when listing members' do
  68 + community = fast_create(Community)
  69 + p1 = fast_create(Person)
  70 + p2 = fast_create(Person)
  71 + p3 = fast_create(Person)
  72 + p4 = fast_create(Person)
  73 +
  74 + community.add_member(p1)
  75 + community.add_member(p2)
  76 + community.add_member(p3)
  77 + community.add_member(p4)
  78 +
  79 + block = MembersBlock.new(:limit => 3)
  80 + block.stubs(:owner).returns(community)
  81 +
  82 + assert_equal 3, block.profile_list.size
  83 + end
  84 +
  85 +
  86 + should 'accept a limit of members to be displayed' do
  87 + block = MembersBlock.new
  88 + block.limit = 20
  89 + assert_equal 20, block.limit
  90 + end
  91 +
  92 +
  93 + should 'list members from community' do
  94 + owner = fast_create(Community)
  95 + person1 = fast_create(Person)
  96 + person2 = fast_create(Person)
  97 + owner.add_member(person1)
  98 + owner.add_member(person2)
  99 +
  100 + block = MembersBlock.new
  101 +
  102 + block.expects(:owner).returns(owner).at_least_once
  103 + expects(:profile_image_link).with(person1, :minor).returns(person1.name)
  104 + expects(:profile_image_link).with(person2, :minor).returns(person2.name)
  105 + expects(:block_title).with(anything).returns('')
  106 +
  107 + content = instance_eval(&block.content)
  108 +
  109 + assert_match(/#{person1.name}/, content)
  110 + assert_match(/#{person2.name}/, content)
  111 + end
  112 +
  113 + should 'count number of public and private members' do
  114 + owner = fast_create(Community)
  115 + private_p = fast_create(Person, {:public_profile => false})
  116 + public_p = fast_create(Person, {:public_profile => true})
  117 +
  118 + owner.add_member(private_p)
  119 + owner.add_member(public_p)
  120 +
  121 + block = MembersBlock.new
  122 + block.expects(:owner).returns(owner).at_least_once
  123 +
  124 + assert_equal 2, block.profile_count
  125 + end
  126 +
  127 +
  128 + should 'not count number of invisible members' do
  129 + owner = fast_create(Community)
  130 + private_p = fast_create(Person, {:visible => false})
  131 + public_p = fast_create(Person, {:visible => true})
  132 +
  133 + owner.add_member(private_p)
  134 + owner.add_member(public_p)
  135 +
  136 + block = MembersBlock.new
  137 + block.expects(:owner).returns(owner).at_least_once
  138 +
  139 + assert_equal 1, block.profile_count
  140 + end
  141 +
  142 + should 'provide link to members page without a visible_role selected' do
  143 + profile = create_user('mytestuser').person
  144 + block = MembersBlock.new
  145 + block.box = profile.boxes.first
  146 + block.save!
  147 +
  148 + expects(:_).with('View all').returns('View all')
  149 + expects(:link_to).with('View all' , :profile => 'mytestuser', :controller => 'people_block_plugin_profile', :action => 'members', :role_key => block.visible_role).returns('link-to-members')
  150 +
  151 + assert_equal 'link-to-members', instance_eval(&block.footer)
  152 + end
  153 +
  154 + should 'provide link to members page with a selected role' do
  155 + profile = create_user('mytestuser').person
  156 + block = MembersBlock.new
  157 + block.box = profile.boxes.first
  158 + block.visible_role = 'profile_member'
  159 + block.save!
  160 +
  161 + expects(:_).with('View all').returns('View all')
  162 + expects(:link_to).with('View all' , :profile => 'mytestuser', :controller => 'people_block_plugin_profile', :action => 'members', :role_key => block.visible_role).returns('link-to-members')
  163 +
  164 + assert_equal 'link-to-members', instance_eval(&block.footer)
  165 + end
  166 +
  167 + should 'provide a role to be displayed (and default to nil)' do
  168 + env = fast_create(Environment)
  169 + env.boxes << Box.new
  170 + block = MembersBlock.new
  171 + assert_equal nil, block.visible_role
  172 + env.boxes.first.blocks << block
  173 + block.visible_role = 'profile_member'
  174 + block.save!
  175 + assert_equal 'profile_member', block.visible_role
  176 + end
  177 +
  178 + should 'list all members' do
  179 + env = fast_create(Environment)
  180 + env.boxes << Box.new
  181 + profile1 = fast_create(Person, :environment_id => env.id)
  182 + profile2 = fast_create(Person, :environment_id => env.id)
  183 +
  184 + block = MembersBlock.new
  185 + owner = fast_create(Community)
  186 + block.stubs(:owner).returns(owner)
  187 + env.boxes.first.blocks << block
  188 + block.save!
  189 +
  190 + owner.add_member profile1
  191 + owner.add_member profile2
  192 + profiles = block.profiles
  193 +
  194 + assert_includes profiles, profile1
  195 + assert_includes profiles, profile2
  196 + end
  197 +
  198 + should 'list only profiles with moderator role' do
  199 + env = fast_create(Environment)
  200 + env.boxes << Box.new
  201 + profile1 = fast_create(Person, :environment_id => env.id)
  202 + profile2 = fast_create(Person, :environment_id => env.id)
  203 +
  204 + block = MembersBlock.new
  205 + owner = fast_create(Community)
  206 + block.visible_role = Profile::Roles.moderator(owner.environment.id).key
  207 + block.stubs(:owner).returns(owner)
  208 + env.boxes.first.blocks << block
  209 + block.save!
  210 +
  211 + owner.add_member profile2
  212 + owner.add_moderator profile1
  213 + profiles = block.profiles
  214 +
  215 + assert_includes profiles, profile1
  216 + assert_not_includes profiles, profile2
  217 + end
  218 +
  219 + should 'list only profiles with member role' do
  220 + env = fast_create(Environment)
  221 + env.boxes << Box.new
  222 + profile1 = fast_create(Person, :environment_id => env.id)
  223 + profile2 = fast_create(Person, :environment_id => env.id)
  224 +
  225 + block = MembersBlock.new
  226 + owner = fast_create(Community)
  227 + block.visible_role = Profile::Roles.member(owner.environment.id).key
  228 + block.stubs(:owner).returns(owner)
  229 + env.boxes.first.blocks << block
  230 + block.save!
  231 +
  232 + owner.add_member profile2
  233 + owner.add_moderator profile1
  234 + profiles = block.profiles
  235 +
  236 + assert_not_includes profiles, profile1
  237 + assert_includes profiles, profile2
  238 + end
  239 +
  240 + should 'list available roles' do
  241 + block = MembersBlock.new
  242 + owner = fast_create(Community)
  243 + block.stubs(:owner).returns(owner)
  244 + assert_includes block.roles, Profile::Roles.member(owner.environment.id)
  245 + assert_includes block.roles, Profile::Roles.admin(owner.environment.id)
  246 + assert_includes block.roles, Profile::Roles.moderator(owner.environment.id)
  247 + end
  248 +
  249 + protected
  250 + include NoosferoTestHelper
  251 +
  252 +end
plugins/people_block/test/unit/people_block_plugin_test.rb 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class PeopleBlockPluginTest < ActiveSupport::TestCase
  4 +
  5 + should "return PeopleBlock in extra_blocks class method" do
  6 + assert PeopleBlockPlugin.extra_blocks.keys.include?(PeopleBlock)
  7 + end
  8 +
  9 + should "return MembersBlock in extra_blocks class method" do
  10 + assert PeopleBlockPlugin.extra_blocks.keys.include?(MembersBlock)
  11 + end
  12 +
  13 + should "return FriendsBlock in extra_blocks class method" do
  14 + assert PeopleBlockPlugin.extra_blocks.keys.include?(FriendsBlock)
  15 + end
  16 +
  17 + should "return false for class method has_admin_url?" do
  18 + assert !PeopleBlockPlugin.has_admin_url?
  19 + end
  20 +
  21 + should "return false for class method stylesheet?" do
  22 + assert PeopleBlockPlugin.new.stylesheet?
  23 + end
  24 +
  25 +end
plugins/people_block/test/unit/people_block_test.rb 0 → 100644
@@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class PeopleBlockTest < ActiveSupport::TestCase
  4 +
  5 + should 'inherit from Block' do
  6 + assert_kind_of Block, PeopleBlock.new
  7 + end
  8 +
  9 +
  10 + should 'declare its default title' do
  11 + assert_not_equal Block.new.default_title, PeopleBlock.new.default_title
  12 + end
  13 +
  14 +
  15 + should 'describe itself' do
  16 + assert_not_equal Block.description, PeopleBlock.description
  17 + end
  18 +
  19 +
  20 + should 'is editable' do
  21 + block = PeopleBlock.new
  22 + assert block.editable?
  23 + end
  24 +
  25 +
  26 + should 'have field limit' do
  27 + block = PeopleBlock.new
  28 + assert_respond_to block, :limit
  29 + end
  30 +
  31 +
  32 + should 'default value of limit' do
  33 + block = PeopleBlock.new
  34 + assert_equal 6, block.limit
  35 + end
  36 +
  37 +
  38 + should 'have field name' do
  39 + block = PeopleBlock.new
  40 + assert_respond_to block, :name
  41 + end
  42 +
  43 +
  44 + should 'default value of name' do
  45 + block = PeopleBlock.new
  46 + assert_equal "", block.name
  47 + end
  48 +
  49 +
  50 + should 'have field address' do
  51 + block = PeopleBlock.new
  52 + assert_respond_to block, :address
  53 + end
  54 +
  55 +
  56 + should 'default value of address' do
  57 + block = PeopleBlock.new
  58 + assert_equal "", block.address
  59 + end
  60 +
  61 +
  62 + should 'prioritize profiles with image by default' do
  63 + assert PeopleBlock.new.prioritize_profiles_with_image
  64 + end
  65 +
  66 +
  67 + should 'respect limit when listing people' do
  68 + env = fast_create(Environment)
  69 + p1 = fast_create(Person, :environment_id => env.id)
  70 + p2 = fast_create(Person, :environment_id => env.id)
  71 + p3 = fast_create(Person, :environment_id => env.id)
  72 + p4 = fast_create(Person, :environment_id => env.id)
  73 +
  74 + block = PeopleBlock.new(:limit => 3)
  75 + block.stubs(:owner).returns(env)
  76 +
  77 + assert_equal 3, block.profile_list.size
  78 + end
  79 +
  80 +
  81 + should 'accept a limit of people to be displayed' do
  82 + block = PeopleBlock.new
  83 + block.limit = 20
  84 + assert_equal 20, block.limit
  85 + end
  86 +
  87 +
  88 + should 'list people from environment' do
  89 + owner = fast_create(Environment)
  90 + person1 = fast_create(Person, :environment_id => owner.id)
  91 + person2 = fast_create(Person, :environment_id => owner.id)
  92 +
  93 + block = PeopleBlock.new
  94 +
  95 + block.expects(:owner).returns(owner).at_least_once
  96 + expects(:profile_image_link).with(person1, :minor).returns(person1.name)
  97 + expects(:profile_image_link).with(person2, :minor).returns(person2.name)
  98 + expects(:block_title).with(anything).returns('')
  99 +
  100 + content = instance_exec(&block.content)
  101 +
  102 + assert_match(/#{person1.name}/, content)
  103 + assert_match(/#{person2.name}/, content)
  104 + end
  105 +
  106 +
  107 + should 'link to "all people"' do
  108 + env = fast_create(Environment)
  109 +
  110 + block = PeopleBlock.new
  111 +
  112 + stubs(:_).with('View all').returns('View all')
  113 + stubs(:link_to).returns('link-to-people')
  114 + stubs(:url_for).returns(' ')
  115 +
  116 + assert_equal 'link-to-people', instance_exec(&block.footer)
  117 + end
  118 +
  119 +
  120 + should 'count number of public and private people' do
  121 + owner = fast_create(Environment)
  122 + private_p = fast_create(Person, :public_profile => false, :environment_id => owner.id)
  123 + public_p = fast_create(Person, :public_profile => true, :environment_id => owner.id)
  124 +
  125 + block = PeopleBlock.new
  126 + block.expects(:owner).returns(owner).at_least_once
  127 +
  128 + assert_equal 2, block.profile_count
  129 + end
  130 +
  131 +
  132 + should 'not count number of invisible people' do
  133 + owner = fast_create(Environment)
  134 + private_p = fast_create(Person, :visible => false, :environment_id => owner.id)
  135 + public_p = fast_create(Person, :visible => true, :environment_id => owner.id)
  136 +
  137 + block = PeopleBlock.new
  138 + block.expects(:owner).returns(owner).at_least_once
  139 +
  140 + assert_equal 1, block.profile_count
  141 + end
  142 +
  143 + protected
  144 + include NoosferoTestHelper
  145 +
  146 +end
plugins/people_block/views/blocks/friends.html.erb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= link_to s_('friends|View all'), {:profile => profile.identifier, :controller => 'profile', :action => 'friends'}, :class => 'view-all' %>
plugins/people_block/views/blocks/members.html.erb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +<%= link_to _('View all'), {:profile => profile.identifier, :controller => 'people_block_plugin_profile', :action => 'members', :role_key => role_key}, :class => 'view-all' %>
  2 +
  3 +<% if show_join_leave_button %>
  4 + <%= render :partial => 'blocks/profile_info_actions/join_leave_community' %>
  5 +<% end %>
plugins/people_block/views/blocks/people.html.erb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= link_to _('View all'), {:controller => 'search', :action => 'people'}, :class => 'view-all' %>
plugins/people_block/views/box_organizer/_people_block_base.html.erb 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +<%= labelled_form_field _('Name:'), text_field(:block, :name) %>
  2 +
  3 +<%= labelled_form_field _('Address:'), text_field(:block, :address) %>
  4 +
  5 +<% if @block.kind_of?(MembersBlock) %>
  6 + <%= labelled_form_field _('Filter by role:'), '' %>
  7 + <%= select_tag 'block[visible_role]', options_for_select(@block.roles.map{|r| [r.name, r.key]}.insert(0,''), @block.visible_role) %>
  8 +<% end %>
  9 +
  10 +<%= render :partial => 'profile_list_block' %>
plugins/people_block/views/environment_design 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +box_organizer
0 \ No newline at end of file 2 \ No newline at end of file
plugins/people_block/views/profile_design 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +box_organizer
0 \ No newline at end of file 2 \ No newline at end of file
plugins/piwik/controllers/piwik_plugin_admin_controller.rb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +class PiwikPluginAdminController < AdminController
  2 +
  3 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  4 +
  5 + def index
  6 + if request.post?
  7 + if @environment.update_attributes(params[:environment])
  8 + session[:notice] = _('Piwik plugin settings updated successfully.')
  9 + else
  10 + session[:notice] = _('Piwik plugin settings could not be saved.')
  11 + end
  12 + redirect_to :controller => 'plugins', :action => 'index'
  13 + end
  14 + end
  15 +
  16 +end
plugins/piwik/lib/ext/environment.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +require_dependency 'environment'
  2 +
  3 +class Environment
  4 + settings_items :piwik_domain
  5 + settings_items :piwik_site_id
  6 + attr_accessible :piwik_domain, :piwik_site_id
  7 +end
plugins/piwik/lib/piwik_plugin.rb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +class PiwikPlugin < Noosfero::Plugin
  2 +
  3 + include ActionView::Helpers::JavaScriptHelper
  4 + include ActionView::Helpers::FormHelper
  5 + include ActionView::Helpers::UrlHelper
  6 + include ActionView::Helpers::TagHelper
  7 +
  8 + def self.plugin_name
  9 + "Piwik"
  10 + end
  11 +
  12 + def self.plugin_description
  13 + _("Tracking and web analytics to your Noosfero's environment")
  14 + end
  15 +
  16 + def body_ending
  17 + domain = context.environment.piwik_domain
  18 + site_id = context.environment.piwik_site_id
  19 + unless domain.blank? || site_id.blank?
  20 + expanded_template('tracking-code.rhtml',{:domain => domain, :site_id => site_id})
  21 + end
  22 + end
  23 +
  24 +end
plugins/piwik/test/functional/piwik_plugin_test.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/piwik_plugin_admin_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class PiwikPluginAdminController; def rescue_action(e) raise e end; end
  6 +
  7 +class PiwikPluginAdminControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @environment = Environment.default
  11 + user_login = create_admin_user(@environment)
  12 + login_as(user_login)
  13 + @environment.enabled_plugins = ['PiwikPlugin']
  14 + @environment.save!
  15 + end
  16 +
  17 + should 'access index action' do
  18 + get :index
  19 + assert_template 'index'
  20 + assert_response :success
  21 + end
  22 +
  23 + should 'update piwik plugin settings' do
  24 + assert_nil @environment.reload.piwik_domain
  25 + assert_nil @environment.reload.piwik_site_id
  26 + post :index, :environment => { :piwik_domain => 'http://something', :piwik_site_id => 10 }
  27 + assert_not_nil @environment.reload.piwik_domain
  28 + assert_not_nil @environment.reload.piwik_site_id
  29 + end
  30 +
  31 +end
plugins/piwik/test/unit/piwik_plugin_test.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class PiwikPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @plugin = PiwikPlugin.new
  7 + @context = mock()
  8 + @plugin.context = @context
  9 + @environment = Environment.new
  10 + @context.stubs(:environment).returns(@environment)
  11 + end
  12 +
  13 + should 'add content at the body ending unless domain and site_id are blank' do
  14 + @environment.piwik_domain = 'piwik.domain.example.com'
  15 + @environment.piwik_site_id = 5
  16 + @plugin.stubs(:expanded_template).returns('content')
  17 + assert_equal 'content', @plugin.body_ending
  18 + end
  19 +
  20 + should 'not add any content at the body ending if domain is blank' do
  21 + @environment.piwik_domain = nil
  22 + @environment.piwik_site_id = 5
  23 + @plugin.stubs(:expanded_template).returns('content')
  24 + assert_equal nil, @plugin.body_ending
  25 + end
  26 +
  27 + should 'not add any content at the body ending if site_id is blank' do
  28 + @environment.piwik_domain = 'piwik.domain.example.com'
  29 + @environment.piwik_site_id = nil
  30 + @plugin.stubs(:expanded_template).returns('content')
  31 + assert_equal nil, @plugin.body_ending
  32 + end
  33 +
  34 + should 'extends Environment with attr piwik_domain' do
  35 + assert_respond_to Environment.new, :piwik_domain
  36 + end
  37 +
  38 + should 'extends Environment with attr piwik_site_id' do
  39 + assert_respond_to Environment.new, :piwik_site_id
  40 + end
  41 +
  42 +end
plugins/piwik/views/piwik_plugin_admin/index.html.erb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<h1><%= _("Piwik plugin settings") %></h1>
  2 +
  3 +<%= form_for(:environment) do |f| %>
  4 +
  5 + <%= labelled_form_field _('Piwik domain'), f.text_field(:piwik_domain) %>
  6 +
  7 + <%= labelled_form_field _('Piwik site id'), f.text_field(:piwik_site_id) %>
  8 +
  9 + <% button_bar do %>
  10 + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
  11 + <% end %>
  12 +
  13 +<% end %>
plugins/piwik/views/tracking-code.rhtml 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +<!-- Piwik -->
  2 +<script type="text/javascript">
  3 + var _paq = _paq || [];
  4 + _paq.push(['trackPageView']);
  5 + _paq.push(['enableLinkTracking']);
  6 + (function() {
  7 + var u=(("https:" == document.location.protocol) ? "https" : "http") + "://<%= escape_javascript locals[:domain] %>/piwik/";
  8 + _paq.push(['setTrackerUrl', u+'piwik.php']);
  9 + _paq.push(['setSiteId', <%= escape_javascript locals[:site_id] %>]);
  10 + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript';
  11 + g.defer=true; g.async=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  12 + })();
  13 +</script>
  14 +<noscript><p><img src="http://<%= escape_javascript locals[:domain] %>/piwik/piwik.php?idsite=<%= escape_javascript locals[:site_id] %>" style="border:0;" alt="" /></p></noscript>
  15 +<!-- End Piwik Code -->
plugins/video/lib/video_block.rb
@@ -6,8 +6,10 @@ class VideoBlock &lt; Block @@ -6,8 +6,10 @@ class VideoBlock &lt; Block
6 settings_items :width, :type => :integer, :default => 400 6 settings_items :width, :type => :integer, :default => 400
7 settings_items :height, :type => :integer, :default => 315 7 settings_items :height, :type => :integer, :default => 315
8 8
  9 + YOUTUBE_ID_FORMAT = '\w-'
  10 +
9 def is_youtube? 11 def is_youtube?
10 - url.match(/.*(youtube.com.*v=[[:alnum:]]+|youtu.be\/[[:alnum:]]+).*/) ? true : false 12 + url.match(/.*(youtube.com.*v=[#{YOUTUBE_ID_FORMAT}]+|youtu.be\/[#{YOUTUBE_ID_FORMAT}]+).*/) ? true : false
11 end 13 end
12 14
13 def is_vimeo? 15 def is_vimeo?
@@ -46,8 +48,8 @@ class VideoBlock &lt; Block @@ -46,8 +48,8 @@ class VideoBlock &lt; Block
46 48
47 def extract_youtube_id 49 def extract_youtube_id
48 return nil unless is_youtube? 50 return nil unless is_youtube?
49 - youtube_match = url.match('v=([[:alnum:]]*)')  
50 - youtube_match ||= url.match('youtu.be\/([[:alnum:]]*)') 51 + youtube_match = url.match("v=([#{YOUTUBE_ID_FORMAT}]*)")
  52 + youtube_match ||= url.match("youtu.be\/([#{YOUTUBE_ID_FORMAT}]*)")
51 youtube_match[1] unless youtube_match.nil? 53 youtube_match[1] unless youtube_match.nil?
52 end 54 end
53 55
plugins/video/test/unit/video_block_test.rb
@@ -70,6 +70,13 @@ class VideoBlockTest &lt; ActiveSupport::TestCase @@ -70,6 +70,13 @@ class VideoBlockTest &lt; ActiveSupport::TestCase
70 assert_equal id, block.send('extract_youtube_id') 70 assert_equal id, block.send('extract_youtube_id')
71 end 71 end
72 72
  73 + should "extract youtube id from youtube video url's if it has underline and hyphen" do
  74 + block = VideoBlock.new
  75 + id = 'oi43_re-d2'
  76 + block.url = "youtube.com/?v=#{id}"
  77 + assert_equal id, block.send('extract_youtube_id')
  78 + end
  79 +
73 should "extract youtube id from youtube video url's if it's a valid youtube short url" do 80 should "extract youtube id from youtube video url's if it's a valid youtube short url" do
74 block = VideoBlock.new 81 block = VideoBlock.new
75 id = 'oi43jre2d2' 82 id = 'oi43jre2d2'
public/designs/themes/base/style.css
@@ -478,12 +478,9 @@ div#notice { @@ -478,12 +478,9 @@ div#notice {
478 478
479 /************************** Profile List *****************************/ 479 /************************** Profile List *****************************/
480 480
481 -#content .people-block ul,  
482 #content .profile-list-block ul, 481 #content .profile-list-block ul,
483 #content .enterprises-block ul, 482 #content .enterprises-block ul,
484 -#content .members-block ul,  
485 #content .communities-block ul, 483 #content .communities-block ul,
486 -#content .friends-block ul,  
487 #content .fans-block ul { 484 #content .fans-block ul {
488 min-width: 196px; 485 min-width: 196px;
489 width: 192px; 486 width: 192px;
@@ -491,24 +488,18 @@ div#notice { @@ -491,24 +488,18 @@ div#notice {
491 padding: 0px; 488 padding: 0px;
492 } 489 }
493 490
494 -#content .box-1 .people-block ul,  
495 #content .box-1 .profile-list-block ul, 491 #content .box-1 .profile-list-block ul,
496 #content .box-1 .enterprises-block ul, 492 #content .box-1 .enterprises-block ul,
497 -#content .box-1 .members-block ul,  
498 #content .box-1 .communities-block ul, 493 #content .box-1 .communities-block ul,
499 -#content .box-1 .friends-block ul,  
500 #content .box-1 .fans-block ul { 494 #content .box-1 .fans-block ul {
501 width: auto; 495 width: auto;
502 display: block; 496 display: block;
503 } 497 }
504 498
505 #content .tags-block .block-footer-content a, 499 #content .tags-block .block-footer-content a,
506 -#content .people-block .block-footer-content a,  
507 #content .profile-list-block .block-footer-content a, 500 #content .profile-list-block .block-footer-content a,
508 #content .enterprises-block .block-footer-content a, 501 #content .enterprises-block .block-footer-content a,
509 -#content .members-block .block-footer-content a,  
510 -#content .communities-block .block-footer-content a,  
511 -#content .friends-block .block-footer-content a { 502 +#content .communities-block .block-footer-content a {
512 position: absolute; 503 position: absolute;
513 top: 2px; 504 top: 2px;
514 right: 0px; 505 right: 0px;
@@ -518,29 +509,12 @@ div#notice { @@ -518,29 +509,12 @@ div#notice {
518 padding-right: 15px; 509 padding-right: 15px;
519 } 510 }
520 #content .tags-block .block-footer-content a, 511 #content .tags-block .block-footer-content a,
521 -#content .people-block .block-footer-content a,  
522 #content .profile-list-block .block-footer-content a, 512 #content .profile-list-block .block-footer-content a,
523 #content .enterprises-block .block-footer-content a, 513 #content .enterprises-block .block-footer-content a,
524 -#content .communities-block .block-footer-content a,  
525 -#content .friends-block .block-footer-content a { 514 +#content .communities-block .block-footer-content a {
526 background: url(imgs/arrow-right-p.png) 100% 50% no-repeat; 515 background: url(imgs/arrow-right-p.png) 100% 50% no-repeat;
527 } 516 }
528 517
529 -#content .members-block .block-footer-content .join-leave-button a {  
530 - position: relative;  
531 - background-color: #EEE;  
532 - border: 1px solid #CCC;  
533 - color: #555;  
534 - padding-right: inherit;  
535 -}  
536 -  
537 -#content .members-block .block-footer-content .join-leave-button a:hover {  
538 - color: #FFF;  
539 - background-color: #555;  
540 - border: 1px solid #2e3436;  
541 - text-decoration: none;  
542 -}  
543 -  
544 #content .profile-list-block .block-title { 518 #content .profile-list-block .block-title {
545 text-align: left; 519 text-align: left;
546 } 520 }
public/plugins/people_block 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../plugins/people_block/public
0 \ No newline at end of file 2 \ No newline at end of file
script/noosfero-plugins
@@ -76,7 +76,8 @@ run(){ @@ -76,7 +76,8 @@ run(){
76 76
77 _enable(){ 77 _enable(){
78 plugin="$1" 78 plugin="$1"
79 - source="$available_plugins_dir/$plugin" 79 + cd $enabled_plugins_dir
  80 + source="../../plugins/$plugin"
80 target="$enabled_plugins_dir/$plugin" 81 target="$enabled_plugins_dir/$plugin"
81 run "$source/before_enable.rb" 82 run "$source/before_enable.rb"
82 if [ -h "$target" ]; then 83 if [ -h "$target" ]; then
@@ -98,11 +99,13 @@ _enable(){ @@ -98,11 +99,13 @@ _enable(){
98 fi 99 fi
99 fi 100 fi
100 if [ "$installation_ok" = true ] && [ "$dependencies_ok" = true ]; then 101 if [ "$installation_ok" = true ] && [ "$dependencies_ok" = true ]; then
101 - ln -s "$source" "$target" 102 + ln -s "$source" "$plugin"
102 plugins_public_dir="$NOOSFERO_DIR/public/plugins" 103 plugins_public_dir="$NOOSFERO_DIR/public/plugins"
103 plugins_features_dir="$NOOSFERO_DIR/features/plugins" 104 plugins_features_dir="$NOOSFERO_DIR/features/plugins"
104 - test -d "$target/public/" && ln -s "$target/public" "$plugins_public_dir/$plugin"  
105 - test -d "$NOOSFERO_DIR/features" && test -d "$target/features" && ln -s "$target/features" "$plugins_features_dir/$plugin" 105 + cd $plugins_public_dir
  106 + test -d "$source/public" && ln -s "$source/public" "$plugin"
  107 + cd $plugins_features_dir
  108 + test -d "$NOOSFERO_DIR/features" && test -d "$source/features" && ln -s "$source/features" "$plugin"
106 _say "$plugin enabled" 109 _say "$plugin enabled"
107 run "$source/after_enable.rb" 110 run "$source/after_enable.rb"
108 needs_migrate=true 111 needs_migrate=true
@@ -122,15 +125,19 @@ _disable(){ @@ -122,15 +125,19 @@ _disable(){
122 target="$enabled_plugins_dir/$plugin" 125 target="$enabled_plugins_dir/$plugin"
123 plugins_public_dir="$NOOSFERO_DIR/public/plugins" 126 plugins_public_dir="$NOOSFERO_DIR/public/plugins"
124 plugins_features_dir="$NOOSFERO_DIR/features/plugins" 127 plugins_features_dir="$NOOSFERO_DIR/features/plugins"
125 - run "$source/before_disable.rb"  
126 - if [ -h "$target" ]; then  
127 - rm "$target"  
128 - test -h "$plugins_public_dir/$plugin" && rm "$plugins_public_dir/$plugin"  
129 - test -h "$plugins_features_dir/$plugin" && rm "$plugins_features_dir/$plugin"  
130 - _say "$plugin disabled"  
131 - run "$source/after_disable.rb" 128 + if ! run "$source/before_disable.rb"; then
  129 + echo "W: failed to disabling $plugin"
  130 + echo
132 else 131 else
133 - _say "$plugin already disabled" 132 + if [ -h "$target" ]; then
  133 + rm "$target"
  134 + test -h "$plugins_public_dir/$plugin" && rm "$plugins_public_dir/$plugin"
  135 + test -h "$plugins_features_dir/$plugin" && rm "$plugins_features_dir/$plugin"
  136 + _say "$plugin disabled"
  137 + run "$source/after_disable.rb"
  138 + else
  139 + _say "$plugin already disabled"
  140 + fi
134 fi 141 fi
135 } 142 }
136 143
test/functional/cms_controller_test.rb
@@ -1228,7 +1228,7 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1228,7 +1228,7 @@ class CmsControllerTest &lt; ActionController::TestCase
1228 should 'allow user edit article if he is owner and has publish permission' do 1228 should 'allow user edit article if he is owner and has publish permission' do
1229 c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') 1229 c = Community.create!(:name => 'test_comm', :identifier => 'test_comm')
1230 u = create_user_with_permission('test_user', 'publish_content', c) 1230 u = create_user_with_permission('test_user', 'publish_content', c)
1231 - a = create(Article, :profile => c, :name => 'test_article', :last_changed_by => u) 1231 + a = create(Article, :profile => c, :name => 'test_article', :created_by => u)
1232 login_as :test_user 1232 login_as :test_user
1233 @controller.stubs(:user).returns(u) 1233 @controller.stubs(:user).returns(u)
1234 1234
@@ -1774,6 +1774,31 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1774,6 +1774,31 @@ class CmsControllerTest &lt; ActionController::TestCase
1774 assert_equal 'first version', Article.find(article.id).name 1774 assert_equal 'first version', Article.find(article.id).name
1775 end 1775 end
1776 1776
  1777 + should 'set created_by when creating article' do
  1778 + login_as(profile.identifier)
  1779 +
  1780 + post :new, :type => 'TinyMceArticle', :profile => profile.identifier, :article => { :name => 'changed by me', :body => 'content ...' }
  1781 +
  1782 + a = profile.articles.find_by_path('changed-by-me')
  1783 + assert_not_nil a
  1784 + assert_equal profile, a.created_by
  1785 + end
  1786 +
  1787 + should 'not change created_by when updating article' do
  1788 + other_person = create_user('otherperson').person
  1789 +
  1790 + a = profile.articles.build(:name => 'my article')
  1791 + a.created_by = other_person
  1792 + a.save!
  1793 +
  1794 + login_as(profile.identifier)
  1795 + post :edit, :profile => profile.identifier, :id => a.id, :article => { :body => 'new content for this article' }
  1796 +
  1797 + a.reload
  1798 +
  1799 + assert_equal other_person, a.created_by
  1800 + end
  1801 +
1777 protected 1802 protected
1778 1803
1779 # FIXME this is to avoid adding an extra dependency for a proper JSON parser. 1804 # FIXME this is to avoid adding an extra dependency for a proper JSON parser.
test/functional/content_viewer_controller_test.rb
@@ -743,7 +743,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -743,7 +743,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
743 c = Community.create!(:name => 'test_com') 743 c = Community.create!(:name => 'test_com')
744 u = create_user_with_permission('test_user', 'publish_content', c) 744 u = create_user_with_permission('test_user', 'publish_content', c)
745 login_as u.identifier 745 login_as u.identifier
746 - a = create(Article, :profile => c, :name => 'test-article', :last_changed_by => u, :published => false) 746 + a = create(Article, :profile => c, :name => 'test-article', :created_by => u, :published => false)
747 747
748 get :view_page, :profile => c.identifier, :page => a.path 748 get :view_page, :profile => c.identifier, :page => a.path
749 749
test/functional/environment_design_controller_test.rb
@@ -8,7 +8,7 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase @@ -8,7 +8,7 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase
8 8
9 # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from 9 # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
10 # the Noosfero core soon, see ActionItem3045 10 # the Noosfero core soon, see ActionItem3045
11 - ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 11 + ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
12 12
13 def setup 13 def setup
14 @controller = EnvironmentDesignController.new 14 @controller = EnvironmentDesignController.new
@@ -107,16 +107,6 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase @@ -107,16 +107,6 @@ class EnvironmentDesignControllerTest &lt; ActionController::TestCase
107 assert_tag :tag => 'input', :attributes => { :id => 'block_limit' } 107 assert_tag :tag => 'input', :attributes => { :id => 'block_limit' }
108 end 108 end
109 109
110 - should 'be able to edit PeopleBlock' do  
111 - login_as(create_admin_user(Environment.default))  
112 - b = PeopleBlock.create!  
113 - e = Environment.default  
114 - e.boxes.create!  
115 - e.boxes.first.blocks << b  
116 - get :edit, :id => b.id  
117 - assert_tag :tag => 'input', :attributes => { :id => 'block_limit' }  
118 - end  
119 -  
120 should 'be able to edit SlideshowBlock' do 110 should 'be able to edit SlideshowBlock' do
121 login_as(create_admin_user(Environment.default)) 111 login_as(create_admin_user(Environment.default))
122 b = SlideshowBlock.create! 112 b = SlideshowBlock.create!
test/functional/profile_design_controller_test.rb
@@ -6,8 +6,7 @@ class ProfileDesignController; def rescue_action(e) raise e end; end @@ -6,8 +6,7 @@ class ProfileDesignController; def rescue_action(e) raise e end; end
6 class ProfileDesignControllerTest < ActionController::TestCase 6 class ProfileDesignControllerTest < ActionController::TestCase
7 7
8 COMMOM_BLOCKS = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ] 8 COMMOM_BLOCKS = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ]
9 - PERSON_BLOCKS = COMMOM_BLOCKS + [FriendsBlock, FavoriteEnterprisesBlock, CommunitiesBlock, EnterprisesBlock ]  
10 - PERSON_BLOCKS_WITH_MEMBERS = PERSON_BLOCKS + [MembersBlock] 9 + PERSON_BLOCKS = COMMOM_BLOCKS + [ FavoriteEnterprisesBlock, CommunitiesBlock, EnterprisesBlock ]
11 PERSON_BLOCKS_WITH_BLOG = PERSON_BLOCKS + [BlogArchivesBlock] 10 PERSON_BLOCKS_WITH_BLOG = PERSON_BLOCKS + [BlogArchivesBlock]
12 11
13 ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, FeaturedProductsBlock, FansBlock, ProductCategoriesBlock] 12 ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, FeaturedProductsBlock, FansBlock, ProductCategoriesBlock]
@@ -525,23 +524,6 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase @@ -525,23 +524,6 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
525 assert_equal PERSON_BLOCKS, @controller.available_blocks 524 assert_equal PERSON_BLOCKS, @controller.available_blocks
526 end 525 end
527 526
528 - should 'the person with members blocks are all available' do  
529 - profile = mock  
530 - profile.stubs(:has_members?).returns(true)  
531 - profile.stubs(:person?).returns(true)  
532 - profile.stubs(:community?).returns(true)  
533 - profile.stubs(:enterprise?).returns(false)  
534 - profile.stubs(:has_blog?).returns(false)  
535 - profile.stubs(:is_admin?).with(anything).returns(false)  
536 - environment = mock  
537 - profile.stubs(:environment).returns(environment)  
538 - environment.stubs(:enabled?).returns(false)  
539 - @controller.stubs(:profile).returns(profile)  
540 - @controller.stubs(:user).returns(profile)  
541 - Noosfero::Plugin::Manager.any_instance.stubs(:enabled_plugins).returns([])  
542 - assert_equal [], @controller.available_blocks - PERSON_BLOCKS_WITH_MEMBERS  
543 - end  
544 -  
545 should 'the person with blog blocks are all available' do 527 should 'the person with blog blocks are all available' do
546 profile = mock 528 profile = mock
547 profile.stubs(:has_members?).returns(false) 529 profile.stubs(:has_members?).returns(false)
test/unit/article_test.rb
@@ -154,7 +154,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -154,7 +154,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
154 assert a4.errors[:slug.to_s].present? 154 assert a4.errors[:slug.to_s].present?
155 end 155 end
156 156
157 - should 'record who did the last change' do 157 + should 'last_changed_by be a person' do
158 a = profile.articles.build(:name => 'test') 158 a = profile.articles.build(:name => 'test')
159 159
160 # must be a person 160 # must be a person
@@ -167,6 +167,19 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -167,6 +167,19 @@ class ArticleTest &lt; ActiveSupport::TestCase
167 end 167 end
168 end 168 end
169 169
  170 + should 'created_by be a person' do
  171 + a = profile.articles.build(:name => 'test')
  172 +
  173 + # must be a person
  174 + assert_raise ActiveRecord::AssociationTypeMismatch do
  175 + a.created_by = Profile.new
  176 + end
  177 + assert_nothing_raised do
  178 + a.created_by = Person.new
  179 + a.save!
  180 + end
  181 + end
  182 +
170 should 'not show private documents as recent' do 183 should 'not show private documents as recent' do
171 p = create_user('usr1').person 184 p = create_user('usr1').person
172 Article.destroy_all 185 Article.destroy_all
@@ -802,7 +815,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -802,7 +815,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
802 should 'allow author to edit if is publisher' do 815 should 'allow author to edit if is publisher' do
803 c = fast_create(Community) 816 c = fast_create(Community)
804 p = create_user_with_permission('test_user', 'publish_content', c) 817 p = create_user_with_permission('test_user', 'publish_content', c)
805 - a = create(Article, :name => 'a test article', :last_changed_by => p, :profile_id => c.id) 818 + a = create(Article, :name => 'a test article', :created_by => p, :profile_id => c.id)
806 819
807 assert a.allow_post_content?(p) 820 assert a.allow_post_content?(p)
808 end 821 end
@@ -1380,17 +1393,17 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1380,17 +1393,17 @@ class ArticleTest &lt; ActiveSupport::TestCase
1380 1393
1381 should "the author_name returns the name of the article's author" do 1394 should "the author_name returns the name of the article's author" do
1382 author = fast_create(Person) 1395 author = fast_create(Person)
1383 - a = create(Article, :name => 'a test article', :last_changed_by => author, :profile_id => profile.id) 1396 + a = create(Article, :name => 'a test article', :created_by => author, :profile_id => profile.id)
1384 assert_equal author.name, a.author_name 1397 assert_equal author.name, a.author_name
1385 author.destroy 1398 author.destroy
1386 - a.reload 1399 + a = Article.find(a.id)
1387 a.author_name = 'some name' 1400 a.author_name = 'some name'
1388 assert_equal 'some name', a.author_name 1401 assert_equal 'some name', a.author_name
1389 end 1402 end
1390 1403
1391 should 'retrieve latest info from topic when has no comments' do 1404 should 'retrieve latest info from topic when has no comments' do
1392 forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) 1405 forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id)
1393 - post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now, :last_changed_by_id => profile.id) 1406 + post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now, :last_changed_by_id => profile.id, :created_by_id => profile.id)
1394 assert_equal post.updated_at, post.info_from_last_update[:date] 1407 assert_equal post.updated_at, post.info_from_last_update[:date]
1395 assert_equal profile.name, post.info_from_last_update[:author_name] 1408 assert_equal profile.name, post.info_from_last_update[:author_name]
1396 assert_equal profile.url, post.info_from_last_update[:author_url] 1409 assert_equal profile.url, post.info_from_last_update[:author_url]
@@ -1744,30 +1757,30 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1744,30 +1757,30 @@ class ArticleTest &lt; ActiveSupport::TestCase
1744 1757
1745 should 'set author_name before creating article if there is an author' do 1758 should 'set author_name before creating article if there is an author' do
1746 author = fast_create(Person) 1759 author = fast_create(Person)
1747 - article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => author) 1760 + article = create(Article, :name => 'Test', :profile => profile, :created_by => author)
1748 assert_equal author.name, article.author_name 1761 assert_equal author.name, article.author_name
1749 1762
1750 author_name = author.name 1763 author_name = author.name
1751 author.destroy 1764 author.destroy
1752 - article.reload 1765 + article = Article.find(article.id)
1753 assert_equal author_name, article.author_name 1766 assert_equal author_name, article.author_name
1754 end 1767 end
1755 1768
1756 should "author_id return the author id of the article's author" do 1769 should "author_id return the author id of the article's author" do
1757 author = fast_create(Person) 1770 author = fast_create(Person)
1758 - article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => author) 1771 + article = create(Article, :name => 'Test', :profile => profile, :created_by => author)
1759 assert_equal author.id, article.author_id 1772 assert_equal author.id, article.author_id
1760 end 1773 end
1761 1774
1762 should "author_id return nil if there is no article's author" do 1775 should "author_id return nil if there is no article's author" do
1763 - article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => nil) 1776 + article = create(Article, :name => 'Test', :profile => profile, :created_by => nil)
1764 assert_nil article.author_id 1777 assert_nil article.author_id
1765 end 1778 end
1766 1779
1767 should "return the author of a specific version" do 1780 should "return the author of a specific version" do
1768 author1 = fast_create(Person) 1781 author1 = fast_create(Person)
1769 author2 = fast_create(Person) 1782 author2 = fast_create(Person)
1770 - article = create(Article, :name => 'first version', :profile => profile, :last_changed_by => author1) 1783 + article = create(Article, :name => 'first version', :profile => profile, :created_by => author1, :last_changed_by => author1)
1771 article.name = 'second version' 1784 article.name = 'second version'
1772 article.last_changed_by = author2 1785 article.last_changed_by = author2
1773 article.save 1786 article.save
@@ -1778,7 +1791,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1778,7 +1791,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1778 should "return the author_name of a specific version" do 1791 should "return the author_name of a specific version" do
1779 author1 = fast_create(Person) 1792 author1 = fast_create(Person)
1780 author2 = fast_create(Person) 1793 author2 = fast_create(Person)
1781 - article = create(Article, :name => 'first version', :profile => profile, :last_changed_by => author1) 1794 + article = create(Article, :name => 'first version', :profile => profile, :created_by => author1)
1782 article.name = 'second version' 1795 article.name = 'second version'
1783 article.last_changed_by = author2 1796 article.last_changed_by = author2
1784 article.save 1797 article.save
@@ -1828,4 +1841,12 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1828,4 +1841,12 @@ class ArticleTest &lt; ActiveSupport::TestCase
1828 assert_equivalent [c3], Article.with_types(['Event']) 1841 assert_equivalent [c3], Article.with_types(['Event'])
1829 end 1842 end
1830 1843
  1844 + should 'not create version when receive a comment' do
  1845 + a = Article.new(:name => 'my article', :body => 'my text')
  1846 + a.profile = profile
  1847 + a.save!
  1848 + Comment.create!(:title => 'test', :body => 'asdsad', :author => profile, :source => a)
  1849 + assert_equal 1, a.versions.count
  1850 + end
  1851 +
1831 end 1852 end
test/unit/box_test.rb
@@ -39,14 +39,11 @@ class BoxTest &lt; ActiveSupport::TestCase @@ -39,14 +39,11 @@ class BoxTest &lt; ActiveSupport::TestCase
39 assert blocks.include?('fans-block') 39 assert blocks.include?('fans-block')
40 assert blocks.include?('favorite-enterprises-block') 40 assert blocks.include?('favorite-enterprises-block')
41 assert blocks.include?('feed-reader-block') 41 assert blocks.include?('feed-reader-block')
42 - assert blocks.include?('friends-block')  
43 assert blocks.include?('highlights-block') 42 assert blocks.include?('highlights-block')
44 assert blocks.include?('link-list-block') 43 assert blocks.include?('link-list-block')
45 assert blocks.include?('login-block') 44 assert blocks.include?('login-block')
46 assert blocks.include?('main-block') 45 assert blocks.include?('main-block')
47 - assert blocks.include?('members-block')  
48 assert blocks.include?('my-network-block') 46 assert blocks.include?('my-network-block')
49 - assert blocks.include?('people-block')  
50 assert blocks.include?('profile-image-block') 47 assert blocks.include?('profile-image-block')
51 assert blocks.include?('raw-html-block') 48 assert blocks.include?('raw-html-block')
52 assert blocks.include?('recent-documents-block') 49 assert blocks.include?('recent-documents-block')
@@ -74,14 +71,11 @@ class BoxTest &lt; ActiveSupport::TestCase @@ -74,14 +71,11 @@ class BoxTest &lt; ActiveSupport::TestCase
74 assert blocks.include?('favorite-enterprises-block') 71 assert blocks.include?('favorite-enterprises-block')
75 assert blocks.include?('featured-products-block') 72 assert blocks.include?('featured-products-block')
76 assert blocks.include?('feed-reader-block') 73 assert blocks.include?('feed-reader-block')
77 - assert blocks.include?('friends-block')  
78 assert blocks.include?('highlights-block') 74 assert blocks.include?('highlights-block')
79 assert blocks.include?('link-list-block') 75 assert blocks.include?('link-list-block')
80 assert blocks.include?('location-block') 76 assert blocks.include?('location-block')
81 assert blocks.include?('login-block') 77 assert blocks.include?('login-block')
82 - assert blocks.include?('members-block')  
83 assert blocks.include?('my-network-block') 78 assert blocks.include?('my-network-block')
84 - assert blocks.include?('people-block')  
85 assert blocks.include?('products-block') 79 assert blocks.include?('products-block')
86 assert blocks.include?('profile-image-block') 80 assert blocks.include?('profile-image-block')
87 assert blocks.include?('profile-info-block') 81 assert blocks.include?('profile-info-block')
test/unit/forum_helper_test.rb
@@ -38,7 +38,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -38,7 +38,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
38 38
39 should 'return post update if it has no comments' do 39 should 'return post update if it has no comments' do
40 author = create_user('forum test author').person 40 author = create_user('forum test author').person
41 - some_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => forum, :published => true, :last_changed_by => author) 41 + some_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => forum, :published => true, :created_by => author)
42 assert some_post.comments.empty? 42 assert some_post.comments.empty?
43 out = last_topic_update(some_post) 43 out = last_topic_update(some_post)
44 assert_match some_post.updated_at.to_s, out 44 assert_match some_post.updated_at.to_s, out
test/unit/friends_block_test.rb
@@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
1 -require File.dirname(__FILE__) + '/../test_helper'  
2 -  
3 -class FriendsBlockTest < ActiveSupport::TestCase  
4 -  
5 - should 'describe itself' do  
6 - assert_not_equal ProfileListBlock.description, FriendsBlock.description  
7 - end  
8 -  
9 - should 'declare its default title' do  
10 - FriendsBlock.any_instance.stubs(:profile_count).returns(0)  
11 - assert_not_equal ProfileListBlock.new.default_title, FriendsBlock.new.default_title  
12 - end  
13 -  
14 - should 'list owner friends' do  
15 - p1 = create_user('testuser1').person  
16 - p2 = create_user('testuser2').person  
17 - p3 = create_user('testuser3').person  
18 - p4 = create_user('testuser4').person  
19 -  
20 - p1.add_friend(p2)  
21 - p1.add_friend(p3)  
22 - p1.add_friend(p4)  
23 - p1.friends.reload  
24 -  
25 - block = FriendsBlock.new  
26 - block.expects(:owner).returns(p1)  
27 -  
28 - assert_equivalent [p2, p3, p4], block.profiles  
29 - end  
30 -  
31 - should 'point to list with all friends' do  
32 - block = FriendsBlock.new  
33 - user = mock  
34 - user.expects(:identifier).returns('theuser')  
35 - block.expects(:owner).returns(user)  
36 -  
37 - expects(:link_to).with('View all', :profile => 'theuser', :controller => 'profile', :action => 'friends')  
38 -  
39 - instance_eval(&block.footer)  
40 - end  
41 -  
42 - should 'count number of owner friends' do  
43 - p1 = create_user('testuser1').person  
44 - p2 = create_user('testuser2').person  
45 - p3 = create_user('testuser3').person  
46 - p4 = create_user('testuser4').person  
47 -  
48 - p1.add_friend(p2)  
49 - p1.add_friend(p3)  
50 - p1.add_friend(p4)  
51 -  
52 - block = FriendsBlock.new  
53 - block.expects(:owner).returns(p1)  
54 -  
55 - assert_equal 3, block.profile_count  
56 - end  
57 -  
58 - should 'count number of public and private people' do  
59 - owner = create_user('testuser1').person  
60 - private_p = fast_create(Person, {:public_profile => false})  
61 - public_p = fast_create(Person, {:public_profile => true})  
62 -  
63 - owner.add_friend(private_p)  
64 - owner.add_friend(public_p)  
65 -  
66 - block = FriendsBlock.new  
67 - block.expects(:owner).returns(owner)  
68 -  
69 - assert_equal 2, block.profile_count  
70 - end  
71 -  
72 - should 'not count number of invisible people' do  
73 - owner = create_user('testuser1').person  
74 - private_p = fast_create(Person, {:visible => false})  
75 - public_p = fast_create(Person, {:visible => true})  
76 -  
77 - owner.add_friend(private_p)  
78 - owner.add_friend(public_p)  
79 -  
80 - block = FriendsBlock.new  
81 - block.expects(:owner).returns(owner)  
82 -  
83 - assert_equal 1, block.profile_count  
84 - end  
85 -  
86 -end  
test/unit/members_block_test.rb
@@ -1,62 +0,0 @@ @@ -1,62 +0,0 @@
1 -require File.dirname(__FILE__) + '/../test_helper'  
2 -  
3 -class MembersBlockTest < ActiveSupport::TestCase  
4 -  
5 - should 'inherit from ProfileListBlock' do  
6 - assert_kind_of ProfileListBlock, MembersBlock.new  
7 - end  
8 -  
9 - should 'describe itself' do  
10 - assert_not_equal ProfileListBlock.description, MembersBlock.description  
11 - end  
12 -  
13 - should 'provide a default title' do  
14 - assert_not_equal ProfileListBlock.new.default_title, MembersBlock.new.default_title  
15 - end  
16 -  
17 - should 'display members file' do  
18 - community = fast_create(Community)  
19 - block = MembersBlock.create  
20 - block.expects(:owner).returns(community)  
21 -  
22 - self.expects(:render).with(:file => 'blocks/members', :locals => { :profile => community, :show_join_leave_button => false}).returns('file-with-members-list')  
23 - assert_equal 'file-with-members-list', instance_eval(&block.footer)  
24 - end  
25 -  
26 - should 'pick random members' do  
27 - block = MembersBlock.new  
28 -  
29 - owner = mock  
30 - block.expects(:owner).returns(owner)  
31 -  
32 - list = []  
33 - owner.expects(:members).returns(list)  
34 -  
35 - assert_same list, block.profiles  
36 - end  
37 -  
38 - should 'use logged-in to compose cache key' do  
39 - person = fast_create(Person)  
40 - community = fast_create(Community)  
41 - block = MembersBlock.create  
42 - block.expects(:owner).returns(community)  
43 -  
44 - assert_match(/-logged-in/,block.cache_key('en', person))  
45 - end  
46 -  
47 - should 'use logged-in and member to compose cache key for members' do  
48 - person = fast_create(Person)  
49 - community = fast_create(Community)  
50 - community.add_member person  
51 - block = MembersBlock.create  
52 - block.expects(:owner).returns(community)  
53 -  
54 - assert_match(/-logged-in-member/,block.cache_key('en', person))  
55 - end  
56 -  
57 - should 'not change block cache key if user is nil' do  
58 - block = MembersBlock.new  
59 - assert_equal block.cache_key('en'), block.cache_key('en', nil)  
60 - end  
61 -  
62 -end  
test/unit/people_block_test.rb
@@ -1,50 +0,0 @@ @@ -1,50 +0,0 @@
1 -require File.dirname(__FILE__) + '/../test_helper'  
2 -  
3 -class PeopleBlockTest < ActiveSupport::TestCase  
4 -  
5 - should 'inherit from ProfileListBlock' do  
6 - assert_kind_of ProfileListBlock, PeopleBlock.new  
7 - end  
8 -  
9 - should 'declare its default title' do  
10 - assert_not_equal ProfileListBlock.new.default_title, PeopleBlock.new.default_title  
11 - end  
12 -  
13 - should 'describe itself' do  
14 - assert_not_equal ProfileListBlock.description, PeopleBlock.description  
15 - end  
16 -  
17 - should 'give help' do  
18 - assert_not_equal ProfileListBlock.new.help, PeopleBlock.new.help  
19 - end  
20 -  
21 - should 'list people' do  
22 - owner = fast_create(Environment)  
23 - block = PeopleBlock.new  
24 - block.expects(:owner).returns(owner).at_least_once  
25 - person1 = fast_create(Person, :environment_id => owner.id)  
26 - person2 = fast_create(Person, :environment_id => owner.id)  
27 -  
28 - expects(:profile_image_link).with(person1, :minor).returns(person1.name)  
29 - expects(:profile_image_link).with(person2, :minor).returns(person2.name)  
30 - expects(:block_title).with(anything).returns('')  
31 -  
32 - content = instance_eval(&block.content)  
33 -  
34 - assert_match(/#{person1.name}/, content)  
35 - assert_match(/#{person2.name}/, content)  
36 - end  
37 -  
38 - should 'link to browse people' do  
39 - block = PeopleBlock.new  
40 - block.stubs(:owner).returns(Environment.default)  
41 -  
42 - expects(:_).with('View all').returns('View all people')  
43 - expects(:link_to).with('View all people', :controller => 'search', :action => 'people')  
44 - instance_eval(&block.footer)  
45 - end  
46 -  
47 - protected  
48 - include NoosferoTestHelper  
49 -  
50 -end  
test/unit/tiny_mce_article_test.rb
@@ -8,7 +8,7 @@ class TinyMceArticleTest &lt; ActiveSupport::TestCase @@ -8,7 +8,7 @@ class TinyMceArticleTest &lt; ActiveSupport::TestCase
8 @profile = create_user('zezinho').person 8 @profile = create_user('zezinho').person
9 end 9 end
10 attr_reader :profile 10 attr_reader :profile
11 - 11 +
12 # this test can be removed when we get real tests for TinyMceArticle 12 # this test can be removed when we get real tests for TinyMceArticle
13 should 'be an article' do 13 should 'be an article' do
14 assert_subclass TextArticle, TinyMceArticle 14 assert_subclass TextArticle, TinyMceArticle
@@ -210,7 +210,7 @@ end @@ -210,7 +210,7 @@ end
210 assert_equal true, a.notifiable? 210 assert_equal true, a.notifiable?
211 assert_equal true, a.advertise? 211 assert_equal true, a.advertise?
212 assert_equal true, a.is_trackable? 212 assert_equal true, a.is_trackable?
213 - 213 +
214 a.published=false 214 a.published=false
215 assert_equal false, a.published? 215 assert_equal false, a.published?
216 assert_equal false, a.is_trackable? 216 assert_equal false, a.is_trackable?
@@ -237,4 +237,13 @@ end @@ -237,4 +237,13 @@ end
237 assert_tag_in_string article.body, :tag => 'source', :attributes => {:src => 'http://example.ogv', :type => 'video/ogg'} 237 assert_tag_in_string article.body, :tag => 'source', :attributes => {:src => 'http://example.ogv', :type => 'video/ogg'}
238 end 238 end
239 239
  240 + should 'not sanitize colspan and rowspan attributes' do
  241 + article = TinyMceArticle.create!(:name => 'table with colspan and rowspan',
  242 + :body => "<table colspan='2' rowspan='3'><tr></tr></table>",
  243 + :profile => profile
  244 + )
  245 + assert_tag_in_string article.body, :tag => 'table',
  246 + :attributes => { :colspan => 2, :rowspan => 3 }
  247 + end
  248 +
240 end 249 end
vendor/plugins/acts_as_list/Rakefile 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +require 'rake'
  2 +require 'rake/testtask'
  3 +
  4 +desc 'Default: run acts_as_list unit tests.'
  5 +task :default => :test
  6 +
  7 +desc 'Test the acts_as_ordered_tree plugin.'
  8 +Rake::TestTask.new(:test) do |t|
  9 + t.libs << 'lib'
  10 + t.pattern = 'test/**/*_test.rb'
  11 + t.verbose = true
  12 +end
vendor/plugins/acts_as_list/lib/active_record/acts/list.rb
@@ -26,8 +26,8 @@ module ActiveRecord @@ -26,8 +26,8 @@ module ActiveRecord
26 # Configuration options are: 26 # Configuration options are:
27 # 27 #
28 # * +column+ - specifies the column name to use for keeping the position integer (default: +position+) 28 # * +column+ - specifies the column name to use for keeping the position integer (default: +position+)
29 - # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach <tt>_id</tt>  
30 - # (if it hasn't already been added) and use that as the foreign key restriction. It's also possible 29 + # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach <tt>_id</tt>
  30 + # (if it hasn't already been added) and use that as the foreign key restriction. It's also possible
31 # to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. 31 # to give it an entire string that is interpolated if you need a tighter scope than just a foreign key.
32 # Example: <tt>acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0'</tt> 32 # Example: <tt>acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0'</tt>
33 def acts_as_list(options = {}) 33 def acts_as_list(options = {})
@@ -39,11 +39,16 @@ module ActiveRecord @@ -39,11 +39,16 @@ module ActiveRecord
39 if configuration[:scope].is_a?(Symbol) 39 if configuration[:scope].is_a?(Symbol)
40 scope_condition_method = %( 40 scope_condition_method = %(
41 def scope_condition 41 def scope_condition
42 - if #{configuration[:scope].to_s}.nil?  
43 - "#{configuration[:scope].to_s} IS NULL"  
44 - else  
45 - "#{configuration[:scope].to_s} = \#{#{configuration[:scope].to_s}}" 42 + self.class.send(:sanitize_sql_hash_for_conditions, { :#{configuration[:scope].to_s} => send(:#{configuration[:scope].to_s}) })
  43 + end
  44 + )
  45 + elsif configuration[:scope].is_a?(Array)
  46 + scope_condition_method = %(
  47 + def scope_condition
  48 + attrs = %w(#{configuration[:scope].join(" ")}).inject({}) do |memo,column|
  49 + memo[column.intern] = send(column.intern); memo
46 end 50 end
  51 + self.class.send(:sanitize_sql_hash_for_conditions, attrs)
47 end 52 end
48 ) 53 )
49 else 54 else
@@ -63,7 +68,7 @@ module ActiveRecord @@ -63,7 +68,7 @@ module ActiveRecord
63 68
64 #{scope_condition_method} 69 #{scope_condition_method}
65 70
66 - before_destroy :remove_from_list 71 + before_destroy :decrement_positions_on_lower_items
67 before_create :add_to_list_bottom 72 before_create :add_to_list_bottom
68 EOV 73 EOV
69 end 74 end
@@ -250,7 +255,7 @@ module ActiveRecord @@ -250,7 +255,7 @@ module ActiveRecord
250 increment_positions_on_lower_items(position) 255 increment_positions_on_lower_items(position)
251 self.update_attribute(position_column, position) 256 self.update_attribute(position_column, position)
252 end 257 end
253 - end 258 + end
254 end 259 end
255 end 260 end
256 end 261 end
vendor/plugins/acts_as_list/test/list_test.rb
@@ -6,14 +6,15 @@ require &#39;active_record&#39; @@ -6,14 +6,15 @@ require &#39;active_record&#39;
6 6
7 require "#{File.dirname(__FILE__)}/../init" 7 require "#{File.dirname(__FILE__)}/../init"
8 8
9 -ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:") 9 +ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
10 10
11 def setup_db 11 def setup_db
12 ActiveRecord::Schema.define(:version => 1) do 12 ActiveRecord::Schema.define(:version => 1) do
13 create_table :mixins do |t| 13 create_table :mixins do |t|
14 t.column :pos, :integer 14 t.column :pos, :integer
15 t.column :parent_id, :integer 15 t.column :parent_id, :integer
16 - t.column :created_at, :datetime 16 + t.column :parent_type, :string
  17 + t.column :created_at, :datetime
17 t.column :updated_at, :datetime 18 t.column :updated_at, :datetime
18 end 19 end
19 end 20 end
@@ -46,6 +47,11 @@ class ListWithStringScopeMixin &lt; ActiveRecord::Base @@ -46,6 +47,11 @@ class ListWithStringScopeMixin &lt; ActiveRecord::Base
46 def self.table_name() "mixins" end 47 def self.table_name() "mixins" end
47 end 48 end
48 49
  50 +class ArrayScopeListMixin < Mixin
  51 + acts_as_list :column => "pos", :scope => [:parent_id, :parent_type]
  52 +
  53 + def self.table_name() "mixins" end
  54 +end
49 55
50 class ListTest < Test::Unit::TestCase 56 class ListTest < Test::Unit::TestCase
51 57
@@ -95,7 +101,7 @@ class ListTest &lt; Test::Unit::TestCase @@ -95,7 +101,7 @@ class ListTest &lt; Test::Unit::TestCase
95 101
96 def test_injection 102 def test_injection
97 item = ListMixin.new(:parent_id => 1) 103 item = ListMixin.new(:parent_id => 1)
98 - assert_equal "parent_id = 1", item.scope_condition 104 + assert_equal '"mixins"."parent_id" = 1', item.scope_condition
99 assert_equal "pos", item.position_column 105 assert_equal "pos", item.position_column
100 end 106 end
101 107
@@ -187,40 +193,60 @@ class ListTest &lt; Test::Unit::TestCase @@ -187,40 +193,60 @@ class ListTest &lt; Test::Unit::TestCase
187 new2.move_higher 193 new2.move_higher
188 assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') 194 assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos')
189 end 195 end
190 -  
191 -  
192 - def test_remove_from_list_should_then_fail_in_list? 196 +
  197 + def test_remove_from_list_should_then_fail_in_list?
193 assert_equal true, ListMixin.find(1).in_list? 198 assert_equal true, ListMixin.find(1).in_list?
194 ListMixin.find(1).remove_from_list 199 ListMixin.find(1).remove_from_list
195 assert_equal false, ListMixin.find(1).in_list? 200 assert_equal false, ListMixin.find(1).in_list?
196 - end  
197 -  
198 - def test_remove_from_list_should_set_position_to_nil 201 + end
  202 +
  203 + def test_remove_from_list_should_set_position_to_nil
199 assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) 204 assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
200 -  
201 - ListMixin.find(2).remove_from_list  
202 - 205 +
  206 + ListMixin.find(2).remove_from_list
  207 +
203 assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) 208 assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
204 - 209 +
205 assert_equal 1, ListMixin.find(1).pos 210 assert_equal 1, ListMixin.find(1).pos
206 assert_equal nil, ListMixin.find(2).pos 211 assert_equal nil, ListMixin.find(2).pos
207 assert_equal 2, ListMixin.find(3).pos 212 assert_equal 2, ListMixin.find(3).pos
208 assert_equal 3, ListMixin.find(4).pos 213 assert_equal 3, ListMixin.find(4).pos
209 - end  
210 -  
211 - def test_remove_before_destroy_does_not_shift_lower_items_twice 214 + end
  215 +
  216 + def test_remove_before_destroy_does_not_shift_lower_items_twice
212 assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) 217 assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
213 -  
214 - ListMixin.find(2).remove_from_list  
215 - ListMixin.find(2).destroy  
216 - 218 +
  219 + ListMixin.find(2).remove_from_list
  220 + ListMixin.find(2).destroy
  221 +
217 assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) 222 assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
218 - 223 +
  224 + assert_equal 1, ListMixin.find(1).pos
  225 + assert_equal 2, ListMixin.find(3).pos
  226 + assert_equal 3, ListMixin.find(4).pos
  227 + end
  228 +
  229 + def test_before_destroy_callbacks_do_not_update_position_to_nil_before_deleting_the_record
  230 + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
  231 +
  232 + # We need to trigger all the before_destroy callbacks without actually
  233 + # destroying the record so we can see the affect the callbacks have on
  234 + # the record.
  235 + list = ListMixin.find(2)
  236 + if list.respond_to?(:run_callbacks)
  237 + list.run_callbacks(:destroy)
  238 + else
  239 + list.send(:callback, :before_destroy)
  240 + end
  241 +
  242 + assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
  243 +
219 assert_equal 1, ListMixin.find(1).pos 244 assert_equal 1, ListMixin.find(1).pos
  245 + assert_equal 2, ListMixin.find(2).pos
220 assert_equal 2, ListMixin.find(3).pos 246 assert_equal 2, ListMixin.find(3).pos
221 assert_equal 3, ListMixin.find(4).pos 247 assert_equal 3, ListMixin.find(4).pos
222 - end  
223 - 248 + end
  249 +
224 end 250 end
225 251
226 class ListSubTest < Test::Unit::TestCase 252 class ListSubTest < Test::Unit::TestCase
@@ -271,7 +297,7 @@ class ListSubTest &lt; Test::Unit::TestCase @@ -271,7 +297,7 @@ class ListSubTest &lt; Test::Unit::TestCase
271 297
272 def test_injection 298 def test_injection
273 item = ListMixin.new("parent_id"=>1) 299 item = ListMixin.new("parent_id"=>1)
274 - assert_equal "parent_id = 1", item.scope_condition 300 + assert_equal '"mixins"."parent_id" = 1', item.scope_condition
275 assert_equal "pos", item.position_column 301 assert_equal "pos", item.position_column
276 end 302 end
277 303
@@ -330,3 +356,165 @@ class ListSubTest &lt; Test::Unit::TestCase @@ -330,3 +356,165 @@ class ListSubTest &lt; Test::Unit::TestCase
330 end 356 end
331 357
332 end 358 end
  359 +
  360 +class ArrayScopeListTest < Test::Unit::TestCase
  361 +
  362 + def setup
  363 + setup_db
  364 + (1..4).each { |counter| ArrayScopeListMixin.create! :pos => counter, :parent_id => 5, :parent_type => 'ParentClass' }
  365 + end
  366 +
  367 + def teardown
  368 + teardown_db
  369 + end
  370 +
  371 + def test_reordering
  372 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  373 +
  374 + ArrayScopeListMixin.find(2).move_lower
  375 + assert_equal [1, 3, 2, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  376 +
  377 + ArrayScopeListMixin.find(2).move_higher
  378 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  379 +
  380 + ArrayScopeListMixin.find(1).move_to_bottom
  381 + assert_equal [2, 3, 4, 1], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  382 +
  383 + ArrayScopeListMixin.find(1).move_to_top
  384 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  385 +
  386 + ArrayScopeListMixin.find(2).move_to_bottom
  387 + assert_equal [1, 3, 4, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  388 +
  389 + ArrayScopeListMixin.find(4).move_to_top
  390 + assert_equal [4, 1, 3, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  391 + end
  392 +
  393 + def test_move_to_bottom_with_next_to_last_item
  394 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  395 + ArrayScopeListMixin.find(3).move_to_bottom
  396 + assert_equal [1, 2, 4, 3], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  397 + end
  398 +
  399 + def test_next_prev
  400 + assert_equal ArrayScopeListMixin.find(2), ArrayScopeListMixin.find(1).lower_item
  401 + assert_nil ArrayScopeListMixin.find(1).higher_item
  402 + assert_equal ArrayScopeListMixin.find(3), ArrayScopeListMixin.find(4).higher_item
  403 + assert_nil ArrayScopeListMixin.find(4).lower_item
  404 + end
  405 +
  406 + def test_injection
  407 + item = ArrayScopeListMixin.new(:parent_id => 1, :parent_type => 'ParentClass')
  408 + assert_equal '"mixins"."parent_id" = 1 AND "mixins"."parent_type" = \'ParentClass\'', item.scope_condition
  409 + assert_equal "pos", item.position_column
  410 + end
  411 +
  412 + def test_insert
  413 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  414 + assert_equal 1, new.pos
  415 + assert new.first?
  416 + assert new.last?
  417 +
  418 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  419 + assert_equal 2, new.pos
  420 + assert !new.first?
  421 + assert new.last?
  422 +
  423 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  424 + assert_equal 3, new.pos
  425 + assert !new.first?
  426 + assert new.last?
  427 +
  428 + new = ArrayScopeListMixin.create(:parent_id => 0, :parent_type => 'ParentClass')
  429 + assert_equal 1, new.pos
  430 + assert new.first?
  431 + assert new.last?
  432 + end
  433 +
  434 + def test_insert_at
  435 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  436 + assert_equal 1, new.pos
  437 +
  438 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  439 + assert_equal 2, new.pos
  440 +
  441 + new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  442 + assert_equal 3, new.pos
  443 +
  444 + new4 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  445 + assert_equal 4, new4.pos
  446 +
  447 + new4.insert_at(3)
  448 + assert_equal 3, new4.pos
  449 +
  450 + new.reload
  451 + assert_equal 4, new.pos
  452 +
  453 + new.insert_at(2)
  454 + assert_equal 2, new.pos
  455 +
  456 + new4.reload
  457 + assert_equal 4, new4.pos
  458 +
  459 + new5 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
  460 + assert_equal 5, new5.pos
  461 +
  462 + new5.insert_at(1)
  463 + assert_equal 1, new5.pos
  464 +
  465 + new4.reload
  466 + assert_equal 5, new4.pos
  467 + end
  468 +
  469 + def test_delete_middle
  470 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  471 +
  472 + ArrayScopeListMixin.find(2).destroy
  473 +
  474 + assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  475 +
  476 + assert_equal 1, ArrayScopeListMixin.find(1).pos
  477 + assert_equal 2, ArrayScopeListMixin.find(3).pos
  478 + assert_equal 3, ArrayScopeListMixin.find(4).pos
  479 +
  480 + ArrayScopeListMixin.find(1).destroy
  481 +
  482 + assert_equal [3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  483 +
  484 + assert_equal 1, ArrayScopeListMixin.find(3).pos
  485 + assert_equal 2, ArrayScopeListMixin.find(4).pos
  486 + end
  487 +
  488 + def test_remove_from_list_should_then_fail_in_list?
  489 + assert_equal true, ArrayScopeListMixin.find(1).in_list?
  490 + ArrayScopeListMixin.find(1).remove_from_list
  491 + assert_equal false, ArrayScopeListMixin.find(1).in_list?
  492 + end
  493 +
  494 + def test_remove_from_list_should_set_position_to_nil
  495 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  496 +
  497 + ArrayScopeListMixin.find(2).remove_from_list
  498 +
  499 + assert_equal [2, 1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  500 +
  501 + assert_equal 1, ArrayScopeListMixin.find(1).pos
  502 + assert_equal nil, ArrayScopeListMixin.find(2).pos
  503 + assert_equal 2, ArrayScopeListMixin.find(3).pos
  504 + assert_equal 3, ArrayScopeListMixin.find(4).pos
  505 + end
  506 +
  507 + def test_remove_before_destroy_does_not_shift_lower_items_twice
  508 + assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  509 +
  510 + ArrayScopeListMixin.find(2).remove_from_list
  511 + ArrayScopeListMixin.find(2).destroy
  512 +
  513 + assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
  514 +
  515 + assert_equal 1, ArrayScopeListMixin.find(1).pos
  516 + assert_equal 2, ArrayScopeListMixin.find(3).pos
  517 + assert_equal 3, ArrayScopeListMixin.find(4).pos
  518 + end
  519 +
  520 +end