Commit 1c421ee1786ef44c55efda50f118003acd9c37ef

Authored by Victor Costa
2 parents ea7661fa 11166297

Merge branch 'stable' into hotfixes

Showing 80 changed files with 1272 additions and 403 deletions   Show diff stats
1 source "https://rubygems.org" 1 source "https://rubygems.org"
2 -gem 'rails'  
3 -gem 'fast_gettext'  
4 -gem 'acts-as-taggable-on'  
5 -gem 'prototype-rails'  
6 -gem 'prototype_legacy_helper', '0.0.0', :path => 'vendor/prototype_legacy_helper'  
7 -gem 'rails_autolink'  
8 -gem 'pg'  
9 -gem 'rmagick'  
10 -gem 'RedCloth'  
11 -gem 'will_paginate'  
12 -gem 'ruby-feedparser'  
13 -gem 'daemons'  
14 -gem 'thin'  
15 -gem 'hpricot'  
16 -gem 'nokogiri' 2 +gem 'rails', '~> 3.2.19'
  3 +gem 'fast_gettext', '~> 0.6.8'
  4 +gem 'acts-as-taggable-on', '~> 3.0.2'
  5 +gem 'prototype-rails', '~> 3.2.1'
  6 +gem 'prototype_legacy_helper', '0.0.0', :path => 'vendor/prototype_legacy_helper'
  7 +gem 'rails_autolink', '~> 1.1.5'
  8 +gem 'pg', '~> 0.13.2'
  9 +gem 'rmagick', '~> 2.13.1'
  10 +gem 'RedCloth', '~> 4.2.9'
  11 +gem 'will_paginate', '~> 3.0.3'
  12 +gem 'ruby-feedparser', '~> 0.7'
  13 +gem 'daemons', '~> 1.1.5'
  14 +gem 'thin', '~> 1.3.1'
  15 +gem 'hpricot', '~> 0.8.6'
  16 +gem 'nokogiri', '~> 1.5.5'
17 gem 'rake', :require => false 17 gem 'rake', :require => false
18 -gem 'grape', '0.2.1'  
19 -gem 'rest-client'  
20 -gem 'exception_notification'  
21 -gem 'gettext', :require => false, :group => :development 18 +gem 'grape', '~> 0.2.1'
  19 +gem 'rest-client', '~> 1.6.7'
  20 +gem 'exception_notification', '~> 4.0.1'
  21 +gem 'gettext', '~> 2.2.1', :require => false, :group => :development
22 22
23 # FIXME list here all actual dependencies (i.e. the ones in debian/control), 23 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
24 # with their GEM names (not the Debian package names) 24 # with their GEM names (not the Debian package names)
25 25
26 group :production do 26 group :production do
27 - gem 'dalli' 27 + gem 'dalli', '~> 2.7.0'
28 end 28 end
29 29
30 group :test do 30 group :test do
31 - gem 'rspec'  
32 - gem 'rspec-rails'  
33 - gem 'mocha', :require => false 31 + gem 'rspec', '~> 2.10.0'
  32 + gem 'rspec-rails', '~> 2.10.1'
  33 + gem 'mocha', '~> 1.1.0', :require => false
34 end 34 end
35 35
36 group :cucumber do 36 group :cucumber do
37 - gem 'cucumber-rails', :require => false  
38 - gem 'capybara'  
39 - gem 'cucumber'  
40 - gem 'database_cleaner'  
41 - gem 'selenium-webdriver' 37 + gem 'cucumber-rails', '~> 1.0.6', :require => false
  38 + gem 'capybara', '~> 2.1.0'
  39 + gem 'cucumber', '~> 1.0.6'
  40 + gem 'database_cleaner', '~> 1.2.0'
  41 + gem 'selenium-webdriver', '~> 2.39.0'
42 end 42 end
43 43
44 # include plugin gemfiles 44 # include plugin gemfiles
Gemfile.lock
@@ -1,206 +0,0 @@ @@ -1,206 +0,0 @@
1 -PATH  
2 - remote: vendor/prototype_legacy_helper  
3 - specs:  
4 - prototype_legacy_helper (0.0.0)  
5 -  
6 -GEM  
7 - remote: https://rubygems.org/  
8 - specs:  
9 - RedCloth (4.2.9)  
10 - actionmailer (3.2.6)  
11 - actionpack (= 3.2.6)  
12 - mail (~> 2.4.4)  
13 - actionpack (3.2.6)  
14 - activemodel (= 3.2.6)  
15 - activesupport (= 3.2.6)  
16 - builder (~> 3.0.0)  
17 - erubis (~> 2.7.0)  
18 - journey (~> 1.0.1)  
19 - rack (~> 1.4.0)  
20 - rack-cache (~> 1.2)  
21 - rack-test (~> 0.6.1)  
22 - sprockets (~> 2.1.3)  
23 - activemodel (3.2.6)  
24 - activesupport (= 3.2.6)  
25 - builder (~> 3.0.0)  
26 - activerecord (3.2.6)  
27 - activemodel (= 3.2.6)  
28 - activesupport (= 3.2.6)  
29 - arel (~> 3.0.2)  
30 - tzinfo (~> 0.3.29)  
31 - activeresource (3.2.6)  
32 - activemodel (= 3.2.6)  
33 - activesupport (= 3.2.6)  
34 - activesupport (3.2.6)  
35 - i18n (~> 0.6)  
36 - multi_json (~> 1.0)  
37 - acts-as-taggable-on (3.0.2)  
38 - rails (>= 3, < 5)  
39 - arel (3.0.2)  
40 - builder (3.0.0)  
41 - capybara (2.1.0)  
42 - mime-types (>= 1.16)  
43 - nokogiri (>= 1.3.3)  
44 - rack (>= 1.0.0)  
45 - rack-test (>= 0.5.4)  
46 - xpath (~> 2.0)  
47 - childprocess (0.3.3)  
48 - ffi (~> 1.0.6)  
49 - cucumber (1.0.6)  
50 - builder (>= 2.1.2)  
51 - diff-lcs (>= 1.1.2)  
52 - gherkin (~> 2.4.18)  
53 - json (>= 1.4.6)  
54 - term-ansicolor (>= 1.0.6)  
55 - cucumber-rails (1.0.6)  
56 - capybara (>= 1.1.1)  
57 - cucumber (>= 1.0.6)  
58 - nokogiri (>= 1.5.0)  
59 - daemons (1.1.5)  
60 - dalli (2.7.0)  
61 - database_cleaner (1.2.0)  
62 - diff-lcs (1.1.3)  
63 - erubis (2.7.0)  
64 - eventmachine (0.12.10)  
65 - exception_notification (4.0.1)  
66 - actionmailer (>= 3.0.4)  
67 - activesupport (>= 3.0.4)  
68 - fast_gettext (0.6.8)  
69 - ffi (1.0.11)  
70 - gettext (2.2.1)  
71 - locale  
72 - gherkin (2.4.21)  
73 - json (>= 1.4.6)  
74 - grape (0.2.1)  
75 - hashie (~> 1.2)  
76 - multi_json  
77 - multi_xml  
78 - rack  
79 - rack-mount  
80 - hashie (1.2.0)  
81 - hike (1.2.1)  
82 - hpricot (0.8.6)  
83 - i18n (0.6.0)  
84 - journey (1.0.3)  
85 - json (1.7.3)  
86 - locale (2.0.5)  
87 - mail (2.4.4)  
88 - i18n (>= 0.4.0)  
89 - mime-types (~> 1.16)  
90 - treetop (~> 1.4.8)  
91 - metaclass (0.0.1)  
92 - mime-types (1.19)  
93 - mocha (0.11.3)  
94 - metaclass (~> 0.0.1)  
95 - multi_json (1.3.6)  
96 - multi_xml (0.5.5)  
97 - nokogiri (1.5.5)  
98 - pg (0.13.2)  
99 - polyglot (0.3.3)  
100 - prototype-rails (3.2.1)  
101 - rails (~> 3.2)  
102 - rack (1.4.1)  
103 - rack-cache (1.2)  
104 - rack (>= 0.4)  
105 - rack-mount (0.8.3)  
106 - rack (>= 1.0.0)  
107 - rack-ssl (1.3.2)  
108 - rack  
109 - rack-test (0.6.1)  
110 - rack (>= 1.0)  
111 - rails (3.2.6)  
112 - actionmailer (= 3.2.6)  
113 - actionpack (= 3.2.6)  
114 - activerecord (= 3.2.6)  
115 - activeresource (= 3.2.6)  
116 - activesupport (= 3.2.6)  
117 - bundler (~> 1.0)  
118 - railties (= 3.2.6)  
119 - rails_autolink (1.1.5)  
120 - rails (> 3.1)  
121 - railties (3.2.6)  
122 - actionpack (= 3.2.6)  
123 - activesupport (= 3.2.6)  
124 - rack-ssl (~> 1.3.2)  
125 - rake (>= 0.8.7)  
126 - rdoc (~> 3.4)  
127 - thor (>= 0.14.6, < 2.0)  
128 - rake (0.9.2.2)  
129 - rdoc (3.9.4)  
130 - rest-client (1.6.7)  
131 - mime-types (>= 1.16)  
132 - rmagick (2.13.1)  
133 - rspec (2.10.0)  
134 - rspec-core (~> 2.10.0)  
135 - rspec-expectations (~> 2.10.0)  
136 - rspec-mocks (~> 2.10.0)  
137 - rspec-core (2.10.1)  
138 - rspec-expectations (2.10.0)  
139 - diff-lcs (~> 1.1.3)  
140 - rspec-mocks (2.10.1)  
141 - rspec-rails (2.10.1)  
142 - actionpack (>= 3.0)  
143 - activesupport (>= 3.0)  
144 - railties (>= 3.0)  
145 - rspec (~> 2.10.0)  
146 - ruby-feedparser (0.7)  
147 - rubyzip (1.1.2)  
148 - selenium-webdriver (2.39.0)  
149 - childprocess (>= 0.2.5)  
150 - multi_json (~> 1.0)  
151 - rubyzip (~> 1.0)  
152 - websocket (~> 1.0.4)  
153 - sprockets (2.1.3)  
154 - hike (~> 1.2)  
155 - multi_json (~> 1.0)  
156 - rack (~> 1.0)  
157 - tilt (~> 1.1, != 1.3.0)  
158 - term-ansicolor (1.0.7)  
159 - thin (1.3.1)  
160 - daemons (>= 1.0.9)  
161 - eventmachine (>= 0.12.6)  
162 - rack (>= 1.0.0)  
163 - thor (0.15.3)  
164 - tilt (1.3.3)  
165 - treetop (1.4.10)  
166 - polyglot  
167 - polyglot (>= 0.3.1)  
168 - tzinfo (0.3.33)  
169 - websocket (1.0.7)  
170 - will_paginate (3.0.3)  
171 - xpath (2.0.0)  
172 - nokogiri (~> 1.3)  
173 -  
174 -PLATFORMS  
175 - ruby  
176 -  
177 -DEPENDENCIES  
178 - RedCloth  
179 - acts-as-taggable-on  
180 - capybara  
181 - cucumber  
182 - cucumber-rails  
183 - daemons  
184 - dalli  
185 - database_cleaner  
186 - exception_notification  
187 - fast_gettext  
188 - gettext  
189 - grape (= 0.2.1)  
190 - hpricot  
191 - mocha  
192 - nokogiri  
193 - pg  
194 - prototype-rails  
195 - prototype_legacy_helper (= 0.0.0)!  
196 - rails  
197 - rails_autolink  
198 - rake  
199 - rest-client  
200 - rmagick  
201 - rspec  
202 - rspec-rails  
203 - ruby-feedparser  
204 - selenium-webdriver  
205 - thin  
206 - will_paginate  
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 3
4 VAGRANTFILE_API_VERSION = "2" 4 VAGRANTFILE_API_VERSION = "2"
5 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 5 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
6 - config.vm.box = "debian-wheezy" 6 + config.vm.box = ENV.fetch('VAGRANT_BOX', "debian-wheezy")
7 config.vm.network :forwarded_port, host: 3000, guest: 3000 7 config.vm.network :forwarded_port, host: 3000, guest: 3000
8 config.vm.provision :shell do |shell| 8 config.vm.provision :shell do |shell|
9 shell.inline = 'su vagrant -c /vagrant/script/vagrant' 9 shell.inline = 'su vagrant -c /vagrant/script/vagrant'
app/models/environment.rb
@@ -829,7 +829,7 @@ class Environment &lt; ActiveRecord::Base @@ -829,7 +829,7 @@ class Environment &lt; ActiveRecord::Base
829 end 829 end
830 830
831 def notification_emails 831 def notification_emails
832 - [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email) 832 + [contact_email].select(&:present?) + admins.map(&:email)
833 end 833 end
834 834
835 after_create :create_templates 835 after_create :create_templates
app/models/organization.rb
@@ -135,7 +135,11 @@ class Organization &lt; Profile @@ -135,7 +135,11 @@ class Organization &lt; Profile
135 end 135 end
136 136
137 def notification_emails 137 def notification_emails
138 - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) 138 + emails = [contact_email].select(&:present?) + admins.map(&:email)
  139 + if emails.empty?
  140 + emails << environment.contact_email
  141 + end
  142 + emails
139 end 143 end
140 144
141 def already_request_membership?(person) 145 def already_request_membership?(person)
debian/control
@@ -9,7 +9,7 @@ Build-Depends: @@ -9,7 +9,7 @@ Build-Depends:
9 ruby-gettext, 9 ruby-gettext,
10 ruby-sqlite3, 10 ruby-sqlite3,
11 rake, 11 rake,
12 - rails3 (>= 3.2.6-1~), 12 + rails3 (>= 3.2.19-1~),
13 ruby-rspec, 13 ruby-rspec,
14 ruby-rspec-rails, 14 ruby-rspec-rails,
15 ruby-will-paginate, 15 ruby-will-paginate,
debian/noosfero.install
@@ -8,7 +8,6 @@ Rakefile usr/share/noosfero @@ -8,7 +8,6 @@ Rakefile usr/share/noosfero
8 vendor usr/share/noosfero 8 vendor usr/share/noosfero
9 9
10 Gemfile usr/share/noosfero 10 Gemfile usr/share/noosfero
11 -Gemfile.lock usr/share/noosfero  
12 debian/bundle/config usr/share/noosfero/.bundle 11 debian/bundle/config usr/share/noosfero/.bundle
13 12
14 config/application.rb usr/share/noosfero/config 13 config/application.rb usr/share/noosfero/config
debian/noosfero.links
@@ -15,3 +15,4 @@ var/lib/noosfero-data/public/thumbnails usr/share/noosfero/public/th @@ -15,3 +15,4 @@ var/lib/noosfero-data/public/thumbnails usr/share/noosfero/public/th
15 usr/share/noosfero/public/designs/themes/noosfero usr/share/noosfero/public/designs/themes/default 15 usr/share/noosfero/public/designs/themes/noosfero usr/share/noosfero/public/designs/themes/default
16 usr/share/noosfero/public/designs/icons/tango usr/share/noosfero/public/designs/icons/default 16 usr/share/noosfero/public/designs/icons/tango usr/share/noosfero/public/designs/icons/default
17 usr/share/noosfero/script/noosfero-plugins usr/sbin/noosfero-plugins 17 usr/share/noosfero/script/noosfero-plugins usr/sbin/noosfero-plugins
  18 +usr/share/noosfero/Gemfile.lock /dev/null
gitignore.example
@@ -43,3 +43,4 @@ debian/noosfero-apache/ @@ -43,3 +43,4 @@ debian/noosfero-apache/
43 features/plugins/* 43 features/plugins/*
44 plugins/solr/config/solr.yml 44 plugins/solr/config/solr.yml
45 /solr 45 /solr
  46 +/Gemfile.lock
lib/feed_writer.rb
@@ -19,7 +19,7 @@ class FeedWriter @@ -19,7 +19,7 @@ class FeedWriter
19 for article in articles 19 for article in articles
20 xml.item do 20 xml.item do
21 xml.title(article.name) 21 xml.title(article.name)
22 - xml.description(article.to_html) 22 + xml.description(article.to_html(:feed => true))
23 if article.created_at 23 if article.created_at
24 # rfc822 24 # rfc822
25 xml.pubDate(article.created_at.rfc2822) 25 xml.pubDate(article.created_at.rfc2822)
plugins/dspace/controllers/dspace_plugin_controller.rb 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +class DspacePluginController < PublicController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def view_item
  5 +
  6 + collection_id = params[:collection_id]
  7 + item_id = params[:id]
  8 +
  9 + begin
  10 + @collection = DspacePlugin::Collection.find(collection_id)
  11 + rescue ActiveRecord::RecordNotFound
  12 + render_not_found
  13 + return
  14 + end
  15 +
  16 + begin
  17 + dspace_server = @collection.parent.parent.dspace_server_url
  18 + @item = Dspace::Item.get_item_by_id dspace_server, item_id
  19 + rescue ActiveResource::UnauthorizedAccess
  20 + render_not_found
  21 + return
  22 + end
  23 +
  24 + begin
  25 + @collection = DspacePlugin::Collection.find(collection_id)
  26 + rescue ActiveRecord::RecordNotFound
  27 + render_not_found
  28 + return
  29 + end
  30 +
  31 + end
  32 +
  33 +end
plugins/dspace/controllers/dspace_plugin_myprofile_controller.rb 0 → 100644
@@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
  1 +class DspacePluginMyprofileController < CmsController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def new
  5 +
  6 + @success_back_to = params[:success_back_to]
  7 +
  8 + @parent = profile.articles.find(params[:parent_id]) if params && params[:parent_id]
  9 + record_coming
  10 + @type = params[:type]
  11 + if @type.blank?
  12 + @article_types = []
  13 + available_article_types.each do |type|
  14 + @article_types.push({
  15 + :class => type,
  16 + :short_description => type.short_description,
  17 + :description => type.description
  18 + })
  19 + end
  20 + @parent_id = params[:parent_id]
  21 + render :action => 'select_article_type', :layout => false, :back_to => @back_to
  22 + return
  23 + else
  24 + refuse_blocks
  25 + end
  26 +
  27 + raise "Invalid article type #{@type}" unless valid_article_type?(@type)
  28 +
  29 + klass = @type.constantize
  30 + article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
  31 + article_data.merge!(params[:article]) if params[:article]
  32 +
  33 + if @type == 'DspacePlugin::Collection'
  34 + dspace_objects = article_data['dspace_collections']
  35 + elsif @type == 'DspacePlugin::Communityy'
  36 + dspace_objects = article_data['dspace_communities']
  37 + end
  38 +
  39 + dspace_objects.each do |object|
  40 +
  41 + entity = klass.new
  42 +
  43 + parent = check_parent(params[:parent_id])
  44 +
  45 + if parent
  46 + entity.parent = parent
  47 + parent_id = parent.id
  48 + end
  49 +
  50 + if @type == 'DspacePlugin::Communityy'
  51 + entity.dspace_community_id = object['id']
  52 + elsif @type == 'DspacePlugin::Collection'
  53 + entity.dspace_community_id = article_data['dspace_community_id']
  54 + entity.dspace_collection_id = object['id']
  55 + entity.accept_comments = false
  56 + end
  57 +
  58 + entity.name = object['name']
  59 + entity.profile = profile
  60 + entity.author = user
  61 + entity.last_changed_by = user
  62 + entity.created_by = user
  63 +
  64 + entity.save!
  65 +
  66 + end
  67 +
  68 + redirect_to @parent.view_url
  69 +
  70 + end
  71 +
  72 +end
plugins/dspace/lib/dspace/collection.rb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +class Dspace::Collection < Dspace::Resource
  2 +
  3 + def self.get_all_items_from(dspace_server, collection_id)
  4 + self.site = dspace_server
  5 + result = self.find collection_id, :params => { :expand => 'items' }
  6 +
  7 + item_list = []
  8 +
  9 + if result.items.count > 0
  10 + result.items.each { |element|
  11 + item = Dspace::Item.get_item_by_id dspace_server, element.id
  12 + item_list << item
  13 + }
  14 + end
  15 +
  16 + item_list
  17 + end
  18 +
  19 + def self.get_all_collections_from(dspace_server)
  20 + self.site = dspace_server
  21 + self.find(:all)
  22 + end
  23 +
  24 +end
plugins/dspace/lib/dspace/community.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +class Dspace::Community < Dspace::Resource
  2 +
  3 + def self.get_all_communities_from(dspace_server)
  4 + self.site = dspace_server
  5 + self.find(:all)
  6 + end
  7 +
  8 + def self.get_all_collections_from(dspace_server, community_id)
  9 + self.site = dspace_server
  10 + result = self.find community_id, :params => { :expand => 'collections' }
  11 + result.collections
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace/item.rb 0 → 100644
@@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
  1 +class Dspace::Item < Dspace::Resource
  2 +
  3 + def self.get_all_item_metadata_from(dspace_server, item_id)
  4 + self.site = dspace_server
  5 + result = self.find item_id, :params => { :expand => 'metadata' }
  6 + result.metadata
  7 + end
  8 +
  9 + def self.get_item_by_id(dspace_server, item_id)
  10 + self.site = dspace_server
  11 + result = self.find item_id, :params => { :expand => 'metadata' }
  12 +
  13 + item_metadata = Dspace::Item.get_all_item_metadata_from self.site, result.id
  14 +
  15 + # author
  16 + metadata = item_metadata[0].attributes
  17 + if metadata != {}
  18 + metadata = Hash[[metadata.map{|k,v| v}]]
  19 + author = metadata.has_key?('dc.contributor.author') ? metadata['dc.contributor.author'] : nil
  20 + end
  21 +
  22 + # issue date
  23 + metadata = item_metadata[3].attributes
  24 + if metadata != {}
  25 + metadata = Hash[[metadata.map{|k,v| v}]]
  26 + issue_date = metadata.has_key?('dc.date.issued') ? metadata['dc.date.issued'] : nil
  27 + end
  28 +
  29 + # uri
  30 + metadata = item_metadata[4].attributes
  31 + if metadata != {}
  32 + metadata = Hash[[metadata.map{|k,v| v}]]
  33 + uri = metadata.has_key?('dc.identifier.uri') ? metadata['dc.identifier.uri'] : nil
  34 + end
  35 +
  36 + # description
  37 + metadata = item_metadata[5].attributes
  38 + if metadata != {}
  39 + metadata = Hash[[metadata.map{|k,v| v}]]
  40 + abstract = metadata.has_key?('dc.description') ? metadata['dc.description'] : nil
  41 + end
  42 +
  43 + # abstract
  44 + metadata = item_metadata[6].attributes
  45 + if metadata != {}
  46 + metadata = Hash[[metadata.map{|k,v| v}]]
  47 + description = metadata.has_key?('dc.description.abstract') ? metadata['dc.description.abstract'] : nil
  48 + end
  49 +
  50 + item = DspacePlugin::Item.new
  51 +
  52 + item.id = result.id
  53 + item.name = result.name
  54 + item.author = author
  55 + item.issue_date = issue_date
  56 + item.abstract = abstract
  57 + item.description = description
  58 + item.uri = uri
  59 +
  60 + ### BITSTREAMS
  61 +
  62 + item_bitstreams = self.find item_id, :params => { :expand => 'bitstreams' }
  63 +
  64 + bitstreams = item_bitstreams.bitstreams
  65 +
  66 + bitstreams.each do |bs|
  67 + bitstream = DspacePlugin::Bitstream.new
  68 + bitstream.id = bs.attributes[:id]
  69 + bitstream.name = bs.attributes[:name]
  70 + bitstream.description = bs.attributes[:description]
  71 + bitstream.mimetype = bs.attributes[:mimeType]
  72 + bitstream.size_bytes = bs.attributes[:sizeBytes]
  73 + bitstream.retrieve_link = bs.attributes[:retrieveLink]
  74 + bitstream.format = bs.attributes[:format]
  75 + bitstream.link = bs.attributes[:link]
  76 +
  77 + item.files << bitstream
  78 +
  79 + end
  80 +
  81 + if item.files.count > 0
  82 + item.mimetype = item.files.first.mimetype
  83 + end
  84 +
  85 + item
  86 +
  87 + end
  88 +
  89 +end
plugins/dspace/lib/dspace/resource.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class Dspace::Resource < ActiveResource::Base
  2 +
  3 + class << self
  4 + def element_path(id, prefix_options = {}, query_options = nil)
  5 + prefix_options, query_options = split_options(prefix_options) if query_options.nil?
  6 + "#{prefix(prefix_options)}#{collection_name}/#{id}#{query_string(query_options)}"
  7 + end
  8 +
  9 + def collection_path(prefix_options = {}, query_options = nil)
  10 + prefix_options, query_options = split_options(prefix_options) if query_options.nil?
  11 + "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
  12 + end
  13 + end
  14 +
  15 +end
plugins/dspace/lib/dspace_plugin.rb 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +class DspacePlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "DSpace Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that add a DSpace library feature to noosfero.")
  9 + end
  10 +
  11 + def content_types
  12 + if context.respond_to?(:params) && context.params
  13 + types = []
  14 + parent_id = context.params[:parent_id]
  15 + types << DspacePlugin::Library if context.profile.community? && !parent_id
  16 + parent = parent_id ? context.profile.articles.find(parent_id) : nil
  17 + if parent.kind_of?(DspacePlugin::Library)
  18 + types << DspacePlugin::Communityy
  19 + elsif parent.kind_of?(DspacePlugin::Communityy)
  20 + types << DspacePlugin::Collection
  21 + end
  22 + types
  23 + else
  24 + [DspacePlugin::Library, DspacePlugin::Collection, DspacePlugin::Communityy]
  25 + end
  26 + end
  27 +
  28 + def stylesheet?
  29 + true
  30 + end
  31 +
  32 + def self.has_admin_url?
  33 + false
  34 + end
  35 +
  36 +end
plugins/dspace/lib/dspace_plugin/bitstream.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +class DspacePlugin::Bitstream
  2 +
  3 + attr_accessor :id, :name, :description, :mimetype, :size_bytes, :retrieve_link, :format, :link
  4 +
  5 +end
plugins/dspace/lib/dspace_plugin/collection.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +class DspacePlugin::Collection < Article
  2 +
  3 + settings_items :dspace_collection_id, :type => :string
  4 + settings_items :dspace_community_id, :type => :integer
  5 +
  6 + attr_accessible :dspace_collection_id, :dspace_community_id
  7 +
  8 + def self.icon_name(article = nil)
  9 + 'dspace-collection'
  10 + end
  11 +
  12 + def self.short_description
  13 + _("DSpace collection")
  14 + end
  15 +
  16 + def self.description
  17 + _("Defines a DSpace collection")
  18 + end
  19 +
  20 + def to_html(options = {})
  21 + dspace_content = self
  22 + proc do
  23 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  24 + end
  25 + end
  26 +
  27 + def items(dspace_server, collection_id)
  28 + Dspace::Collection.get_all_items_from dspace_server, collection_id
  29 + end
  30 +
  31 +end
plugins/dspace/lib/dspace_plugin/collection_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::CollectionHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace_plugin/communityy.rb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +class DspacePlugin::Communityy < Folder
  2 +
  3 + settings_items :dspace_community_id, :type => :string
  4 +
  5 + attr_accessible :dspace_community_id
  6 +
  7 + def self.icon_name(article = nil)
  8 + 'dspace-community'
  9 + end
  10 +
  11 + def self.short_description
  12 + _("DSpace community")
  13 + end
  14 +
  15 + def self.description
  16 + _("Defines a DSpace community")
  17 + end
  18 +
  19 + def to_html(options = {})
  20 + dspace_content = self
  21 + proc do
  22 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  23 + end
  24 + end
  25 +
  26 + def collections(dspace_server, community_id)
  27 + DspacePlugin::Collection.find(:all)
  28 + end
  29 +
  30 +end
plugins/dspace/lib/dspace_plugin/communityy_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::CommunityyHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace_plugin/item.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class DspacePlugin::Item
  2 +
  3 + include DspacePlugin::ItemHelper
  4 +
  5 + attr_accessor :id, :name, :author, :issue_date, :abstract, :description, :uri, :files, :mimetype
  6 +
  7 + def initialize
  8 + self.files = []
  9 + end
  10 +
  11 +end
plugins/dspace/lib/dspace_plugin/item_helper.rb 0 → 100644
@@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
  1 +module DspacePlugin::ItemHelper
  2 +
  3 + TEXT_MIMETYPES = [ 'text/plain; charset=utf-8',
  4 + 'text/html',
  5 + 'text/xml',
  6 + 'text/plain',
  7 + 'text/html',
  8 + 'text/css',
  9 + 'text/richtext' ]
  10 +
  11 + AUDIO_MIMETYPES = [ 'audio/x-pn-realaudio',
  12 + 'audio/x-mpeg',
  13 + 'audio/x-aiff',
  14 + 'audio/basic',
  15 + 'audio/x-wav' ]
  16 +
  17 + DOCUMENT_MIMETYPES = [ 'application/msword',
  18 + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  19 + 'application/vnd.oasis.opendocument.text',
  20 + 'application/vnd.oasis.opendocument.text-template',
  21 + 'application/vnd.oasis.opendocument.text-web',
  22 + 'application/vnd.oasis.opendocument.text-master',
  23 + 'application/vnd.sun.xml.writer',
  24 + 'application/vnd.sun.xml.writer.template',
  25 + 'application/vnd.sun.xml.writer.global',
  26 + 'application/vnd.stardivision.writer',
  27 + 'application/vnd.stardivision.writer-global' ]
  28 +
  29 + PICTURE_MIMETYPES = [ 'image/x-photo-cd',
  30 + 'image/x-ms-bmp',
  31 + 'image/jpeg',
  32 + 'image/gif',
  33 + 'image/png',
  34 + 'image/tiff',
  35 + 'application/x-photoshop',
  36 + 'application/postscript' ]
  37 +
  38 + SPREADSHEET_MIMETYPES = [ 'application/vnd.ms-excel',
  39 + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  40 + 'application/vnd.oasis.opendocument.spreadsheet',
  41 + 'application/vnd.oasis.opendocument.spreadsheet-template',
  42 + 'application/vnd.sun.xml.calc',
  43 + 'application/vnd.sun.xml.calc.template',
  44 + 'application/vnd.sun.xml.math',
  45 + 'application/vnd.stardivision.calc' ]
  46 +
  47 + VIDEO_MIMETYPES = [ 'video/quicktime',
  48 + 'video/mpeg' ]
  49 +
  50 +
  51 + def remove_slash_at_end_url(url)
  52 + url.gsub!(/\/$/,'') if url =~ /\/$/
  53 + url
  54 + end
  55 +
  56 + def class_for_item_mimetype(mimetype)
  57 +
  58 + case
  59 +
  60 + when mimetype == 'application/pdf'
  61 + mimetype_class = 'pdf'
  62 +
  63 + when TEXT_MIMETYPES.include?(mimetype)
  64 + mimetype_class = 'text'
  65 +
  66 + when AUDIO_MIMETYPES.include?(mimetype)
  67 + mimetype_class = 'audio'
  68 +
  69 + when DOCUMENT_MIMETYPES.include?(mimetype)
  70 + mimetype_class = 'document'
  71 +
  72 + when PICTURE_MIMETYPES.include?(mimetype)
  73 + mimetype_class = 'picture'
  74 +
  75 + when SPREADSHEET_MIMETYPES.include?(mimetype)
  76 + mimetype_class = 'spreadsheet'
  77 +
  78 + when VIDEO_MIMETYPES.include?(mimetype)
  79 + mimetype_class = 'video'
  80 +
  81 + else
  82 + mimetype_class = 'other'
  83 +
  84 + end
  85 +
  86 + "icon-#{mimetype_class}"
  87 +
  88 + end
  89 +
  90 +end
plugins/dspace/lib/dspace_plugin/library.rb 0 → 100644
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +class DspacePlugin::Library < Folder
  2 +
  3 + settings_items :dspace_server_url, :type => :string
  4 +
  5 + attr_accessible :dspace_server_url
  6 +
  7 + def dspace_server_url_valid
  8 +
  9 + if self.dspace_server_url.blank?
  10 + errors.add(:dspace_server_url, _("can't be blank") )
  11 + return
  12 + end
  13 +
  14 + errors.add(self.dspace_server_url, _("is not a valid URL. Please correct it and resubmit.")) unless url_valid?(self.dspace_server_url)
  15 + end
  16 +
  17 + validate :dspace_server_url_valid
  18 +
  19 + def self.icon_name(article = nil)
  20 + 'dspace-library'
  21 + end
  22 +
  23 + def self.short_description
  24 + _("DSpace library")
  25 + end
  26 +
  27 + def self.description
  28 + _("Defines a DSpace library")
  29 + end
  30 +
  31 + def to_html(options = {})
  32 + dspace_content = self
  33 + proc do
  34 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  35 + end
  36 + end
  37 +
  38 + def communities
  39 + DspacePlugin::Communityy.find(:all)
  40 + end
  41 +
  42 + protected
  43 +
  44 + def url_valid?(url)
  45 + url = URI.parse(url) rescue false
  46 + url.kind_of?(URI::HTTP) || url.kind_of?(URI::HTTPS)
  47 + end
  48 +
  49 +end
plugins/dspace/lib/dspace_plugin/library_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::LibraryHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/public/icons/audio.png 0 → 100644

717 Bytes

plugins/dspace/public/icons/document.png 0 → 100644

658 Bytes

plugins/dspace/public/icons/dspace.png 0 → 100644

3.2 KB

plugins/dspace/public/icons/pdf.png 0 → 100644

874 Bytes

plugins/dspace/public/icons/picture.png 0 → 100644

525 Bytes

plugins/dspace/public/icons/spreadsheet.png 0 → 100644

644 Bytes

plugins/dspace/public/icons/text.png 0 → 100644

419 Bytes

plugins/dspace/public/icons/video.png 0 → 100644

711 Bytes

plugins/dspace/public/javascripts/dspace_plugin.js 0 → 100644
@@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
  1 +/**
  2 +
  3 +function selectCommunity(element, community_slug) {
  4 + var hidden_field = jQuery('<input>').attr({
  5 + id: 'article_dspace_community_name_',
  6 + name: 'article[dspace_communities_names][]',
  7 + type: 'hidden',
  8 + name: 'article[dspace_communities_names][]',
  9 + value: community_slug
  10 + });
  11 + jQuery(hidden_field).insertAfter(element);
  12 +}
  13 +
  14 +
  15 +function selectCollection(element, collection_slug) {
  16 + var hidden_field = jQuery('<input>').attr({
  17 + id: 'article_dspace_collection_name_',
  18 + name: 'article[dspace_collections_names][]',
  19 + type: 'hidden',
  20 + name: 'article[dspace_collections_names][]',
  21 + value: collection_slug
  22 + });
  23 + jQuery(hidden_field).insertAfter(element);
  24 +}
  25 +
  26 +function select_action(field_active) {
  27 +}
  28 +**/
  29 +
  30 +jQuery(document).ready(function() {
  31 + url_base = window.location.protocol + '//' + window.location.host;
  32 + forms = jQuery('form');
  33 + forms.each( function(f) {
  34 + url_action = forms[f].action;
  35 + if (url_action.indexOf("/cms/new") > -1) {
  36 + forms[f].action = url_action.replace("/cms/new", "/plugin/dspace/new").replace(url_base,'');
  37 + }
  38 + });
  39 +
  40 + function check_fields(check, table_id) {
  41 + var checkboxes = jQuery("#" + table_id + " tbody tr td input[type='checkbox']")
  42 + for (var i = 0; i < checkboxes.length; i++) {
  43 + if (checkboxes[i].disabled == false) {
  44 + checkboxes[i].checked = check
  45 + }
  46 + }
  47 + }
  48 +
  49 + function verify_checked(field_id){
  50 + var checkboxes = jQuery("#" + field_id + "_fields_conf tbody tr td input[type='checkbox']")
  51 + var allchecked = true;
  52 + for (var j = 1; j < checkboxes.length; j++) {
  53 + if(!checkboxes[j].checked) {
  54 + allchecked = false;
  55 + break;
  56 + }
  57 + }
  58 +
  59 + var checkbox = jQuery("#" + field_id + "_active");
  60 + checkbox.attr("checked", allchecked);
  61 + }
  62 +
  63 +
  64 + function check_all(field_id) {
  65 + jQuery("#" + field_id + "_active").click(function (){
  66 + check_fields(this.checked, field_id + "_fields_conf")
  67 + });
  68 + verify_checked(field_id);
  69 + }
  70 +
  71 + check_all("community");
  72 + check_all("collection");
  73 +
  74 + jQuery("input[type='checkbox']").click(function () {
  75 + var checkbox = jQuery(this).attr("id").split("_");
  76 + verify_checked(checkbox.first());
  77 +
  78 + if(this.checked == false) {
  79 + jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", false)
  80 + }
  81 +
  82 + jQuery(this).next().attr("disabled", !this.checked);
  83 + })
  84 +
  85 +});
plugins/dspace/public/style.css 0 → 100644
@@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
  1 +#dspace_library ul {
  2 + margin: 0;
  3 + padding: 0 0 0 5px;
  4 +}
  5 +
  6 +#dspace_library li {
  7 + /**list-style-image: url(/designs/themes/base/imgs/li-recent.gif);*/
  8 + list-style-type: none;
  9 +}
  10 +
  11 +#dspace_library li.item,
  12 +#dspace_library li.collection,
  13 +#dspace_library li.community {
  14 + margin: 0;
  15 + padding: 10px 0;
  16 +}
  17 +
  18 +#dspace_library li.item span.name,
  19 +#dspace_library li.collection span.title,
  20 +#dspace_library li.community span.title {
  21 + font-weight: bold;
  22 +}
  23 +
  24 +#dspace_library div#actions {
  25 + margin: 10px 0;
  26 +}
  27 +
  28 +#dspace_library_item {
  29 + /*8border: 1px solid green;*/
  30 +}
  31 +
  32 +.dspace_item_section {
  33 + margin: 15px;
  34 +}
  35 +
  36 +.dspace_item_section_title {
  37 + margin: 0px;
  38 + font-weight: bold;
  39 + border-bottom: 1px solid #c0c0c0;
  40 +}
  41 +
  42 +#dspace_library_item ul {
  43 + list-style-type: none;
  44 +}
  45 +
  46 +#dspace_library_item ul#item_files_list,
  47 +#dspace_library_item ul.item_file_attributes_list {
  48 + margin: 0;
  49 + padding: 0;
  50 +}
  51 +
  52 +#dspace_library_item ul#item_files_list > li {
  53 + margin: 5px 0;
  54 +}
  55 +
  56 +.icon-newdspace-library,
  57 +.icon-dspace-library,
  58 +.icon-newdspace-community,
  59 +.icon-dspace-community,
  60 +.icon-newdspace-collection,
  61 +.icon-dspace-collection {
  62 + background-image: url(/plugins/dspace/icons/dspace.png)
  63 +}
  64 +
  65 +#dspace_library div.icon-item {
  66 + width: 32px;
  67 + height: 33px;
  68 + display: inline-block;
  69 + vertical-align: top;
  70 + border-right: 1px solid #c0c0c0;
  71 +}
  72 +
  73 +#dspace_library div.icon-audio {
  74 + background-image: url(/plugins/dspace/icons/audio.png)
  75 +}
  76 +
  77 +#dspace_library div.icon-document {
  78 + background-image: url(/plugins/dspace/icons/document.png)
  79 +}
  80 +
  81 +#dspace_library div.icon-pdf {
  82 + background-image: url(/plugins/dspace/icons/pdf.png)
  83 +}
  84 +
  85 +#dspace_library div.icon-picture {
  86 + background-image: url(/plugins/dspace/icons/picture.png)
  87 +}
  88 +
  89 +#dspace_library div.icon-spreadsheet {
  90 + background-image: url(/plugins/dspace/icons/spreadsheet.png)
  91 +}
  92 +
  93 +#dspace_library div.icon-text,
  94 +#dspace_library div.icon-other {
  95 + background-image: url(/plugins/dspace/icons/text.png)
  96 +}
  97 +
  98 +#dspace_library div.icon-video {
  99 + background-image: url(/plugins/dspace/icons/video.png)
  100 +}
  101 +
plugins/dspace/views/cms/dspace_plugin/_collection.html.erb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +<h1><%= _('DSpace Collections') %></h1>
  2 +
  3 +<%= hidden_field_tag 'article[parent_id]', @article.parent_id %>
  4 +
  5 +<%= hidden_field_tag 'article[dspace_community_id]', @article.parent.dspace_community_id %>
  6 +
  7 +<% dspace_server_url = @article.parent.parent.dspace_server_url %>
  8 +
  9 +<% community_id = @article.parent.dspace_community_id %>
  10 +
  11 +<% collections = Dspace::Community.get_all_collections_from( dspace_server_url, community_id ).map { |collection| item = [_(collection.name), collection.id] } %>
  12 +
  13 +<table id="collection_fields_conf" border="0" style="border-bottom: 1px solid #c0c0c0;">
  14 + <tr style="background-color: #f0f0f0; border-top: 1px solid #c0c0c0; border-bottom: 1px solid #c0c0c0;">
  15 + <td style="font-style: italic">
  16 + <%= _("Check/Uncheck All Unlocked")%>
  17 + </td>
  18 + <td align="center">
  19 + <input type="checkbox" id="collection_active" />
  20 + </td>
  21 + </tr>
  22 +
  23 + <% dspace_collections_ids = DspacePlugin::Collection.find(:all, :conditions => { :parent_id => @article.parent_id}).map { |collection| ids = collection.dspace_collection_id.to_i } %>
  24 +
  25 + <% collections.each do |collection| %>
  26 +
  27 + <tr>
  28 + <td>
  29 + <%= collection[0] %>
  30 + </td>
  31 +
  32 + <% if dspace_collections_ids.include? collection[1] %>
  33 + <td align="center">
  34 + <%= check_box_tag "article[dspace_collections][][id]", collection[1], true, :disabled => 'disabled', :id => "collection_id_#{collection[1]}" %>
  35 + <%= hidden_field_tag "article[dspace_collections][][name]", collection[0], :disabled => 'disabled' %>
  36 + </td>
  37 + <% else %>
  38 + <td align="center">
  39 + <%= check_box_tag "article[dspace_collections][][id]", collection[1], false, :id => "collection_id_#{collection[1]}" %>
  40 + <%= hidden_field_tag "article[dspace_collections][][name]", collection[0], :disabled => 'disabled', :id => "collection_name_#{collection[1]}" %>
  41 + </td>
  42 + <% end %>
  43 +
  44 + </tr>
  45 +
  46 + <% end %>
  47 +
  48 +</table>
  49 +
  50 +<%= javascript_include_tag 'plugins/dspace/javascripts/dspace_plugin' %>
plugins/dspace/views/cms/dspace_plugin/_communityy.html.erb 0 → 100644
@@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
  1 +<h1><%= _('DSpace Communities') %></h1>
  2 +
  3 +<%= hidden_field_tag 'article[parent_id]', @article.parent_id %>
  4 +
  5 +<% dspace_server_url = @article.parent.dspace_server_url %>
  6 +
  7 +<% communities = Dspace::Community.get_all_communities_from(dspace_server_url).map { |community| item = [_(community.name), community.id] } %>
  8 +
  9 +<table id="community_fields_conf" border="0" style="border-bottom: 1px solid #c0c0c0;">
  10 + <tr style="background-color: #f0f0f0; border-top: 1px solid #c0c0c0; border-bottom: 1px solid #c0c0c0;">
  11 + <td style="font-style: italic">
  12 + <%= _("Check/Uncheck All Unlocked")%>
  13 + </td>
  14 + <td align="center">
  15 + <input type="checkbox" id="community_active" />
  16 + </td>
  17 + </tr>
  18 +
  19 + <% dspace_communities_ids = DspacePlugin::Communityy.find(:all, :conditions => { :parent_id => @article.parent_id }).map { |community| ids = community.dspace_community_id.to_i } %>
  20 +
  21 + <% communities.each do |community| %>
  22 +
  23 + <tr>
  24 + <td>
  25 + <%= community[0] %>
  26 + </td>
  27 +
  28 + <% if dspace_communities_ids.include? community[1] %>
  29 + <td align="center">
  30 + <%= check_box_tag "article[dspace_communities][][id]", community[1], true, :disabled => 'disabled', :id => "community_id_#{community[1]}" %>
  31 + <%= hidden_field_tag "article[dspace_communities][][name]", community[0], :disabled => 'disabled' %>
  32 + </td>
  33 + <% else %>
  34 + <td align="center">
  35 + <%= check_box_tag "article[dspace_communities][][id]", community[1], false, :id => "community_id_#{community[1]}" %>
  36 + <%= hidden_field_tag "article[dspace_communities][][name]", community[0], :disabled => 'disabled', :id => "community_name_#{community[1]}" %>
  37 + </td>
  38 + <% end %>
  39 +
  40 + </tr>
  41 +
  42 + <% end %>
  43 +
  44 +</table>
  45 +
  46 +<%= javascript_include_tag 'plugins/dspace/javascripts/dspace_plugin' %>
plugins/dspace/views/cms/dspace_plugin/_library.html.erb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<h1><%= _('My DSpace Library') %></h1>
  2 +
  3 +<%= render :file => 'shared/tiny_mce' %>
  4 +
  5 +<%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %>
  6 +
  7 +<%= required f.text_field(:dspace_server_url, :size => '150', :maxlength => 150) %>
  8 +
  9 +<%= render :partial => 'general_fields' %>
  10 +
  11 +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 68, :rows => 10)) %>
plugins/dspace/views/content_viewer/_collection.html.erb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<li class="collection">
  2 + <span class="title"><%= link_to collection.name, :controller => 'content_viewer', :action => 'view_page', :page => collection.path %></span>
  3 +</li>
plugins/dspace/views/content_viewer/_community.html.erb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<li class="community">
  2 + <span class="title"><%= link_to community.title, :controller => 'content_viewer', :action => 'view_page', :page => community.path %></span>
  3 +</li>
plugins/dspace/views/content_viewer/_item.html.erb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +<li class="item">
  2 + <div style="vertical-align: top;">
  3 + <div class="icon-item <%= item.class_for_item_mimetype(item.mimetype) %>"></div>
  4 + <div style="display: inline-block; width: 92%;">
  5 + <span class="name"><%= link_to item.name, :controller => 'dspace_plugin', :action => 'view_item', :id => item.id, :collection_id => @page.id %></span><br />
  6 + <span class="authors"><%= item.author %></span> <span class="date_issued">(<%= item.issue_date %>)</span>
  7 + </div>
  8 + </div>
  9 +</li>
plugins/dspace/views/content_viewer/dspace_content.html.erb 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +<div id="dspace_library">
  2 +
  3 + <% if dspace_content.allow_create?(user) %>
  4 +
  5 + <div id="actions">
  6 +
  7 + <% if dspace_content.is_a? DspacePlugin::Library %>
  8 +
  9 + <%= content_tag('a', :href => url_for({:controller => 'cms', :action => 'new', :type => "DspacePlugin::Communityy", :parent_id => dspace_content.id}), :class => 'button with-text icon-add') do %>
  10 + <%= _("Add %s") % DspacePlugin::Communityy.short_description %>
  11 + <% end %>
  12 +
  13 + <% elsif dspace_content.is_a? DspacePlugin::Communityy %>
  14 +
  15 + <%= content_tag('a', :href => url_for({:controller => 'cms', :action => 'new', :type => "DspacePlugin::Collection", :parent_id => dspace_content.id}), :class => 'button with-text icon-add') do %>
  16 + <%= _("Add %s") % DspacePlugin::Collection.short_description %>
  17 + <% end %>
  18 +
  19 + <% end %>
  20 +
  21 + </div>
  22 +
  23 + <% end %>
  24 +
  25 + <% if dspace_content.is_a? DspacePlugin::Library %>
  26 +
  27 + <% communities = dspace_content.communities %>
  28 +
  29 + <ul id="communities_list">
  30 + <%= render :partial => 'community', :collection => communities %>
  31 + </ul>
  32 +
  33 + <% elsif dspace_content.is_a? DspacePlugin::Communityy %>
  34 +
  35 + <% community_id = dspace_content.dspace_community_id %>
  36 + <% dspace_server = dspace_content.parent.dspace_server_url %>
  37 +
  38 + <% collections = dspace_content.collections dspace_server, community_id %>
  39 +
  40 + <ul id="collections_list">
  41 + <%= render :partial => 'collection', :collection => collections %>
  42 + </ul>
  43 +
  44 + <% elsif dspace_content.is_a? DspacePlugin::Collection %>
  45 +
  46 + <% collection_id = dspace_content.dspace_collection_id %>
  47 + <% dspace_server = dspace_content.parent.parent.dspace_server_url %>
  48 +
  49 + <div id="dspace_library">
  50 + <div id="dspace_collection">
  51 + <ul id="items_list">
  52 + <%= render :partial => 'item', :collection => dspace_content.items(dspace_server, collection_id) %>
  53 + </ul>
  54 + </div>
  55 + </div>
  56 +
  57 + <% end %>
  58 +
  59 +</div>
plugins/dspace/views/dspace_plugin/_item_file.html.erb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +<li>
  2 + <ul class="item_file_attributes_list">
  3 + <li>
  4 + <span><%= _('File:') %></span> <%= link_to item_file.name, dspace_server_url + item_file.retrieve_link, :target => '_blank' %></li>
  5 + <% unless item_file.description.blank? %>
  6 + <li>
  7 + <span><%= _('Description:') %> </span> <%= item_file.description %></li>
  8 + <% end %>
  9 + <li>
  10 + <span><%= _('Size:') %> </span> <%= number_to_human_size( item_file.size_bytes ) %></li>
  11 + </ul>
  12 +</li>
plugins/dspace/views/dspace_plugin/_item_section.html.erb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div class="dspace_item_section">
  2 + <div class="dspace_item_section_title">
  3 + <%= item_section[:title] %>
  4 + </div>
  5 + <div class="dspace_item_section_content">
  6 + <%= item_section[:content] %>
  7 + </div>
  8 +</div>
plugins/dspace/views/dspace_plugin/view_item.html.erb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +<% extend DspacePlugin::ItemHelper %>
  2 +
  3 +<div id="article-parent">
  4 + <%= button(:back, _('Go back to %s') % @collection.short_title, @collection.url) %>
  5 +</div>
  6 +
  7 +<div id="dspace_library_item">
  8 +
  9 + <div id="dspace_item_title">
  10 + <h1 class="title"><%= @item.name %></h1>
  11 + </div>
  12 +
  13 + <% item_files = render :partial => 'item_file',
  14 + :locals => { :dspace_server_url => remove_slash_at_end_url(@collection.parent.parent.dspace_server_url) },
  15 + :collection => @item.files %>
  16 +
  17 + <% item_files_content = content_tag('ul', item_files, :id => 'item_files_list') %>
  18 +
  19 +
  20 + <%= render :partial => 'item_section',
  21 + :collection => [ { :title => _('Authors:'), :content => @item.author },
  22 + { :title => _('Issue date:'), :content => @item.issue_date },
  23 + { :title => _('Abstract:'), :content => @item.abstract },
  24 + { :title => _('Description:'), :content => @item.description },
  25 + { :title => _('URI:'), :content => link_to(@item.uri, @item.uri, :target => '_blank') },
  26 + { :title => _('Files in this item'), :content => item_files_content } ] %>
  27 +
  28 +</div>
plugins/proposals_discussion/controllers/public/proposals_discussion_plugin_public_controller.rb
@@ -20,6 +20,12 @@ class ProposalsDiscussionPluginPublicController &lt; ApplicationController @@ -20,6 +20,12 @@ class ProposalsDiscussionPluginPublicController &lt; ApplicationController
20 case order 20 case order
21 when 'alphabetical' 21 when 'alphabetical'
22 proposals.reorder('name') 22 proposals.reorder('name')
  23 + when 'recent'
  24 + proposals.reorder('created_at DESC')
  25 + when 'most_commented'
  26 + proposals.reorder('comments_count DESC')
  27 + when 'most_recently_commented'
  28 + proposals.joins("LEFT OUTER JOIN comments ON comments.source_id=articles.id AND comments.created_at >= '#{5.days.ago}'").group('articles.id').reorder('count(comments.id) DESC')
23 else 29 else
24 set_seed 30 set_seed
25 proposals.reorder('random()') 31 proposals.reorder('random()')
plugins/proposals_discussion/lib/proposals_discussion_plugin/discussion.rb
1 class ProposalsDiscussionPlugin::Discussion < Folder 1 class ProposalsDiscussionPlugin::Discussion < Folder
2 2
  3 + acts_as_having_posts
  4 +
3 has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id' 5 has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id'
4 has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children 6 has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children
5 7
@@ -26,4 +28,9 @@ class ProposalsDiscussionPlugin::Discussion &lt; Folder @@ -26,4 +28,9 @@ class ProposalsDiscussionPlugin::Discussion &lt; Folder
26 end 28 end
27 alias_method_chain :cache_key, :person 29 alias_method_chain :cache_key, :person
28 30
  31 + def posts
  32 + #override posts method to list proposals in feed
  33 + ProposalsDiscussionPlugin::Proposal.from_discussion(self)
  34 + end
  35 +
29 end 36 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposal.rb
1 class ProposalsDiscussionPlugin::Proposal < TinyMceArticle 1 class ProposalsDiscussionPlugin::Proposal < TinyMceArticle
2 2
3 scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}} 3 scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}}
  4 + scope :from_discussion, lambda {|discussion| joins(:parent).where(['parents_articles.parent_id = ?', discussion.id])}
4 5
5 alias :topic :parent 6 alias :topic :parent
6 7
@@ -16,8 +17,12 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle @@ -16,8 +17,12 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
16 17
17 18
18 def to_html(options = {}) 19 def to_html(options = {})
19 - proc do  
20 - render :file => 'content_viewer/proposal' 20 + unless options[:feed]
  21 + proc do
  22 + render :file => 'content_viewer/proposal'
  23 + end
  24 + else
  25 + body
21 end 26 end
22 end 27 end
23 28
@@ -38,4 +43,8 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle @@ -38,4 +43,8 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
38 end 43 end
39 alias_method_chain :cache_key, :person 44 alias_method_chain :cache_key, :person
40 45
  46 + def can_display_versions?
  47 + false
  48 + end
  49 +
41 end 50 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposal_helper.rb
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -module ProposalsDiscussionPlugin::ProposalHelper  
2 -  
3 - def visibility_options(article, tokenized_children)  
4 - article.published = false if article.new_record?  
5 - super  
6 - end  
7 -  
8 -end  
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposals_list_helper.rb
1 module ProposalsDiscussionPlugin::ProposalsListHelper 1 module ProposalsDiscussionPlugin::ProposalsListHelper
2 2
  3 + def sort_criteria
  4 + [[_('Random'), :random], [_('Alphabetical'), :alphabetical], [_('Recent'), :recent], [_('Most Commented'), :most_commented], [_('Most Recently Commented'), :most_recently_commented]]
  5 + end
  6 +
3 def more_proposals(text, holder, order, page=1) 7 def more_proposals(text, holder, order, page=1)
4 link_to text, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order, :page => page }) 8 link_to text, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order, :page => page })
5 end 9 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/topic.rb
@@ -44,11 +44,21 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder @@ -44,11 +44,21 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder
44 end 44 end
45 45
46 def proposals_per_day 46 def proposals_per_day
47 - proposals.group("date(created_at)").count 47 + result = proposals.group("date(created_at)").count
  48 + fill_empty_days(result)
48 end 49 end
49 50
50 def comments_per_day 51 def comments_per_day
51 - proposals.joins(:comments).group('date(comments.created_at)').count('comments.id') 52 + result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id')
  53 + fill_empty_days(result)
  54 + end
  55 +
  56 + def fill_empty_days(result)
  57 + from = created_at.to_date
  58 + (from..Date.today).inject({}) do |h, date|
  59 + h[date.to_s] = result[date.to_s] || 0
  60 + h
  61 + end
52 end 62 end
53 63
54 def cache_key_with_person(params = {}, user = nil, language = 'en') 64 def cache_key_with_person(params = {}, user = nil, language = 'en')
plugins/proposals_discussion/lib/proposals_discussion_plugin/topic_helper.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +module ProposalsDiscussionPlugin::TopicHelper
  2 +
  3 + def topic_title(topic)
  4 + image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : ''
  5 +
  6 + content_tag(:div, (
  7 + content_tag(:div, '', :class=>'topic-color', :style => "background-color: #{topic.color};") +
  8 + content_tag(:h2, link_to(image_icon + content_tag(:span, topic.title), topic.view_url))
  9 + ), :class => 'topic-title')
  10 + end
  11 +
  12 +end
plugins/proposals_discussion/public/proposals_graph.js~
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -(function basic_time(container) {  
2 -  
3 - var  
4 - d1 = [],  
5 - start = new Date("2009/01/01 01:00").getTime(),  
6 - options,  
7 - graph,  
8 - i, x, o;  
9 -  
10 - for (i = 0; i < 100; i++) {  
11 - x = start+(i*1000*3600*24*36.5);  
12 - d1.push([x, i+Math.random()*30+Math.sin(i/20+Math.random()*2)*20+Math.sin(i/10+Math.random())*10]);  
13 - }  
14 -  
15 - options = {  
16 - xaxis : {  
17 - mode : 'time',  
18 - labelsAngle : 45  
19 - },  
20 - selection : {  
21 - mode : 'x'  
22 - },  
23 - HtmlText : false,  
24 - title : 'Time'  
25 - };  
26 -  
27 - // Draw graph with default options, overwriting with passed options  
28 - function drawGraph (opts) {  
29 -  
30 - // Clone the options, so the 'options' variable always keeps intact.  
31 - o = Flotr._.extend(Flotr._.clone(options), opts || {});  
32 -  
33 - // Return a new graph.  
34 - return Flotr.draw(  
35 - container,  
36 - [ d1 ],  
37 - o  
38 - );  
39 - }  
40 -  
41 - graph = drawGraph();  
42 -  
43 - Flotr.EventAdapter.observe(container, 'flotr:select', function(area){  
44 - // Draw selected area  
45 - graph = drawGraph({  
46 - xaxis : { min : area.x1, max : area.x2, mode : 'time', labelsAngle : 45 },  
47 - yaxis : { min : area.y1, max : area.y2 }  
48 - });  
49 - });  
50 -  
51 - // When graph is clicked, draw the graph with default area.  
52 - Flotr.EventAdapter.observe(container, 'flotr:click', function () { graph = drawGraph(); });  
53 -})(document.getElementById("editor-render-0"));  
plugins/proposals_discussion/public/proposals_list.js
@@ -10,9 +10,9 @@ jQuery(document).ready(function($) { @@ -10,9 +10,9 @@ jQuery(document).ready(function($) {
10 }); 10 });
11 11
12 function proposalsScroll() { 12 function proposalsScroll() {
13 - var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list'); 13 + var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals');
14 var nextSelector = 'div.more a'; 14 var nextSelector = 'div.more a';
15 - if(scroll.data('jscroll')) scroll.jscroll.destroy(); 15 + if(scroll.data('jscroll')) scroll.data('jscroll', null);
16 16
17 if(scroll.find(nextSelector).length > 0) { 17 if(scroll.find(nextSelector).length > 0) {
18 scroll.jscroll({ 18 scroll.jscroll({
@@ -31,6 +31,12 @@ jQuery(document).ready(function($) { @@ -31,6 +31,12 @@ jQuery(document).ready(function($) {
31 $('.topics').masonry(); 31 $('.topics').masonry();
32 }); 32 });
33 $('.topics').masonry(); 33 $('.topics').masonry();
  34 + $(window).resize(function() {
  35 + $('.topics').masonry();
  36 + });
  37 + $(window).bind('toggleFullwidth', function() {
  38 + $('.topics').masonry();
  39 + });
34 }); 40 });
35 41
36 function loadSocialButtons() { 42 function loadSocialButtons() {
plugins/proposals_discussion/public/style.css
@@ -156,11 +156,14 @@ form .proposals-discussion-plugin .body textarea { @@ -156,11 +156,14 @@ form .proposals-discussion-plugin .body textarea {
156 #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a, 156 #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a,
157 #content .topic h2 a { 157 #content .topic h2 a {
158 text-decoration: none; 158 text-decoration: none;
159 - padding: 10px;  
160 display: inline-block; 159 display: inline-block;
161 width: 94%; 160 width: 94%;
162 color: white; 161 color: white;
163 } 162 }
  163 +#content .topic-title h2 span {
  164 + padding: 10px;
  165 + display: inline-block;
  166 +}
164 .topic-item .topic-content, #article .article-body-proposals-discussion-plugin_topic .topic-content { 167 .topic-item .topic-content, #article .article-body-proposals-discussion-plugin_topic .topic-content {
165 padding: 5px 7px 5px 2px; 168 padding: 5px 7px 5px 2px;
166 } 169 }
@@ -177,7 +180,7 @@ form .proposals-discussion-plugin .body textarea { @@ -177,7 +180,7 @@ form .proposals-discussion-plugin .body textarea {
177 margin: 1px 0 0 0; 180 margin: 1px 0 0 0;
178 } 181 }
179 182
180 -#content .tag_cloud a { 183 +#content .article-body-proposals-discussion-plugin_topic .tag_cloud a {
181 text-decoration: none; 184 text-decoration: none;
182 } 185 }
183 186
@@ -199,7 +202,7 @@ form .proposals-discussion-plugin .body textarea { @@ -199,7 +202,7 @@ form .proposals-discussion-plugin .body textarea {
199 #content .statistics h5 { 202 #content .statistics h5 {
200 color: rgb(95, 95, 95); 203 color: rgb(95, 95, 95);
201 } 204 }
202 -#content .tag_cloud { 205 +#content .article-body-proposals-discussion-plugin_topic .tag_cloud {
203 float: right; 206 float: right;
204 width: 300px; 207 width: 300px;
205 box-shadow: 5px 5px 5px -2px #ddd; 208 box-shadow: 5px 5px 5px -2px #ddd;
@@ -219,3 +222,13 @@ form .proposals-discussion-plugin .body textarea { @@ -219,3 +222,13 @@ form .proposals-discussion-plugin .body textarea {
219 clear: both; 222 clear: both;
220 padding-top: 10px; 223 padding-top: 10px;
221 } 224 }
  225 +
  226 +.proposal .actions .fb-share-button {
  227 + top: -3px;
  228 +}
  229 +
  230 +.topic-title h2 img {
  231 + max-height: 36px;
  232 + vertical-align: middle;
  233 + padding: 4px 0 4px 4px;
  234 +}
plugins/proposals_discussion/test/functional/proposals_discussion_plugin_public_controller_test.rb
@@ -35,4 +35,48 @@ class ProposalsDiscussionPluginPublicControllerTest &lt; ActionController::TestCase @@ -35,4 +35,48 @@ class ProposalsDiscussionPluginPublicControllerTest &lt; ActionController::TestCase
35 assert_equal [proposal2, proposal3, proposal1], assigns(:proposals) 35 assert_equal [proposal2, proposal3, proposal1], assigns(:proposals)
36 end 36 end
37 37
  38 + should 'load proposals with most commented order' do
  39 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal1', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  40 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal2', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  41 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal3', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  42 +
  43 + author = fast_create(Person)
  44 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  45 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  46 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  47 +
  48 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'most_commented'
  49 + assert_equal [proposal2, proposal3, proposal1], assigns(:proposals)
  50 + end
  51 +
  52 + should 'load proposals with most recent order' do
  53 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'z', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  54 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'b', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  55 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'k', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  56 +
  57 + author = fast_create(Person)
  58 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  59 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  60 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  61 +
  62 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'recent'
  63 + assert_equal [proposal3, proposal2, proposal1], assigns(:proposals)
  64 + end
  65 +
  66 + should 'load proposals with most recently commented order' do
  67 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal1', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  68 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal2', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  69 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal3', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  70 +
  71 + author = fast_create(Person)
  72 + Comment.create!({:source => proposal2, :body => 'text', :author => author, :created_at => 10.days.ago}, :without_protection => true)
  73 + Comment.create!({:source => proposal2, :body => 'text', :author => author, :created_at => 10.days.ago}, :without_protection => true)
  74 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  75 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  76 + Comment.create!(:source => proposal1, :body => 'text', :author => author)
  77 +
  78 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'most_recently_commented'
  79 + assert_equal [proposal3, proposal1, proposal2], assigns(:proposals)
  80 + end
  81 +
38 end 82 end
plugins/proposals_discussion/test/unit/proposal_test.rb
@@ -29,4 +29,26 @@ class ProposalTest &lt; ActiveSupport::TestCase @@ -29,4 +29,26 @@ class ProposalTest &lt; ActiveSupport::TestCase
29 assert !proposal.allow_edit?(fast_create(Person)) 29 assert !proposal.allow_edit?(fast_create(Person))
30 end 30 end
31 31
  32 + should 'return body when to_html was called with feed=true' do
  33 + assert_equal proposal.body, proposal.to_html(:feed => true)
  34 + end
  35 +
  36 + should 'return a proc when to_html was called with feed=false' do
  37 + assert proposal.to_html(:feed => false).kind_of?(Proc)
  38 + end
  39 +
  40 + should 'return a proc when to_html was called with no feed parameter' do
  41 + assert proposal.to_html.kind_of?(Proc)
  42 + end
  43 +
  44 + should 'return proposals by discussion' do
  45 + discussion = fast_create(ProposalsDiscussionPlugin::Discussion)
  46 + topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id)
  47 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
  48 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal)
  49 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
  50 +
  51 + assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion)
  52 + end
  53 +
32 end 54 end
plugins/proposals_discussion/views/cms/proposals_discussion_plugin/_proposal.html.erb
@@ -5,7 +5,14 @@ @@ -5,7 +5,14 @@
5 <% title_limit = 70 %> 5 <% title_limit = 70 %>
6 <% abstract_limit = 140 %> 6 <% abstract_limit = 140 %>
7 7
  8 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  9 +
8 <div class="proposals-discussion-plugin"> 10 <div class="proposals-discussion-plugin">
  11 +
  12 + <div class="topic">
  13 + <%= topic_title @article.topic %>
  14 + </div>
  15 +
9 <div class="title"> 16 <div class="title">
10 <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %> 17 <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %>
11 </div> 18 </div>
plugins/proposals_discussion/views/cms/proposals_discussion_plugin/_topic.html.erb
@@ -11,3 +11,8 @@ @@ -11,3 +11,8 @@
11 11
12 <%= labelled_colorpicker_field(_('Color:'), :article, :color) %> 12 <%= labelled_colorpicker_field(_('Color:'), :article, :color) %>
13 <span id="color_preview" class = "color_marker" style="background-color: <%= @article.color %>" ></span> 13 <span id="color_preview" class = "color_marker" style="background-color: <%= @article.color %>" ></span>
  14 +
  15 +<%= f.fields_for :image_builder, @article.image do |i| %>
  16 + <%= file_field_or_thumbnail(_('Image:'), @article.image, i)%>
  17 + <%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %>
  18 +<% end %>
plugins/proposals_discussion/views/content_viewer/_proposals_list.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <% order ||= 'random' %> 12 <% order ||= 'random' %>
13 <div class="proposals_list"> 13 <div class="proposals_list">
14 <div class="filters"> 14 <div class="filters">
15 - <% [[_('Random'), :random], [_('Aplhabetical'), :alphabetical]].each_with_index do |order, i| %> 15 + <% sort_criteria.each_with_index do |order, i| %>
16 <%= link_to order.first, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order.second}), :remote => true, :class => "order #{order.second} #{i==0 ? 'selected':''}" %> 16 <%= link_to order.first, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order.second}), :remote => true, :class => "order #{order.second} #{i==0 ? 'selected':''}" %>
17 <% end %> 17 <% end %>
18 </div> 18 </div>
plugins/proposals_discussion/views/content_viewer/_social.html.erb
1 <a href="https://twitter.com/share" class="twitter-share-button" data-url="<%= url_for proposal.view_url %>" data-text="<%= proposal.title %>" data-count="none"></a> 1 <a href="https://twitter.com/share" class="twitter-share-button" data-url="<%= url_for proposal.view_url %>" data-text="<%= proposal.title %>" data-count="none"></a>
2 2
3 -<div class="fb-share-button" data-href="<%= url_for proposal.view_url %>" data-layout="box-count"></div> 3 +<div class="fb-share-button" data-href="<%= url_for proposal.view_url %>"></div>
plugins/proposals_discussion/views/content_viewer/discussion.html.erb
1 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %> 1 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %>
2 2
  3 +<%= add_rss_feed_to_head(@page.name, @page.feed.url) if @page.feed %>
  4 +
3 <div class="description"> 5 <div class="description">
4 <%= @page.body %> 6 <%= @page.body %>
5 </div> 7 </div>
plugins/proposals_discussion/views/content_viewer/proposal.html.erb
@@ -2,9 +2,10 @@ @@ -2,9 +2,10 @@
2 <h5><%= @page.topic.discussion.title %> </h5> 2 <h5><%= @page.topic.discussion.title %> </h5>
3 </div> 3 </div>
4 4
  5 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  6 +
5 <div class="topic"> 7 <div class="topic">
6 - <div class="topic-color" style="background-color: <%= @page.topic.color %>;"></div>  
7 - <h2><%= link_to @page.topic.title, @page.topic.view_url %></h2> 8 + <%= topic_title @page.topic %>
8 </div> 9 </div>
9 10
10 <div class="title"> 11 <div class="title">
plugins/proposals_discussion/views/content_viewer/topic.html.erb
@@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
4 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %> 4 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %>
5 <% end %> 5 <% end %>
6 6
7 -<div class="topic-color" style="background-color: <%= topic.color %>;"></div>  
8 -<h2><%= link_to topic.title, topic.view_url %></h2> 7 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  8 +<%= topic_title topic %>
9 9
10 <div class="topic-content"> 10 <div class="topic-content">
11 11
plugins/proposals_discussion/views/select_topic.html.erb
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 <h3><%= _('Select topic') %></h3> 16 <h3><%= _('Select topic') %></h3>
17 <div id="topics"> 17 <div id="topics">
18 18
19 - <% @discussion.children.each do |topic| %> 19 + <% @discussion.topics.each do |topic| %>
20 <h4> 20 <h4>
21 <%= radio_button_tag('discussion[topic]', topic.id) %> 21 <%= radio_button_tag('discussion[topic]', topic.id) %>
22 <%= topic.title %> 22 <%= topic.title %>
public/javascripts/application.js
@@ -1037,7 +1037,7 @@ jQuery(document).ready(function(){ @@ -1037,7 +1037,7 @@ jQuery(document).ready(function(){
1037 function apply_zoom_to_images(zoom_text) { 1037 function apply_zoom_to_images(zoom_text) {
1038 jQuery(function($) { 1038 jQuery(function($) {
1039 $(window).load( function() { 1039 $(window).load( function() {
1040 - $('#article .article-body img').each( function(index) { 1040 + $('#article .article-body img:not(.disable-zoom)').each( function(index) {
1041 var original = original_image_dimensions($(this).attr('src')); 1041 var original = original_image_dimensions($(this).attr('src'));
1042 if ($(this).width() < original['width'] || $(this).height() < original['height']) { 1042 if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1043 $(this).wrap('<div class="zoomable-image" />'); 1043 $(this).wrap('<div class="zoomable-image" />');
@@ -1083,6 +1083,7 @@ function toggle_fullwidth(itemId){ @@ -1083,6 +1083,7 @@ function toggle_fullwidth(itemId){
1083 jQuery("#fullscreen-btn").hide() 1083 jQuery("#fullscreen-btn").hide()
1084 fullwidth = true; 1084 fullwidth = true;
1085 } 1085 }
  1086 + jQuery(window).trigger("toggleFullwidth", fullwidth);
1086 } 1087 }
1087 1088
1088 function fullscreenPageLoad(itemId){ 1089 function fullscreenPageLoad(itemId){
script/install-dependencies/debian-wheezy.sh
@@ -50,6 +50,13 @@ FPQAoNmiMgP6zGF9rgOEWMEiFEryayrz @@ -50,6 +50,13 @@ FPQAoNmiMgP6zGF9rgOEWMEiFEryayrz
50 EOF 50 EOF
51 fi 51 fi
52 52
  53 +if test -f tmp/debian/Release.gpg; then
  54 + echo "deb file://$(pwd)/tmp/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list
  55 + sudo apt-key add tmp/debian/signing-key.asc
  56 +else
  57 + sudo rm -f /etc/apt/sources.list.d/local.list
  58 +fi
  59 +
53 run sudo apt-get update 60 run sudo apt-get update
54 run sudo apt-get -qy dist-upgrade 61 run sudo apt-get -qy dist-upgrade
55 62
script/install-dependencies/ubuntu-precise.sh 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +#!/bin/sh
  2 +
  3 +export DEBIAN_INTERFACE=noninteractive
  4 +
  5 +#run sudo apt-get update
  6 +#run sudo apt-get dist-upgrade -qy
  7 +
  8 +run sudo apt-get install -qy dctrl-tools
  9 +
  10 +packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debian/control | sed -e 's/([^)]*)//g; s/,\s*/\n/g' | grep -v 'rake\|ruby\|thin\|debhelper\|cucumber\|rail\|memcached\|debconf\|dbconfig-common\|misc:Depends\|adduser\|mail-transport-agent')
  11 +
  12 +run sudo apt-get install -qy ruby1.9.1-full build-essential libxml2-dev libxslt-dev libpq-dev libmagickcore-dev libmagickwand-dev $packages
  13 +
  14 +
  15 +export GEM_HOME=$(ruby -e 'puts Gem.user_dir')
  16 +export PATH="${GEM_HOME}/bin:${PATH}"
  17 +(gem list | grep bundler) || run gem install --no-rdoc --no-ri bundler
  18 +run bundle install
  19 +
  20 +sudo tee /etc/profile.d/rubygems-path.sh <<EOF
  21 +export GEM_HOME=\$(ruby -e 'puts Gem.user_dir')
  22 +PATH="\${GEM_HOME}/bin:\${PATH}"
  23 +EOF
test/factories.rb
@@ -174,7 +174,11 @@ module Noosfero::Factory @@ -174,7 +174,11 @@ module Noosfero::Factory
174 ############################################### 174 ###############################################
175 175
176 def defaults_for_environment 176 def defaults_for_environment
177 - { :name => 'Environment ' + factory_num_seq.to_s } 177 + seq = factory_num_seq
  178 + {
  179 + :name => "Environment %d" % seq,
  180 + :contact_email => "environment%d@example.com" % seq
  181 + }
178 end 182 end
179 183
180 ############################################### 184 ###############################################
test/functional/profile_controller_test.rb
@@ -78,7 +78,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -78,7 +78,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
78 78
79 should 'actually add friend' do 79 should 'actually add friend' do
80 login_as(@profile.identifier) 80 login_as(@profile.identifier)
81 - person = fast_create(Person) 81 + person = create_user.person
82 assert_difference 'AddFriend.count' do 82 assert_difference 'AddFriend.count' do
83 post :add, :profile => person.identifier 83 post :add, :profile => person.identifier
84 end 84 end
@@ -366,10 +366,10 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -366,10 +366,10 @@ class ProfileControllerTest &lt; ActionController::TestCase
366 assert profile.memberships.include?(community), 'profile should be actually added to the community' 366 assert profile.memberships.include?(community), 'profile should be actually added to the community'
367 end 367 end
368 368
369 - should 'create task when join to closed organization with members' do 369 + should 'create a task when joining a closed organization with members' do
370 community = fast_create(Community) 370 community = fast_create(Community)
371 community.update_attribute(:closed, true) 371 community.update_attribute(:closed, true)
372 - admin = fast_create(Person) 372 + admin = create_user.person
373 community.add_member(admin) 373 community.add_member(admin)
374 374
375 login_as profile.identifier 375 login_as profile.identifier
@@ -587,7 +587,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -587,7 +587,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
587 should "leave a scrap on another profile" do 587 should "leave a scrap on another profile" do
588 login_as(profile.identifier) 588 login_as(profile.identifier)
589 count = Scrap.count 589 count = Scrap.count
590 - another_person = fast_create(Person) 590 + another_person = create_user.person
591 assert another_person.scraps_received.empty? 591 assert another_person.scraps_received.empty?
592 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'} 592 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'}
593 assert_equal count + 1, Scrap.count 593 assert_equal count + 1, Scrap.count
@@ -645,7 +645,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -645,7 +645,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
645 should "the sender be the logged user by default" do 645 should "the sender be the logged user by default" do
646 login_as(profile.identifier) 646 login_as(profile.identifier)
647 count = Scrap.count 647 count = Scrap.count
648 - another_person = fast_create(Person) 648 + another_person = create_user.person
649 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'} 649 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'}
650 last = Scrap.last 650 last = Scrap.last
651 assert_equal profile, last.sender 651 assert_equal profile, last.sender
@@ -654,7 +654,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -654,7 +654,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
654 should "the receiver be the current profile by default" do 654 should "the receiver be the current profile by default" do
655 login_as(profile.identifier) 655 login_as(profile.identifier)
656 count = Scrap.count 656 count = Scrap.count
657 - another_person = fast_create(Person) 657 + another_person = create_user.person
658 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'} 658 post :leave_scrap, :profile => another_person.identifier, :scrap => {:content => 'something'}
659 last = Scrap.last 659 last = Scrap.last
660 assert_equal another_person, last.receiver 660 assert_equal another_person, last.receiver
@@ -686,8 +686,8 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -686,8 +686,8 @@ class ProfileControllerTest &lt; ActionController::TestCase
686 end 686 end
687 687
688 should 'not display activities of the current profile when he is not followed by the viewer' do 688 should 'not display activities of the current profile when he is not followed by the viewer' do
689 - p1= fast_create(Person)  
690 - p2= fast_create(Person) 689 + p1= create_user.person
  690 + p2= create_user.person
691 691
692 UserStampSweeper.any_instance.stubs(:current_user).returns(p1) 692 UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
693 scrap1 = create(Scrap, defaults_for_scrap(:sender => p1, :receiver => p2)) 693 scrap1 = create(Scrap, defaults_for_scrap(:sender => p1, :receiver => p2))
@@ -714,9 +714,9 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -714,9 +714,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
714 end 714 end
715 715
716 should 'not see the friends activities in the current profile' do 716 should 'not see the friends activities in the current profile' do
717 - p2= fast_create(Person) 717 + p2 = create_user.person
718 assert !profile.is_a_friend?(p2) 718 assert !profile.is_a_friend?(p2)
719 - p3= fast_create(Person) 719 + p3 = create_user.person
720 p3.add_friend(profile) 720 p3.add_friend(profile)
721 assert p3.is_a_friend?(profile) 721 assert p3.is_a_friend?(profile)
722 ActionTracker::Record.destroy_all 722 ActionTracker::Record.destroy_all
@@ -737,13 +737,13 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -737,13 +737,13 @@ class ProfileControllerTest &lt; ActionController::TestCase
737 end 737 end
738 738
739 should 'see all the activities in the current profile network' do 739 should 'see all the activities in the current profile network' do
740 - p1= fast_create(Person)  
741 - p2= fast_create(Person) 740 + p1= create_user.person
  741 + p2= create_user.person
742 assert !p1.is_a_friend?(p2) 742 assert !p1.is_a_friend?(p2)
743 743
744 - p3= fast_create(Person) 744 + p3= create_user.person
745 p3.add_friend(p1) 745 p3.add_friend(p1)
746 - assert p3.is_a_friend?(p1) 746 + p1.add_friend(p3)
747 747
748 ActionTracker::Record.delete_all 748 ActionTracker::Record.delete_all
749 749
@@ -759,27 +759,21 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -759,27 +759,21 @@ class ProfileControllerTest &lt; ActionController::TestCase
759 create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) 759 create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1))
760 a3 = ActionTracker::Record.last 760 a3 = ActionTracker::Record.last
761 761
762 - @controller.stubs(:logged_in?).returns(true)  
763 - user = mock()  
764 - user.stubs(:person).returns(p3)  
765 - user.stubs(:login).returns('some')  
766 - @controller.stubs(:current_user).returns(user)  
767 - Person.any_instance.stubs(:follows?).returns(true)  
768 -  
769 process_delayed_job_queue 762 process_delayed_job_queue
770 - get :index, :profile => p1.identifier  
771 763
  764 + login_as p3.user.login
  765 + get :index, :profile => p1.identifier
772 assert_equivalent [a1,a3].map(&:id), assigns(:network_activities).map(&:id) 766 assert_equivalent [a1,a3].map(&:id), assigns(:network_activities).map(&:id)
773 end 767 end
774 768
775 should 'the network activity be visible only to profile followers' do 769 should 'the network activity be visible only to profile followers' do
776 - p1= fast_create(Person)  
777 - p2= fast_create(Person) 770 + p1= create_user.person
  771 + p2= create_user.person
778 assert !p1.is_a_friend?(p2) 772 assert !p1.is_a_friend?(p2)
779 773
780 - p3= fast_create(Person) 774 + p3= create_user.person
781 p3.add_friend(p1) 775 p3.add_friend(p1)
782 - assert p3.is_a_friend?(p1) 776 + p1.add_friend(p3)
783 777
784 ActionTracker::Record.delete_all 778 ActionTracker::Record.delete_all
785 779
@@ -795,24 +789,11 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -795,24 +789,11 @@ class ProfileControllerTest &lt; ActionController::TestCase
795 create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1)) 789 create(Scrap, defaults_for_scrap(:sender => p3, :receiver => p1))
796 a3 = ActionTracker::Record.last 790 a3 = ActionTracker::Record.last
797 791
798 - @controller.stubs(:logged_in?).returns(true)  
799 - user = mock()  
800 - user.stubs(:person).returns(p2)  
801 - user.stubs(:login).returns('some')  
802 - @controller.stubs(:current_user).returns(user) 792 + process_delayed_job_queue
803 793
  794 + login_as p2.user.login
804 get :index, :profile => p1.identifier 795 get :index, :profile => p1.identifier
805 assert assigns(:network_activities).blank? 796 assert assigns(:network_activities).blank?
806 -  
807 - user = mock()  
808 - user.stubs(:person).returns(p3)  
809 - user.stubs(:login).returns('some')  
810 - @controller.stubs(:current_user).returns(user)  
811 - Person.any_instance.stubs(:follows?).returns(true)  
812 - process_delayed_job_queue  
813 -  
814 - get :index, :profile => p3.identifier  
815 - assert_equivalent [a1,a3], assigns(:network_activities)  
816 end 797 end
817 798
818 should 'the network activity be paginated' do 799 should 'the network activity be paginated' do
@@ -829,10 +810,10 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -829,10 +810,10 @@ class ProfileControllerTest &lt; ActionController::TestCase
829 end 810 end
830 811
831 should 'the network activity be visible only to logged users' do 812 should 'the network activity be visible only to logged users' do
832 - p1= fast_create(Person)  
833 - p2= fast_create(Person) 813 + p1= create_user.person
  814 + p2= create_user.person
834 assert !p1.is_a_friend?(p2) 815 assert !p1.is_a_friend?(p2)
835 - p3= fast_create(Person) 816 + p3= create_user.person
836 p3.add_friend(p1) 817 p3.add_friend(p1)
837 assert p3.is_a_friend?(p1) 818 assert p3.is_a_friend?(p1)
838 ActionTracker::Record.destroy_all 819 ActionTracker::Record.destroy_all
@@ -891,10 +872,10 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -891,10 +872,10 @@ class ProfileControllerTest &lt; ActionController::TestCase
891 end 872 end
892 873
893 should 'the self activity not crashes with user not logged in' do 874 should 'the self activity not crashes with user not logged in' do
894 - p1= fast_create(Person)  
895 - p2= fast_create(Person) 875 + p1= create_user.person
  876 + p2= create_user.person
896 assert !p1.is_a_friend?(p2) 877 assert !p1.is_a_friend?(p2)
897 - p3= fast_create(Person) 878 + p3= create_user.person
898 p3.add_friend(p1) 879 p3.add_friend(p1)
899 assert p3.is_a_friend?(p1) 880 assert p3.is_a_friend?(p1)
900 ActionTracker::Record.destroy_all 881 ActionTracker::Record.destroy_all
test/functional/profile_editor_controller_test.rb
@@ -865,7 +865,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -865,7 +865,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
865 865
866 should 'not be able to destroy enterprise if is a regular member' do 866 should 'not be able to destroy enterprise if is a regular member' do
867 enterprise = fast_create(Enterprise) 867 enterprise = fast_create(Enterprise)
868 - enterprise.add_member(fast_create(Person)) # first member is admin by default 868 + enterprise.add_member(create_user.person) # first member is admin by default
869 869
870 person = create_user('foo').person 870 person = create_user('foo').person
871 enterprise.add_member(person) 871 enterprise.add_member(person)
test/unit/application_helper_test.rb
@@ -49,6 +49,20 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -49,6 +49,20 @@ class ApplicationHelperTest &lt; ActionView::TestCase
49 end 49 end
50 end 50 end
51 51
  52 + should 'plugins path take precedence over core path' do
  53 + core_path = 'core/'
  54 + plugin_path = 'path/'
  55 + @controller = mock()
  56 + @controller.stubs(:view_paths).returns([plugin_path, core_path])
  57 + self.stubs(:params).returns({:controller => 'test'})
  58 +
  59 + File.stubs(:exists?).returns(false)
  60 + File.stubs(:exists?).with(core_path+"test/_block.html.erb").returns(true)
  61 + File.stubs(:exists?).with(plugin_path+"test/_raw_html_block.html.erb").returns(true)
  62 +
  63 + assert_equal 'raw_html_block', partial_for_class(RawHTMLBlock)
  64 + end
  65 +
52 should 'generate link to stylesheet' do 66 should 'generate link to stylesheet' do
53 File.stubs(:exists?).returns(false) 67 File.stubs(:exists?).returns(false)
54 File.expects(:exists?).with(Rails.root.join('public', 'stylesheets', 'something.css')).returns(true) 68 File.expects(:exists?).with(Rails.root.join('public', 'stylesheets', 'something.css')).returns(true)
test/unit/comment_notifier_test.rb
@@ -57,15 +57,6 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase @@ -57,15 +57,6 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
57 assert_match /comment body/, sent.body.to_s 57 assert_match /comment body/, sent.body.to_s
58 end 58 end
59 59
60 - should 'not deliver mail if has no notification emails' do  
61 - community = fast_create(Community)  
62 - assert_equal [], community.notification_emails  
63 - article = fast_create(Article, :name => 'Article test', :profile_id => community.id, :notify_comments => true)  
64 - assert_no_difference 'ActionMailer::Base.deliveries.size' do  
65 - create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'there is no addresses to send notification', :source => article)  
66 - end  
67 - end  
68 -  
69 should "deliver mail to followers" do 60 should "deliver mail to followers" do
70 author = create_user('follower_author').person 61 author = create_user('follower_author').person
71 follower = create_user('follower').person 62 follower = create_user('follower').person
test/unit/environment_test.rb
@@ -195,6 +195,12 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -195,6 +195,12 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
195 assert !env.errors[:contact_email.to_s].present? 195 assert !env.errors[:contact_email.to_s].present?
196 end 196 end
197 197
  198 + should 'notify contact email' do
  199 + env = Environment.new(:contact_email => 'foo@bar.com')
  200 + env.stubs(:admins).returns([])
  201 + assert_equal ['foo@bar.com'], env.notification_emails
  202 + end
  203 +
198 should 'provide a default hostname' do 204 should 'provide a default hostname' do
199 env = fast_create(Environment) 205 env = fast_create(Environment)
200 env.domains << create(Domain, :name => 'example.com', :is_default => true) 206 env.domains << create(Domain, :name => 'example.com', :is_default => true)
test/unit/feed_reader_block_test.rb
@@ -53,7 +53,7 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase @@ -53,7 +53,7 @@ class FeedReaderBlockTest &lt; ActiveSupport::TestCase
53 end 53 end
54 54
55 should 'display last fetched date' do 55 should 'display last fetched date' do
56 - now = Time.now 56 + now = Time.new(2014,1,1)
57 feed.feed_items = ['one', 'two'] 57 feed.feed_items = ['one', 'two']
58 feed.fetched_at = now 58 feed.fetched_at = now
59 assert_equal "Updated: #{show_date(now)}", feed.footer 59 assert_equal "Updated: #{show_date(now)}", feed.footer
test/unit/organization_test.rb
@@ -123,9 +123,9 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -123,9 +123,9 @@ class OrganizationTest &lt; ActiveSupport::TestCase
123 assert_equal ['admin1@email.com', 'admin2@email.com'], o.notification_emails 123 assert_equal ['admin1@email.com', 'admin2@email.com'], o.notification_emails
124 end 124 end
125 125
126 - should 'return empty array if contact_email is a blank string and it has no admin' do 126 + should 'use the environment contact email if no emails are listed here' do
127 o = build(Organization, :contact_email => '', :environment => Environment.default) 127 o = build(Organization, :contact_email => '', :environment => Environment.default)
128 - assert_equal [], o.notification_emails 128 + assert_equal [o.environment.contact_email], o.notification_emails
129 end 129 end
130 130
131 should 'list pending enterprise validations' do 131 should 'list pending enterprise validations' do
test/unit/person_test.rb
@@ -1198,8 +1198,8 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1198,8 +1198,8 @@ class PersonTest &lt; ActiveSupport::TestCase
1198 1198
1199 should 'return tracked_actions and scraps as activities' do 1199 should 'return tracked_actions and scraps as activities' do
1200 ActionTracker::Record.destroy_all 1200 ActionTracker::Record.destroy_all
1201 - person = fast_create(Person)  
1202 - another_person = fast_create(Person) 1201 + person = create_user.person
  1202 + another_person = create_user.person
1203 1203
1204 UserStampSweeper.any_instance.stubs(:current_user).returns(another_person) 1204 UserStampSweeper.any_instance.stubs(:current_user).returns(another_person)
1205 scrap = create(Scrap, defaults_for_scrap(:sender => another_person, :receiver => person, :content => 'A scrap')) 1205 scrap = create(Scrap, defaults_for_scrap(:sender => another_person, :receiver => person, :content => 'A scrap'))
test/unit/scrap_notifier_test.rb
@@ -57,10 +57,10 @@ class ScrapNotifierTest &lt; ActiveSupport::TestCase @@ -57,10 +57,10 @@ class ScrapNotifierTest &lt; ActiveSupport::TestCase
57 57
58 should 'not deliver mail if is a reply on a community' do 58 should 'not deliver mail if is a reply on a community' do
59 community = fast_create(Community) 59 community = fast_create(Community)
60 - person = fast_create(Person) 60 + person = create_user.person
61 scrap = fast_create(Scrap, :receiver_id => community.id, :sender_id => @sender.id) 61 scrap = fast_create(Scrap, :receiver_id => community.id, :sender_id => @sender.id)
62 assert_no_difference 'ActionMailer::Base.deliveries.size' do 62 assert_no_difference 'ActionMailer::Base.deliveries.size' do
63 - Scrap.create!(:sender_id => person, :receiver_id => @sender.id, :scrap_id => scrap.id, :content => 'Hi myself!') 63 + Scrap.create!(:sender_id => person.id, :receiver_id => @sender.id, :scrap_id => scrap.id, :content => 'Hi myself!')
64 end 64 end
65 end 65 end
66 66
test/unit/scrap_test.rb
@@ -42,7 +42,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -42,7 +42,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
42 end 42 end
43 43
44 should "be associated to Person as sender" do 44 should "be associated to Person as sender" do
45 - person = fast_create(Person) 45 + person = create_user.person
46 s = Scrap.new 46 s = Scrap.new
47 assert_nothing_raised do 47 assert_nothing_raised do
48 s.sender = person 48 s.sender = person
@@ -50,7 +50,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -50,7 +50,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
50 end 50 end
51 51
52 should "be associated to Person as receiver" do 52 should "be associated to Person as receiver" do
53 - person = fast_create(Person) 53 + person = create_user.person
54 s = Scrap.new 54 s = Scrap.new
55 assert_nothing_raised do 55 assert_nothing_raised do
56 s.receiver = person 56 s.receiver = person
@@ -66,7 +66,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -66,7 +66,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
66 end 66 end
67 67
68 should "collect all scraps sent and received of a person" do 68 should "collect all scraps sent and received of a person" do
69 - person = fast_create(Person) 69 + person = create_user.person
70 s1 = fast_create(Scrap, :sender_id => person.id) 70 s1 = fast_create(Scrap, :sender_id => person.id)
71 assert_equal [s1], Scrap.all_scraps(person) 71 assert_equal [s1], Scrap.all_scraps(person)
72 s2 = fast_create(Scrap, :sender_id => person.id) 72 s2 = fast_create(Scrap, :sender_id => person.id)
@@ -77,7 +77,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -77,7 +77,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
77 77
78 should "collect all scraps sent and received of a community" do 78 should "collect all scraps sent and received of a community" do
79 community = fast_create(Community) 79 community = fast_create(Community)
80 - person = fast_create(Person) 80 + person = create_user.person
81 s1 = fast_create(Scrap, :sender_id => person.id) 81 s1 = fast_create(Scrap, :sender_id => person.id)
82 assert_equal [], Scrap.all_scraps(community) 82 assert_equal [], Scrap.all_scraps(community)
83 s2 = fast_create(Scrap, :receiver_id => community.id, :sender_id => person.id) 83 s2 = fast_create(Scrap, :receiver_id => community.id, :sender_id => person.id)
@@ -87,8 +87,8 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -87,8 +87,8 @@ class ScrapTest &lt; ActiveSupport::TestCase
87 end 87 end
88 88
89 should "create the leave_scrap action tracker verb on scrap creation of one user to another" do 89 should "create the leave_scrap action tracker verb on scrap creation of one user to another" do
90 - p1 = fast_create(Person)  
91 - p2 = fast_create(Person) 90 + p1 = create_user.person
  91 + p2 = create_user.person
92 s = Scrap.new 92 s = Scrap.new
93 s.sender= p1 93 s.sender= p1
94 s.receiver= p2 94 s.receiver= p2
@@ -104,7 +104,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -104,7 +104,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
104 end 104 end
105 105
106 should "create the leave_scrap action tracker verb on scrap creation of one user to community" do 106 should "create the leave_scrap action tracker verb on scrap creation of one user to community" do
107 - p = fast_create(Person) 107 + p = create_user.person
108 c = fast_create(Community) 108 c = fast_create(Community)
109 s = Scrap.new 109 s = Scrap.new
110 s.sender= p 110 s.sender= p
@@ -122,8 +122,8 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -122,8 +122,8 @@ class ScrapTest &lt; ActiveSupport::TestCase
122 end 122 end
123 123
124 should "notify leave_scrap action tracker verb to friends and itself" do 124 should "notify leave_scrap action tracker verb to friends and itself" do
125 - p1 = fast_create(Person)  
126 - p2 = fast_create(Person) 125 + p1 = create_user.person
  126 + p2 = create_user.person
127 p1.add_friend(p2) 127 p1.add_friend(p2)
128 ActionTrackerNotification.delete_all 128 ActionTrackerNotification.delete_all
129 Delayed::Job.delete_all 129 Delayed::Job.delete_all
@@ -140,7 +140,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -140,7 +140,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
140 end 140 end
141 141
142 should "notify leave_scrap action tracker verb to members of the communities and the community itself" do 142 should "notify leave_scrap action tracker verb to members of the communities and the community itself" do
143 - p = fast_create(Person) 143 + p = create_user.person
144 c = fast_create(Community) 144 c = fast_create(Community)
145 c.add_member(p) 145 c.add_member(p)
146 ActionTrackerNotification.delete_all 146 ActionTrackerNotification.delete_all
@@ -158,7 +158,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -158,7 +158,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
158 end 158 end
159 159
160 should "create the leave_scrap_to_self action tracker verb on scrap creation of one user to itself" do 160 should "create the leave_scrap_to_self action tracker verb on scrap creation of one user to itself" do
161 - p = fast_create(Person) 161 + p = create_user.person
162 s = Scrap.new 162 s = Scrap.new
163 s.sender= p 163 s.sender= p
164 s.receiver= p 164 s.receiver= p
@@ -172,8 +172,8 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -172,8 +172,8 @@ class ScrapTest &lt; ActiveSupport::TestCase
172 end 172 end
173 173
174 should "notify leave_scrap_to_self action tracker verb to friends and itself" do 174 should "notify leave_scrap_to_self action tracker verb to friends and itself" do
175 - p1 = fast_create(Person)  
176 - p2 = fast_create(Person) 175 + p1 = create_user.person
  176 + p2 = create_user.person
177 p1.add_friend(p2) 177 p1.add_friend(p2)
178 ActionTrackerNotification.delete_all 178 ActionTrackerNotification.delete_all
179 Delayed::Job.delete_all 179 Delayed::Job.delete_all
@@ -216,7 +216,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -216,7 +216,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
216 end 216 end
217 217
218 should "update the scrap on reply creation" do 218 should "update the scrap on reply creation" do
219 - person = fast_create(Person) 219 + person = create_user.person
220 s = fast_create(Scrap, :updated_at => DateTime.parse('2010-01-01')) 220 s = fast_create(Scrap, :updated_at => DateTime.parse('2010-01-01'))
221 assert_equal DateTime.parse('2010-01-01'), s.updated_at.strftime('%Y-%m-%d') 221 assert_equal DateTime.parse('2010-01-01'), s.updated_at.strftime('%Y-%m-%d')
222 DateTime.stubs(:now).returns(DateTime.parse('2010-09-07')) 222 DateTime.stubs(:now).returns(DateTime.parse('2010-09-07'))
@@ -242,20 +242,20 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -242,20 +242,20 @@ class ScrapTest &lt; ActiveSupport::TestCase
242 end 242 end
243 243
244 should 'strip all html tags' do 244 should 'strip all html tags' do
245 - s, r = fast_create(Person), fast_create(Person) 245 + s, r = create_user.person, create_user.person
246 s = build Scrap, :sender => s, :receiver => r, :content => "<p>Test <b>Rails</b></p>" 246 s = build Scrap, :sender => s, :receiver => r, :content => "<p>Test <b>Rails</b></p>"
247 assert_equal "Test Rails", s.strip_all_html_tags 247 assert_equal "Test Rails", s.strip_all_html_tags
248 end 248 end
249 249
250 should 'strip html before save' do 250 should 'strip html before save' do
251 - s, r = fast_create(Person), fast_create(Person) 251 + s, r = create_user.person, create_user.person
252 s = build Scrap, :sender => s, :receiver => r, :content => "<p>Test <b>Rails</b></p>" 252 s = build Scrap, :sender => s, :receiver => r, :content => "<p>Test <b>Rails</b></p>"
253 s.save! 253 s.save!
254 assert_equal "Test Rails", s.reload.content 254 assert_equal "Test Rails", s.reload.content
255 end 255 end
256 256
257 should 'strip html before validate' do 257 should 'strip html before validate' do
258 - s, r = fast_create(Person), fast_create(Person) 258 + s, r = create_user.person, create_user.person
259 s = build Scrap, :sender => s, :receiver => r, :content => "<p><b></b></p>" 259 s = build Scrap, :sender => s, :receiver => r, :content => "<p><b></b></p>"
260 assert !s.valid? 260 assert !s.valid?
261 s.content = "<p>Test</p>" 261 s.content = "<p>Test</p>"
@@ -272,7 +272,7 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -272,7 +272,7 @@ class ScrapTest &lt; ActiveSupport::TestCase
272 end 272 end
273 273
274 should 'scrap wall url be the root scrap receiver url if it is a reply' do 274 should 'scrap wall url be the root scrap receiver url if it is a reply' do
275 - p1, p2 = fast_create(Person), fast_create(Person) 275 + p1, p2 = create_user.person, create_user.person
276 r = create Scrap, :sender => p1, :receiver => p2, :content => "Hello!" 276 r = create Scrap, :sender => p1, :receiver => p2, :content => "Hello!"
277 s = build Scrap, :sender => p2, :receiver => p1, :content => "Hi!" 277 s = build Scrap, :sender => p2, :receiver => p1, :content => "Hi!"
278 r.replies << s; s.reload 278 r.replies << s; s.reload
@@ -280,13 +280,13 @@ class ScrapTest &lt; ActiveSupport::TestCase @@ -280,13 +280,13 @@ class ScrapTest &lt; ActiveSupport::TestCase
280 end 280 end
281 281
282 should 'scrap wall url be the scrap receiver url if it is not a reply' do 282 should 'scrap wall url be the scrap receiver url if it is not a reply' do
283 - p1, p2 = fast_create(Person), fast_create(Person) 283 + p1, p2 = create_user.person, create_user.person
284 s = create Scrap, :sender => p1, :receiver => p2, :content => "Hello!" 284 s = create Scrap, :sender => p1, :receiver => p2, :content => "Hello!"
285 assert_equal s.scrap_wall_url, s.receiver.wall_url 285 assert_equal s.scrap_wall_url, s.receiver.wall_url
286 end 286 end
287 287
288 should 'create activity with reply_scrap_on_self when top_root scrap receiver is the same as sender' do 288 should 'create activity with reply_scrap_on_self when top_root scrap receiver is the same as sender' do
289 - s, r = fast_create(Person), fast_create(Person) 289 + s, r = create_user.person, create_user.person
290 root = fast_create(Scrap, :sender_id => s.id, :receiver_id => r.id) 290 root = fast_create(Scrap, :sender_id => s.id, :receiver_id => r.id)
291 assert_difference 'ActionTracker::Record.count', 1 do 291 assert_difference 'ActionTracker::Record.count', 1 do
292 reply = create(Scrap, :sender => r, :receiver => s, :scrap_id => root.id, :content => 'sample') 292 reply = create(Scrap, :sender => r, :receiver => s, :scrap_id => root.id, :content => 'sample')