Commit ddb644699b03fa44d64db803cf72abf8c0759883

Authored by Rodrigo Souto
2 parents 18ea9ebe 8f4b2c3d

Merge branch 'stable'

Showing 43 changed files with 799 additions and 592 deletions   Show diff stats
AUTHORS
... ... @@ -6,6 +6,7 @@ noosfero, that's not a problem).
6 6 Developers
7 7 ==========
8 8  
  9 +Alan Freihof Tygel <alantygel@gmail.com>
9 10 Alessandro Palmeira <alessandro.palmeira@gmail.com>
10 11 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
11 12 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
... ...
app/models/approve_article.rb
... ... @@ -48,7 +48,7 @@ class ApproveArticle &lt; Task
48 48 end
49 49  
50 50 def perform
51   - article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.author.id)
  51 + article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.author_id)
52 52 end
53 53  
54 54 def title
... ...
app/models/article.rb
... ... @@ -562,6 +562,10 @@ class Article &lt; ActiveRecord::Base
562 562 author ? author.url : nil
563 563 end
564 564  
  565 + def author_id
  566 + author ? author.id : nil
  567 + end
  568 +
565 569 alias :active_record_cache_key :cache_key
566 570 def cache_key(params = {}, the_profile = nil, language = 'en')
567 571 active_record_cache_key+'-'+language +
... ...
app/models/comment.rb
... ... @@ -74,6 +74,10 @@ class Comment &lt; ActiveRecord::Base
74 74 self.find(:all, :order => 'created_at desc, id desc', :limit => limit)
75 75 end
76 76  
  77 + def notification_emails
  78 + self.article.profile.notification_emails - [self.author_email || self.email]
  79 + end
  80 +
77 81 after_save :notify_article
78 82 after_destroy :notify_article
79 83 def notify_article
... ... @@ -114,7 +118,7 @@ class Comment &lt; ActiveRecord::Base
114 118  
115 119 def notify_by_mail
116 120 if source.kind_of?(Article) && article.notify_comments?
117   - if !article.profile.notification_emails.empty?
  121 + if !notification_emails.empty?
118 122 Comment::Notifier.deliver_mail(self)
119 123 end
120 124 emails = article.followers - [author_email]
... ... @@ -174,7 +178,7 @@ class Comment &lt; ActiveRecord::Base
174 178 class Notifier < ActionMailer::Base
175 179 def mail(comment)
176 180 profile = comment.article.profile
177   - recipients profile.notification_emails
  181 + recipients comment.notification_emails
178 182 from "#{profile.environment.name} <#{profile.environment.contact_email}>"
179 183 subject _("[%s] you got a new comment!") % [profile.environment.name]
180 184 body :recipient => profile.nickname || profile.name,
... ...
app/models/environment.rb
... ... @@ -234,7 +234,8 @@ class Environment &lt; ActiveRecord::Base
234 234 end
235 235  
236 236 settings_items :activation_blocked_text, :type => String
237   - settings_items :message_for_disabled_enterprise, :type => String
  237 + settings_items :message_for_disabled_enterprise, :type => String,
  238 + :default => _('This enterprise needs to be enabled.')
238 239 settings_items :location, :type => String
239 240 settings_items :layout_template, :type => String, :default => 'default'
240 241 settings_items :homepage, :type => String
... ...
app/models/profile.rb
... ... @@ -463,6 +463,10 @@ class Profile &lt; ActiveRecord::Base
463 463 { :profile => identifier, :controller => 'profile_editor', :action => 'index' }
464 464 end
465 465  
  466 + def tasks_url
  467 + { :profile => identifier, :controller => 'tasks', :action => 'index', :host => default_hostname }
  468 + end
  469 +
466 470 def leave_url(reload = false)
467 471 { :profile => identifier, :controller => 'profile', :action => 'leave', :reload => reload }
468 472 end
... ...
app/models/task_mailer.rb
... ... @@ -14,7 +14,7 @@ class TaskMailer &lt; ActionMailer::Base
14 14  
15 15 recipients task.target.notification_emails
16 16  
17   - url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.url.merge(:controller => 'tasks', :action => 'index'))
  17 + url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url)
18 18  
19 19 from self.class.generate_from(task)
20 20 subject '[%s] %s' % [task.environment.name, task.target_notification_description]
... ...
app/models/user.rb
... ... @@ -31,7 +31,7 @@ class User &lt; ActiveRecord::Base
31 31 after_create do |user|
32 32 user.person ||= Person.new
33 33 user.person.attributes = user.person_data.merge(:identifier => user.login, :user => user, :environment_id => user.environment_id)
34   - user.person.name ||= user.login
  34 + user.person.name ||= user.name
35 35 user.person.visible = false unless user.activated?
36 36 user.person.save!
37 37 if user.environment.enabled?('skip_new_user_email_confirmation')
... ...
db/migrate/20130111232201_aggressive_indexing_strategy3.rb 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +class AggressiveIndexingStrategy3 < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :articles, :slug
  4 + add_index :articles, :parent_id
  5 + add_index :articles, :profile_id
  6 + add_index :articles, :name
  7 +
  8 + add_index :article_versions, :article_id
  9 +
  10 + add_index :comments, [:source_id, :spam]
  11 +
  12 + add_index :profiles, :identifier
  13 +
  14 + add_index :friendships, :person_id
  15 + add_index :friendships, :friend_id
  16 + add_index :friendships, [:person_id, :friend_id], :uniq => true
  17 +
  18 + add_index :external_feeds, :blog_id
  19 + end
  20 +
  21 + def self.down
  22 + remove_index :articles, :slug
  23 + remove_index :articles, :parent_id
  24 + remove_index :articles, :profile_id
  25 + remove_index :articles, :name
  26 +
  27 + remove_index :article_versions, :article_id
  28 +
  29 + remove_index :comments, [:source_id, :spam]
  30 +
  31 + remove_index :profiles, :identifier
  32 +
  33 + remove_index :friendships, :person_id
  34 + remove_index :friendships, :friend_id
  35 + remove_index :friendships, [:person_id, :friend_id]
  36 +
  37 + remove_index :external_feeds, :blog_id
  38 + end
  39 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20121008185303) do
  12 +ActiveRecord::Schema.define(:version => 20130111232201) do
13 13  
14 14 create_table "abuse_reports", :force => true do |t|
15 15 t.integer "reporter_id"
... ... @@ -88,6 +88,8 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
88 88 t.integer "license_id"
89 89 end
90 90  
  91 + add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id"
  92 +
91 93 create_table "articles", :force => true do |t|
92 94 t.string "name"
93 95 t.string "slug"
... ... @@ -129,6 +131,10 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
129 131 t.integer "license_id"
130 132 end
131 133  
  134 + add_index "articles", ["name"], :name => "index_articles_on_name"
  135 + add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id"
  136 + add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id"
  137 + add_index "articles", ["slug"], :name => "index_articles_on_slug"
132 138 add_index "articles", ["translation_of_id"], :name => "index_articles_on_translation_of_id"
133 139  
134 140 create_table "articles_categories", :id => false, :force => true do |t|
... ... @@ -217,6 +223,8 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
217 223 t.string "referrer"
218 224 end
219 225  
  226 + add_index "comments", ["source_id", "spam"], :name => "index_comments_on_source_id_and_spam"
  227 +
220 228 create_table "contact_lists", :force => true do |t|
221 229 t.text "list"
222 230 t.string "error_fetching"
... ... @@ -280,6 +288,7 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
280 288 t.integer "update_errors", :default => 0
281 289 end
282 290  
  291 + add_index "external_feeds", ["blog_id"], :name => "index_external_feeds_on_blog_id"
283 292 add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled"
284 293 add_index "external_feeds", ["fetched_at"], :name => "index_external_feeds_on_fetched_at"
285 294  
... ... @@ -295,6 +304,10 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
295 304 t.string "group"
296 305 end
297 306  
  307 + add_index "friendships", ["friend_id"], :name => "index_friendships_on_friend_id"
  308 + add_index "friendships", ["person_id", "friend_id"], :name => "index_friendships_on_person_id_and_friend_id"
  309 + add_index "friendships", ["person_id"], :name => "index_friendships_on_person_id"
  310 +
298 311 create_table "images", :force => true do |t|
299 312 t.integer "parent_id"
300 313 t.string "content_type"
... ... @@ -446,6 +459,7 @@ ActiveRecord::Schema.define(:version =&gt; 20121008185303) do
446 459 end
447 460  
448 461 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
  462 + add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier"
449 463 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id"
450 464  
451 465 create_table "qualifier_certifiers", :force => true do |t|
... ...
debian/changelog
  1 +noosfero (0.39.2) unstable; urgency=low
  2 +
  3 + * Bugfixes release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Sat, 12 Jan 2013 10:13:46 +0000
  6 +
1 7 noosfero (0.39.1) unstable; urgency=low
2 8  
3 9 * Bugfixes release
... ...
etc/noosfero/varnish-noosfero.vcl
1 1 sub vcl_recv {
2 2 if (req.request == "GET" || req.request == "HEAD") {
3 3 if (req.http.Cookie) {
4   - # We only care about the "_noosfero_session.*" cookie, used for
5   - # authentication.
6   - if (req.http.Cookie !~ "_noosfero_session.*" ) {
  4 + # We only care about the "_noosfero_.*" cookies, used by Noosfero
  5 + if (req.http.Cookie !~ "_noosfero_.*" ) {
7 6 # strip all cookies
8 7 unset req.http.Cookie;
9 8 }
... ...
gitignore.example
... ... @@ -21,8 +21,8 @@ public/user_themes
21 21 public/designs/themes/default
22 22 public/designs/themes/*
23 23 public/designs/icons/default
24   -public/javascripts/cache*.js
25   -public/stylesheets/cache*.css
  24 +public/javascripts/cache*
  25 +public/stylesheets/cache*
26 26 public/plugins
27 27 db/development.db
28 28 db/production.db
... ...
lib/noosfero.rb
... ... @@ -2,7 +2,7 @@ require &#39;fast_gettext&#39;
2 2  
3 3 module Noosfero
4 4 PROJECT = 'noosfero'
5   - VERSION = '0.39.1'
  5 + VERSION = '0.39.2'
6 6  
7 7 def self.pattern_for_controllers_in_directory(dir)
8 8 disjunction = controllers_in_directory(dir).join('|')
... ...
plugins/shopping_cart/controllers/shopping_cart_plugin_controller.rb 0 → 100644
... ... @@ -0,0 +1,296 @@
  1 +require 'base64'
  2 +
  3 +class ShoppingCartPluginController < PublicController
  4 +
  5 + include ShoppingCartPlugin::CartHelper
  6 + helper ShoppingCartPlugin::CartHelper
  7 +
  8 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  9 + before_filter :login_required, :only => []
  10 +
  11 + before_filter :login_required, :only => []
  12 +
  13 + def get
  14 + config =
  15 + if cart.nil?
  16 + { 'enterprise_id' => nil, 'hasProducts' => false }
  17 + else
  18 + { 'enterprise_id' => cart[:enterprise_id], 'hasProducts' => (cart[:items].keys.size > 0) }
  19 + end
  20 + render :text => config.to_json
  21 + end
  22 +
  23 + def add
  24 + product = find_product(params[:id])
  25 + if product && enterprise = validate_same_enterprise(product)
  26 + self.cart = { :enterprise_id => enterprise.id, :items => {} } if self.cart.nil?
  27 + self.cart[:items][product.id] = 0 if self.cart[:items][product.id].nil?
  28 + self.cart[:items][product.id] += 1
  29 + render :text => {
  30 + :ok => true,
  31 + :error => {:code => 0},
  32 + :products => [{
  33 + :id => product.id,
  34 + :name => product.name,
  35 + :price => get_price(product, enterprise.environment),
  36 + :description => product.description,
  37 + :picture => product.default_image(:minor),
  38 + :quantity => self.cart[:items][product.id]
  39 + }]
  40 + }.to_json
  41 + end
  42 + end
  43 +
  44 + def remove
  45 + id = params[:id].to_i
  46 + if validate_cart_presence && validate_cart_has_product(id)
  47 + self.cart[:items].delete(id)
  48 + self.cart = nil if self.cart[:items].empty?
  49 + render :text => {
  50 + :ok => true,
  51 + :error => {:code => 0},
  52 + :product_id => id
  53 + }.to_json
  54 + end
  55 + end
  56 +
  57 + def list
  58 + if validate_cart_presence
  59 + products = self.cart[:items].collect do |id, quantity|
  60 + product = Product.find(id)
  61 + { :id => product.id,
  62 + :name => product.name,
  63 + :price => get_price(product, product.enterprise.environment),
  64 + :description => product.description,
  65 + :picture => product.default_image(:minor),
  66 + :quantity => quantity
  67 + }
  68 + end
  69 + render :text => {
  70 + :ok => true,
  71 + :error => {:code => 0},
  72 + :products => products
  73 + }.to_json
  74 + end
  75 + end
  76 +
  77 + def update_quantity
  78 + quantity = params[:quantity].to_i
  79 + id = params[:id].to_i
  80 + if validate_cart_presence && validate_cart_has_product(id) && validate_item_quantity(quantity)
  81 + product = Product.find(id)
  82 + self.cart[:items][product.id] = quantity
  83 + render :text => {
  84 + :ok => true,
  85 + :error => {:code => 0},
  86 + :product_id => id,
  87 + :quantity => quantity
  88 + }.to_json
  89 + end
  90 + end
  91 +
  92 + def clean
  93 + self.cart = nil
  94 + render :text => {
  95 + :ok => true,
  96 + :error => {:code => 0}
  97 + }.to_json
  98 + end
  99 +
  100 + def buy
  101 + @cart = cart
  102 + @enterprise = environment.enterprises.find(cart[:enterprise_id])
  103 + render :layout => false
  104 + end
  105 +
  106 + def send_request
  107 + register_order(params[:customer], self.cart[:items])
  108 + begin
  109 + enterprise = Enterprise.find(cart[:enterprise_id])
  110 + ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], enterprise, self.cart[:items])
  111 + ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], enterprise, self.cart[:items])
  112 + self.cart = nil
  113 + render :text => {
  114 + :ok => true,
  115 + :message => _('Request sent successfully. Check your email.'),
  116 + :error => {:code => 0}
  117 + }.to_json
  118 + rescue ActiveRecord::ActiveRecordError
  119 + render :text => {
  120 + :ok => false,
  121 + :error => {
  122 + :code => 6,
  123 + :message => exception.message
  124 + }
  125 + }.to_json
  126 + end
  127 + end
  128 +
  129 + def visibility
  130 + render :text => self.cart.has_key?(:visibility) ? self.cart[:visibility].to_json : true.to_json
  131 + end
  132 +
  133 + def show
  134 + begin
  135 + self.cart[:visibility] = true
  136 + render :text => {
  137 + :ok => true,
  138 + :message => _('Basket displayed.'),
  139 + :error => {:code => 0}
  140 + }.to_json
  141 + rescue Exception => exception
  142 + render :text => {
  143 + :ok => false,
  144 + :error => {
  145 + :code => 7,
  146 + :message => exception.message
  147 + }
  148 + }.to_json
  149 + end
  150 + end
  151 +
  152 + def hide
  153 + begin
  154 + self.cart[:visibility] = false
  155 + render :text => {
  156 + :ok => true,
  157 + :message => _('Basket hidden.'),
  158 + :error => {:code => 0}
  159 + }.to_json
  160 + rescue Exception => exception
  161 + render :text => {
  162 + :ok => false,
  163 + :error => {
  164 + :code => 8,
  165 + :message => exception.message
  166 + }
  167 + }.to_json
  168 + end
  169 + end
  170 +
  171 + private
  172 +
  173 + def validate_same_enterprise(product)
  174 + if self.cart && self.cart[:enterprise_id] && product.enterprise_id != self.cart[:enterprise_id]
  175 + render :text => {
  176 + :ok => false,
  177 + :error => {
  178 + :code => 1,
  179 + :message => _("Can't join items from different enterprises.")
  180 + }
  181 + }.to_json
  182 + return nil
  183 + end
  184 + product.enterprise
  185 + end
  186 +
  187 + def validate_cart_presence
  188 + if self.cart.nil?
  189 + render :text => {
  190 + :ok => false,
  191 + :error => {
  192 + :code => 2,
  193 + :message => _("There is no basket.")
  194 + }
  195 + }.to_json
  196 + return false
  197 + end
  198 + true
  199 + end
  200 +
  201 + def find_product(id)
  202 + begin
  203 + product = Product.find(id)
  204 + rescue ActiveRecord::RecordNotFound
  205 + render :text => {
  206 + :ok => false,
  207 + :error => {
  208 + :code => 3,
  209 + :message => _("This enterprise doesn't have this product.")
  210 + }
  211 + }.to_json
  212 + return nil
  213 + end
  214 + product
  215 + end
  216 +
  217 + def validate_cart_has_product(id)
  218 + if !self.cart[:items].has_key?(id)
  219 + render :text => {
  220 + :ok => false,
  221 + :error => {
  222 + :code => 4,
  223 + :message => _("The basket doesn't have this product.")
  224 + }
  225 + }.to_json
  226 + return false
  227 + end
  228 + true
  229 + end
  230 +
  231 + def validate_item_quantity(quantity)
  232 + if quantity.to_i < 1
  233 + render :text => {
  234 + :ok => false,
  235 + :error => {
  236 + :code => 5,
  237 + :message => _("Invalid quantity.")
  238 + }
  239 + }.to_json
  240 + return false
  241 + end
  242 + true
  243 + end
  244 +
  245 + def register_order(custumer, items)
  246 + new_items = {}
  247 + items.each do |id, quantity|
  248 + product = Product.find(id)
  249 + price = product.price || 0
  250 + new_items[id] = {:quantity => quantity, :price => price, :name => product.name}
  251 + end
  252 + ShoppingCartPlugin::PurchaseOrder.create!(
  253 + :seller => Enterprise.find(cart[:enterprise_id]),
  254 + :customer => user,
  255 + :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED,
  256 + :products_list => new_items,
  257 + :customer_name => params[:customer][:name],
  258 + :customer_email => params[:customer][:email],
  259 + :customer_contact_phone => params[:customer][:contact_phone],
  260 + :customer_address => params[:customer][:address],
  261 + :customer_city => params[:customer][:city],
  262 + :customer_zip_code => params[:customer][:zip_code]
  263 + )
  264 + end
  265 +
  266 + protected
  267 +
  268 + def cart
  269 + @cart ||=
  270 + begin
  271 + cookies[cookie_key] && YAML.load(Base64.decode64(cookies[cookie_key])) || nil
  272 + end
  273 + @cart
  274 + end
  275 +
  276 + def cart=(data)
  277 + @cart = data
  278 + end
  279 +
  280 + after_filter :save_cookie
  281 + def save_cookie
  282 + if @cart.nil?
  283 + cookies.delete(cookie_key, :path => '/plugin/shopping_cart')
  284 + else
  285 + cookies[cookie_key] = {
  286 + :value => Base64.encode64(@cart.to_yaml),
  287 + :path => "/plugin/shopping_cart"
  288 + }
  289 + end
  290 + end
  291 +
  292 + def cookie_key
  293 + :_noosfero_plugin_shopping_cart
  294 + end
  295 +
  296 +end
... ...
plugins/shopping_cart/controllers/shopping_cart_plugin_profile_controller.rb
... ... @@ -1,248 +0,0 @@
1   -include ShoppingCartPlugin::CartHelper
2   -
3   -class ShoppingCartPluginProfileController < ProfileController
4   - append_view_path File.join(File.dirname(__FILE__) + '/../views')
5   - before_filter :login_required, :only => []
6   -
7   - before_filter :login_required, :only => []
8   -
9   - def add
10   - session[:cart] = { :enterprise_id => profile.id, :items => {} } if session[:cart].nil?
11   - if validate_same_enterprise && product = validate_enterprise_has_product(params[:id])
12   - session[:cart][:items][product.id] = 0 if session[:cart][:items][product.id].nil?
13   - session[:cart][:items][product.id] += 1
14   - render :text => {
15   - :ok => true,
16   - :error => {:code => 0},
17   - :products => [{
18   - :id => product.id,
19   - :name => product.name,
20   - :price => get_price(product, profile.environment),
21   - :description => product.description,
22   - :picture => product.default_image(:minor),
23   - :quantity => session[:cart][:items][product.id]
24   - }]
25   - }.to_json
26   - end
27   - end
28   -
29   - def remove
30   - id = params[:id].to_i
31   - if validate_cart_presence && validate_cart_has_product(id)
32   - session[:cart][:items].delete(id)
33   - session[:cart] = nil if session[:cart][:items].empty?
34   - render :text => {
35   - :ok => true,
36   - :error => {:code => 0},
37   - :product_id => id
38   - }.to_json
39   - end
40   - end
41   -
42   - def list
43   - if validate_cart_presence
44   - products = session[:cart][:items].collect do |id, quantity|
45   - product = Product.find(id)
46   - { :id => product.id,
47   - :name => product.name,
48   - :price => get_price(product, profile.environment),
49   - :description => product.description,
50   - :picture => product.default_image(:minor),
51   - :quantity => quantity
52   - }
53   - end
54   - render :text => {
55   - :ok => true,
56   - :error => {:code => 0},
57   - :enterprise => Enterprise.find(session[:cart][:enterprise_id]).identifier,
58   - :products => products
59   - }.to_json
60   - end
61   - end
62   -
63   - def update_quantity
64   - quantity = params[:quantity].to_i
65   - id = params[:id].to_i
66   - if validate_cart_presence && validate_cart_has_product(id) && validate_item_quantity(quantity)
67   - product = Product.find(id)
68   - session[:cart][:items][product.id] = quantity
69   - render :text => {
70   - :ok => true,
71   - :error => {:code => 0},
72   - :product_id => id,
73   - :quantity => quantity
74   - }.to_json
75   - end
76   - end
77   -
78   - def clean
79   - session[:cart] = nil
80   - render :text => {
81   - :ok => true,
82   - :error => {:code => 0}
83   - }.to_json
84   - end
85   -
86   - def buy
87   - @environment = profile.environment
88   - render :layout => false
89   - end
90   -
91   - def send_request
92   - register_order(params[:customer], session[:cart][:items])
93   - begin
94   - ShoppingCartPlugin::Mailer.deliver_customer_notification(params[:customer], profile, session[:cart][:items])
95   - ShoppingCartPlugin::Mailer.deliver_supplier_notification(params[:customer], profile, session[:cart][:items])
96   - render :text => {
97   - :ok => true,
98   - :message => _('Request sent successfully. Check your email.'),
99   - :error => {:code => 0}
100   - }.to_json
101   - rescue Exception => exception
102   - render :text => {
103   - :ok => false,
104   - :error => {
105   - :code => 6,
106   - :message => exception.message
107   - }
108   - }.to_json
109   - end
110   - end
111   -
112   - def visibility
113   - render :text => session[:cart].has_key?(:visibility) ? session[:cart][:visibility].to_json : true.to_json
114   - end
115   -
116   - def show
117   - begin
118   - session[:cart][:visibility] = true
119   - render :text => {
120   - :ok => true,
121   - :message => _('Basket displayed.'),
122   - :error => {:code => 0}
123   - }.to_json
124   - rescue Exception => exception
125   - render :text => {
126   - :ok => false,
127   - :error => {
128   - :code => 7,
129   - :message => exception.message
130   - }
131   - }.to_json
132   - end
133   - end
134   -
135   - def hide
136   - begin
137   - session[:cart][:visibility] = false
138   - render :text => {
139   - :ok => true,
140   - :message => _('Basket hidden.'),
141   - :error => {:code => 0}
142   - }.to_json
143   - rescue Exception => exception
144   - render :text => {
145   - :ok => false,
146   - :error => {
147   - :code => 8,
148   - :message => exception.message
149   - }
150   - }.to_json
151   - end
152   - end
153   -
154   - private
155   -
156   - def validate_same_enterprise
157   - if profile.id != session[:cart][:enterprise_id]
158   - render :text => {
159   - :ok => false,
160   - :error => {
161   - :code => 1,
162   - :message => _("Can't join items from different enterprises.")
163   - }
164   - }.to_json
165   - return false
166   - end
167   - true
168   - end
169   -
170   - def validate_cart_presence
171   - if session[:cart].nil?
172   - render :text => {
173   - :ok => false,
174   - :error => {
175   - :code => 2,
176   - :message => _("There is no basket.")
177   - }
178   - }.to_json
179   - return false
180   - end
181   - true
182   - end
183   -
184   - def validate_enterprise_has_product(id)
185   - begin
186   - product = profile.products.find(id)
187   - rescue
188   - render :text => {
189   - :ok => false,
190   - :error => {
191   - :code => 3,
192   - :message => _("This enterprise doesn't have this product.")
193   - }
194   - }.to_json
195   - return nil
196   - end
197   - product
198   - end
199   -
200   - def validate_cart_has_product(id)
201   - if !session[:cart][:items].has_key?(id)
202   - render :text => {
203   - :ok => false,
204   - :error => {
205   - :code => 4,
206   - :message => _("The basket doesn't have this product.")
207   - }
208   - }.to_json
209   - return false
210   - end
211   - true
212   - end
213   -
214   - def validate_item_quantity(quantity)
215   - if quantity.to_i < 1
216   - render :text => {
217   - :ok => false,
218   - :error => {
219   - :code => 5,
220   - :message => _("Invalid quantity.")
221   - }
222   - }.to_json
223   - return false
224   - end
225   - true
226   - end
227   -
228   - def register_order(custumer, items)
229   - new_items = {}
230   - items.each do |id, quantity|
231   - product = Product.find(id)
232   - price = product.price || 0
233   - new_items[id] = {:quantity => quantity, :price => price, :name => product.name}
234   - end
235   - ShoppingCartPlugin::PurchaseOrder.create!(
236   - :seller => profile,
237   - :customer => user,
238   - :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED,
239   - :products_list => new_items,
240   - :customer_name => params[:customer][:name],
241   - :customer_email => params[:customer][:email],
242   - :customer_contact_phone => params[:customer][:contact_phone],
243   - :customer_address => params[:customer][:address],
244   - :customer_city => params[:customer][:city],
245   - :customer_zip_code => params[:customer][:zip_code]
246   - )
247   - end
248   -end
plugins/shopping_cart/lib/shopping_cart_plugin.rb
... ... @@ -11,12 +11,13 @@ class ShoppingCartPlugin &lt; Noosfero::Plugin
11 11 _("A shopping basket feature for enterprises")
12 12 end
13 13  
14   - def add_to_cart_button(item, enterprise = context.profile)
  14 + def add_to_cart_button(item)
  15 + enterprise = item.enterprise
15 16 if enterprise.shopping_cart && item.available
16 17 lambda {
17 18 link_to(_('Add to basket'), "add:#{item.name}",
18 19 :class => 'cart-add-item',
19   - :onclick => "Cart.addItem('#{enterprise.identifier}', #{item.id}, this); return false"
  20 + :onclick => "Cart.addItem(#{item.id}, this); return false"
20 21 )
21 22 }
22 23 end
... ... @@ -35,7 +36,7 @@ class ShoppingCartPlugin &lt; Noosfero::Plugin
35 36 end
36 37  
37 38 def body_beginning
38   - expanded_template('cart.html.erb',{:cart => context.session[:cart]})
  39 + expanded_template('cart.html.erb')
39 40 end
40 41  
41 42 def control_panel_buttons
... ...
plugins/shopping_cart/lib/shopping_cart_plugin/cart_helper.rb
1 1 module ShoppingCartPlugin::CartHelper
2 2  
3 3 include ActionView::Helpers::NumberHelper
  4 + include ActionView::Helpers::TagHelper
4 5  
5 6 def sell_price(product)
6 7 return 0 if product.price.nil?
... ...
plugins/shopping_cart/lib/shopping_cart_plugin/mailer.rb
1 1 class ShoppingCartPlugin::Mailer < Noosfero::Plugin::MailerBase
2 2  
  3 + include ShoppingCartPlugin::CartHelper
  4 +
3 5 def customer_notification(customer, supplier, items)
4 6 domain = supplier.hostname || supplier.environment.default_hostname
5 7 recipients customer[:email]
... ... @@ -10,7 +12,8 @@ class ShoppingCartPlugin::Mailer &lt; Noosfero::Plugin::MailerBase
10 12 body :customer => customer,
11 13 :supplier => supplier,
12 14 :items => items,
13   - :environment => supplier.environment
  15 + :environment => supplier.environment,
  16 + :helper => self
14 17 end
15 18  
16 19 def supplier_notification(customer, supplier, items)
... ... @@ -23,6 +26,8 @@ class ShoppingCartPlugin::Mailer &lt; Noosfero::Plugin::MailerBase
23 26 body :customer => customer,
24 27 :supplier => supplier,
25 28 :items => items,
26   - :environment => supplier.environment
  29 + :environment => supplier.environment,
  30 + :helper => self
  31 +
27 32 end
28 33 end
... ...
plugins/shopping_cart/public/cart.js
... ... @@ -11,10 +11,9 @@ function Cart(config) {
11 11 $(".cart-buy", this.cartElem).button({ icons: { primary: 'ui-icon-cart'} });
12 12 if (!this.empty) {
13 13 $(this.cartElem).show();
14   - this.enterprise = config.enterprise;
15 14 me = this;
16 15 $.ajax({
17   - url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/visibility',
  16 + url: '/plugin/shopping_cart/visibility',
18 17 dataType: 'json',
19 18 success: function(data, status, ajax){
20 19 me.visible = /^true$/i.test(data);
... ... @@ -25,7 +24,7 @@ function Cart(config) {
25 24 alert('Visibility - HTTP '+status+': '+errorThrown);
26 25 }
27 26 });
28   - $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugin/shopping_cart/buy'});
  27 + $(".cart-buy", this.cartElem).colorbox({ href: '/plugin/shopping_cart/buy' });
29 28 }
30 29 }
31 30  
... ... @@ -34,7 +33,7 @@ function Cart(config) {
34 33 Cart.prototype.listProducts = function() {
35 34 var me = this;
36 35 $.ajax({
37   - url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/list',
  36 + url: '/plugin/shopping_cart/list',
38 37 dataType: 'json',
39 38 success: function(data, ststus, ajax){
40 39 if ( !data.ok ) alert(data.error.message);
... ... @@ -61,7 +60,7 @@ function Cart(config) {
61 60 '<span class="item-name">'+ item.name +'</span>' +
62 61 '<div class="item-price">' +
63 62 '<input size="1" value="'+item.quantity+'" />'+ (item.price ? '&times; '+ item.price : '') +'</div>' +
64   - ' <a href="remove:'+item.name+'" onclick="Cart.removeItem(\''+this.enterprise+'\', '+item.id+'); return false"' +
  63 + ' <a href="remove:'+item.name+'" onclick="Cart.removeItem('+item.id+'); return false"' +
65 64 ' class="button icon-remove"><span>remove</span></a>'
66 65 ).appendTo(li);
67 66 var input = $("input", li)[0];
... ... @@ -100,7 +99,7 @@ function Cart(config) {
100 99 var me = this;
101 100 if( quantity == NaN ) return input.value = input.lastValue;
102 101 $.ajax({
103   - url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity,
  102 + url: '/plugin/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity,
104 103 dataType: 'json',
105 104 success: function(data, status, ajax){
106 105 if ( !data.ok ) {
... ... @@ -132,8 +131,7 @@ function Cart(config) {
132 131 this.updateTotal();
133 132 }
134 133  
135   - Cart.addItem = function(enterprise, itemId, link) {
136   - // on the future, the instance may be found by the enterprise identifier.
  134 + Cart.addItem = function(itemId, link) {
137 135 link.intervalId = setInterval(function() {
138 136 steps = ['w', 'n', 'e', 's'];
139 137 if( !link.step || link.step==3 ) link.step = 0;
... ... @@ -144,18 +142,13 @@ function Cart(config) {
144 142 clearInterval(link.intervalId);
145 143 $(link).button({ icons: { primary: 'ui-icon-cart'}, disable: false });
146 144 };
147   - this.instance.addItem(enterprise, itemId, stopBtLoading);
  145 + this.instance.addItem(itemId, stopBtLoading);
148 146 }
149 147  
150   - Cart.prototype.addItem = function(enterprise, itemId, callback) {
151   - if(!this.enterprise) {
152   - this.enterprise = enterprise;
153   - $(".cart-buy", this.cartElem).colorbox({href: '/profile/' + this.enterprise + '/plugin/shopping_cart/buy'});
154   -// $(this.cartElem).show();
155   - }
  148 + Cart.prototype.addItem = function(itemId, callback) {
156 149 var me = this;
157 150 $.ajax({
158   - url: '/profile/'+ enterprise +'/plugin/shopping_cart/add/'+ itemId,
  151 + url: '/plugin/shopping_cart/add/'+ itemId,
159 152 dataType: 'json',
160 153 success: function(data, status, ajax){
161 154 if ( !data.ok ) alert(data.error.message);
... ... @@ -169,16 +162,16 @@ function Cart(config) {
169 162 });
170 163 }
171 164  
172   - Cart.removeItem = function(enterprise, itemId) {
  165 + Cart.removeItem = function(itemId) {
173 166 var message = this.instance.cartElem.getAttribute('data-l10nRemoveItem');
174   - if( confirm(message) ) this.instance.removeItem(enterprise, itemId);
  167 + if( confirm(message) ) this.instance.removeItem(itemId);
175 168 }
176 169  
177   - Cart.prototype.removeItem = function(enterprise, itemId) {
  170 + Cart.prototype.removeItem = function(itemId) {
178 171 if ($("li", this.itemsBox).size() < 2) return this.clean();
179 172 var me = this;
180 173 $.ajax({
181   - url: '/profile/'+ enterprise +'/plugin/shopping_cart/remove/'+ itemId,
  174 + url: '/plugin/shopping_cart/remove/'+ itemId,
182 175 dataType: 'json',
183 176 success: function(data, status, ajax){
184 177 if ( !data.ok ) alert(data.error.message);
... ... @@ -200,7 +193,7 @@ function Cart(config) {
200 193  
201 194 Cart.prototype.show = function() {
202 195 $.ajax({
203   - url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/show',
  196 + url: '/plugin/shopping_cart/show',
204 197 dataType: 'json',
205 198 cache: false,
206 199 error: function(ajax, status, errorThrown) {
... ... @@ -215,7 +208,7 @@ function Cart(config) {
215 208 }
216 209 Cart.prototype.hide = function() {
217 210 $.ajax({
218   - url: '/profile/'+ this.enterprise +'/plugin/shopping_cart/hide',
  211 + url: '/plugin/shopping_cart/hide',
219 212 dataType: 'json',
220 213 cache: false,
221 214 error: function(ajax, status, errorThrown) {
... ... @@ -252,7 +245,7 @@ function Cart(config) {
252 245 Cart.prototype.clean = function() {
253 246 var me = this;
254 247 $.ajax({
255   - url: '/profile/'+ me.enterprise +'/plugin/shopping_cart/clean',
  248 + url: '/plugin/shopping_cart/clean',
256 249 dataType: 'json',
257 250 success: function(data, status, ajax){
258 251 if ( !data.ok ) alert(data.error.message);
... ... @@ -261,7 +254,6 @@ function Cart(config) {
261 254 $(me.cartElem).slideUp(500, function() {
262 255 $(me.itemsBox).empty();
263 256 me.hide();
264   - me.enterprise = null;
265 257 me.updateTotal();
266 258 me.empty = true;
267 259 });
... ... @@ -284,7 +276,7 @@ function Cart(config) {
284 276 var me = this;
285 277 $.ajax({
286 278 type: 'POST',
287   - url: '/profile/'+ me.enterprise +'/plugin/shopping_cart/send_request',
  279 + url: '/plugin/shopping_cart/send_request',
288 280 data: params,
289 281 dataType: 'json',
290 282 success: function(data, status, ajax){
... ... @@ -309,7 +301,19 @@ function Cart(config) {
309 301 }
310 302  
311 303 $(function(){
312   - $('.cart-add-item').button({ icons: { primary: 'ui-icon-cart'} })
  304 +
  305 + $.ajax({
  306 + url: "/plugin/shopping_cart/get",
  307 + dataType: 'json',
  308 + success: function(data) {
  309 + new Cart(data);
  310 + $('.cart-add-item').button({ icons: { primary: 'ui-icon-cart'} })
  311 + },
  312 + cache: false,
  313 + error: function(ajax, status, errorThrown) {
  314 + alert('Error getting shopping cart - HTTP '+status+': '+errorThrown);
  315 + }
  316 + });
313 317 });
314 318  
315 319 })(jQuery);
... ...
plugins/shopping_cart/public/style.css
1   -@import url(colorbox/colorbox.css);
2   -
3 1 .cart-add-item .ui-icon-cart {
4 2 background: url("/plugins/shopping_cart/images/button-icon.png") no-repeat scroll left center transparent;
5 3 width: 22px;
... ...
plugins/shopping_cart/test/functional/shopping_cart_plugin_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,225 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/shopping_cart_plugin_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class ShoppingCartPluginController; def rescue_action(e) raise e end; end
  6 +
  7 +class ShoppingCartPluginControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @controller = ShoppingCartPluginController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 + @enterprise = fast_create(Enterprise)
  14 + @product = fast_create(Product, :enterprise_id => @enterprise.id)
  15 + end
  16 + attr_reader :enterprise
  17 + attr_reader :product
  18 +
  19 + should 'force cookie expiration with explicit path for an empty cart' do
  20 + get :get
  21 + assert @response.headers['Set-Cookie'].any? { |c| c =~ /_noosfero_plugin_shopping_cart=; path=\/plugin\/shopping_cart; expires=.*-1970/}
  22 + end
  23 +
  24 + should 'add a new product to cart' do
  25 + get :add, :id => product.id
  26 +
  27 + assert product_in_cart?(product)
  28 + assert_equal 1, product_quantity(product)
  29 + end
  30 +
  31 + should 'grow quantity through add' do
  32 + get :add, :id => product.id
  33 + assert_equal 1, product_quantity(product)
  34 +
  35 + get :add, :id => product.id
  36 + assert_equal 2, product_quantity(product)
  37 + end
  38 +
  39 + should 'not add product to cart if it does not exists' do
  40 + assert_nothing_raised { get :add, :id => 9999 }
  41 +
  42 + assert !product_in_cart?(product)
  43 + assert !response_ok?
  44 + assert 3, reponse_error_code
  45 + end
  46 +
  47 + should 'remove cart if the product being removed is the last one' do
  48 + get :add, :id => product.id
  49 + assert cart?
  50 +
  51 + get :remove, :id => product.id
  52 + assert !cart?
  53 + end
  54 +
  55 + should 'not try to remove a product if there is no cart' do
  56 + instantiate_cart
  57 + assert !cart?
  58 +
  59 + assert_nothing_raised { get :remove, :id => 9999 }
  60 + assert !response_ok?
  61 + assert_equal 2, reponse_error_code
  62 + end
  63 +
  64 + should 'just remove product if there are other products on cart' do
  65 + another_product = fast_create(Product, :enterprise_id => enterprise.id)
  66 + get :add, :id => product.id
  67 + get :add, :id => another_product.id
  68 +
  69 + get :remove, :id => product.id
  70 + assert cart?
  71 + assert !product_in_cart?(product)
  72 + end
  73 +
  74 + should 'not try to remove a product that is not in the cart' do
  75 + get :add, :id => product.id
  76 + assert cart?
  77 + assert_nothing_raised { get :remove, :id => 9999 }
  78 +
  79 + assert !response_ok?
  80 + assert_equal 4, reponse_error_code
  81 + end
  82 +
  83 + should 'not try to list the cart if there is no cart' do
  84 + instantiate_cart
  85 + assert !cart?
  86 +
  87 + assert_nothing_raised { get :list }
  88 + assert !response_ok?
  89 + assert_equal 2, reponse_error_code
  90 + end
  91 +
  92 + should 'list products without errors' do
  93 + get :add, :id => product.id
  94 +
  95 + assert_nothing_raised { get :list }
  96 + assert response_ok?
  97 + end
  98 +
  99 + should 'update the quantity of a product' do
  100 + get :add, :id => product.id
  101 + assert 1, product_quantity(product)
  102 +
  103 + get :update_quantity, :id => product.id, :quantity => 3
  104 + assert 3, product_quantity(product)
  105 + end
  106 +
  107 + should 'not try to update quantity the quantity of a product if there is no cart' do
  108 + instantiate_cart
  109 + assert !cart?
  110 +
  111 + assert_nothing_raised { get :update_quantity, :id => 9999, :quantity => 3 }
  112 + assert !response_ok?
  113 + assert_equal 2, reponse_error_code
  114 + end
  115 +
  116 + should 'not try to update the quantity of a product that is not in the cart' do
  117 + get :add, :id => product.id
  118 + assert cart?
  119 + assert_nothing_raised { get :update_quantity, :id => 9999, :quantity => 3 }
  120 +
  121 + assert !response_ok?
  122 + assert_equal 4, reponse_error_code
  123 + end
  124 +
  125 + should 'not update the quantity of a product with a invalid value' do
  126 + get :add, :id => product.id
  127 +
  128 + assert_nothing_raised { get :update_quantity, :id => product.id, :quantity => -1}
  129 + assert !response_ok?
  130 + assert_equal 5, reponse_error_code
  131 +
  132 + assert_nothing_raised { get :update_quantity, :id => product.id, :quantity => 'asdf'}
  133 + assert !response_ok?
  134 + assert_equal 5, reponse_error_code
  135 + end
  136 +
  137 + should 'clean the cart' do
  138 + another_product = fast_create(Product, :enterprise_id => enterprise.id)
  139 + get :add, :id => product.id
  140 + get :add, :id => another_product.id
  141 +
  142 + assert_nothing_raised { get :clean }
  143 + assert !cart?
  144 + end
  145 +
  146 + should 'not crash if there is no cart' do
  147 + instantiate_cart
  148 + assert !cart?
  149 + assert_nothing_raised { get :clean }
  150 + end
  151 +
  152 + should 'register order on send request' do
  153 + product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99)
  154 + product2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2.23)
  155 + @controller.stubs(:cart).returns({ :enterprise_id => enterprise.id, :items => {product1.id => 1, product2.id => 2}})
  156 + assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do
  157 + post :send_request,
  158 + :customer => {:name => "Manuel", :email => "manuel@ceu.com"}
  159 + end
  160 +
  161 + order = ShoppingCartPlugin::PurchaseOrder.last
  162 +
  163 + assert_equal 1.99, order.products_list[product1.id][:price]
  164 + assert_equal 1, order.products_list[product1.id][:quantity]
  165 + assert_equal 2.23, order.products_list[product2.id][:price]
  166 + assert_equal 2, order.products_list[product2.id][:quantity]
  167 + assert_equal ShoppingCartPlugin::PurchaseOrder::Status::OPENED, order.status
  168 + end
  169 +
  170 + should 'register order on send request and not crash if product is not defined' do
  171 + product1 = fast_create(Product, :enterprise_id => enterprise.id)
  172 + @controller.stubs(:cart).returns({ :enterprise_id => enterprise.id, :items => {product1.id => 1}})
  173 + assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do
  174 + post :send_request,
  175 + :customer => {:name => "Manuel", :email => "manuel@ceu.com"}
  176 + end
  177 +
  178 + order = ShoppingCartPlugin::PurchaseOrder.last
  179 +
  180 + assert_equal 0, order.products_list[product1.id][:price]
  181 + end
  182 +
  183 + should 'clean the cart after placing the order' do
  184 + product1 = fast_create(Product, :enterprise_id => enterprise.id)
  185 + post :add, :id => product1.id
  186 + post :send_request, :customer => { :name => "Manuel", :email => "manuel@ceu.com" }
  187 + assert !cart?, "cart expected to be empty!"
  188 + end
  189 +
  190 + private
  191 +
  192 + def json_response
  193 + ActiveSupport::JSON.decode @response.body
  194 + end
  195 +
  196 + def cart?
  197 + !@controller.send(:cart).nil?
  198 + end
  199 +
  200 + def product_in_cart?(product)
  201 + @controller.send(:cart) &&
  202 + @controller.send(:cart)[:items] &&
  203 + @controller.send(:cart)[:items].has_key?(product.id)
  204 + end
  205 +
  206 + def product_quantity(product)
  207 + @controller.send(:cart)[:items][product.id]
  208 + end
  209 +
  210 + def response_ok?
  211 + json_response['ok']
  212 + end
  213 +
  214 + def reponse_error_code
  215 + json_response['error']['code']
  216 + end
  217 +
  218 + # temporary hack...if I don't do this the session stays as an Array instead
  219 + # of a TestSession
  220 + def instantiate_cart
  221 + get :add, :id => product.id
  222 + get :remove, :id => product.id
  223 + end
  224 +
  225 +end
... ...
plugins/shopping_cart/test/functional/shopping_cart_plugin_profile_controller_test.rb
... ... @@ -1,213 +0,0 @@
1   -require File.dirname(__FILE__) + '/../../../../test/test_helper'
2   -require File.dirname(__FILE__) + '/../../controllers/shopping_cart_plugin_profile_controller'
3   -
4   -# Re-raise errors caught by the controller.
5   -class ShoppingCartPluginProfileController; def rescue_action(e) raise e end; end
6   -
7   -class ShoppingCartPluginProfileControllerTest < ActionController::TestCase
8   -
9   - def setup
10   - @controller = ShoppingCartPluginProfileController.new
11   - @request = ActionController::TestRequest.new
12   - @response = ActionController::TestResponse.new
13   - @enterprise = fast_create(Enterprise)
14   - @product = fast_create(Product, :enterprise_id => @enterprise.id)
15   - end
16   - attr_reader :enterprise
17   - attr_reader :product
18   -
19   - should 'add a new product to cart' do
20   - get :add, :profile => enterprise.identifier, :id => product.id
21   -
22   - assert product_in_cart?(product)
23   - assert_equal 1, product_quantity(product)
24   - end
25   -
26   - should 'grow quantity through add' do
27   - get :add, :profile => enterprise.identifier, :id => product.id
28   - assert_equal 1, product_quantity(product)
29   -
30   - get :add, :profile => enterprise.identifier, :id => product.id
31   - assert_equal 2, product_quantity(product)
32   - end
33   -
34   - should 'not add product to cart if it does not exists' do
35   - assert_nothing_raised { get :add, :profile => enterprise.identifier, :id => 9999 }
36   -
37   - assert !product_in_cart?(product)
38   - assert !response_ok?
39   - assert 3, reponse_error_code
40   - end
41   -
42   - should 'remove cart if the product being removed is the last one' do
43   - get :add, :profile => enterprise.identifier, :id => product.id
44   - assert cart?
45   -
46   - get :remove, :profile => enterprise.identifier, :id => product.id
47   - assert !cart?
48   - end
49   -
50   - should 'not try to remove a product if there is no cart' do
51   - instantiate_session
52   - assert !cart?
53   -
54   - assert_nothing_raised { get :remove, :profile => enterprise.identifier, :id => 9999 }
55   - assert !response_ok?
56   - assert_equal 2, reponse_error_code
57   - end
58   -
59   - should 'just remove product if there are other products on cart' do
60   - another_product = fast_create(Product, :enterprise_id => enterprise.id)
61   - get :add, :profile => enterprise.identifier, :id => product.id
62   - get :add, :profile => enterprise.identifier, :id => another_product.id
63   -
64   - get :remove, :profile => enterprise.identifier, :id => product.id
65   - assert cart?
66   - assert !product_in_cart?(product)
67   - end
68   -
69   - should 'not try to remove a product that is not in the cart' do
70   - get :add, :profile => enterprise.identifier, :id => product.id
71   - assert cart?
72   - assert_nothing_raised { get :remove, :profile => enterprise.identifier, :id => 9999 }
73   -
74   - assert !response_ok?
75   - assert_equal 4, reponse_error_code
76   - end
77   -
78   - should 'not try to list the cart if there is no cart' do
79   - instantiate_session
80   - assert !cart?
81   -
82   - assert_nothing_raised { get :list, :profile => enterprise.identifier }
83   - assert !response_ok?
84   - assert_equal 2, reponse_error_code
85   - end
86   -
87   - should 'list products without errors' do
88   - get :add, :profile => enterprise.identifier, :id => product.id
89   -
90   - assert_nothing_raised { get :list, :profile => enterprise.identifier }
91   - assert response_ok?
92   - end
93   -
94   - should 'update the quantity of a product' do
95   - get :add, :profile => enterprise.identifier, :id => product.id
96   - assert 1, product_quantity(product)
97   -
98   - get :update_quantity, :profile => enterprise.identifier, :id => product.id, :quantity => 3
99   - assert 3, product_quantity(product)
100   - end
101   -
102   - should 'not try to update quantity the quantity of a product if there is no cart' do
103   - instantiate_session
104   - assert !cart?
105   -
106   - assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => 9999, :quantity => 3 }
107   - assert !response_ok?
108   - assert_equal 2, reponse_error_code
109   - end
110   -
111   - should 'not try to update the quantity of a product that is not in the cart' do
112   - get :add, :profile => enterprise.identifier, :id => product.id
113   - assert cart?
114   - assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => 9999, :quantity => 3 }
115   -
116   - assert !response_ok?
117   - assert_equal 4, reponse_error_code
118   - end
119   -
120   - should 'not update the quantity of a product with a invalid value' do
121   - get :add, :profile => enterprise.identifier, :id => product.id
122   -
123   - assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => product.id, :quantity => -1}
124   - assert !response_ok?
125   - assert_equal 5, reponse_error_code
126   -
127   - assert_nothing_raised { get :update_quantity, :profile => enterprise.identifier, :id => product.id, :quantity => 'asdf'}
128   - assert !response_ok?
129   - assert_equal 5, reponse_error_code
130   - end
131   -
132   - should 'clean the cart' do
133   - another_product = fast_create(Product, :enterprise_id => enterprise.id)
134   - get :add, :profile => enterprise.identifier, :id => product.id
135   - get :add, :profile => enterprise.identifier, :id => another_product.id
136   -
137   - assert_nothing_raised { get :clean, :profile => enterprise.identifier }
138   - assert !cart?
139   - end
140   -
141   - should 'not crash if there is no cart' do
142   - instantiate_session
143   - assert !cart?
144   - assert_nothing_raised { get :clean, :profile => enterprise.identifier }
145   - end
146   -
147   - should 'register order on send request' do
148   - product1 = fast_create(Product, :enterprise_id => enterprise.id, :price => 1.99)
149   - product2 = fast_create(Product, :enterprise_id => enterprise.id, :price => 2.23)
150   - @controller.stubs(:session).returns({:cart => {:items => {product1.id => 1, product2.id => 2}}})
151   - assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do
152   - post :send_request,
153   - :customer => {:name => "Manuel", :email => "manuel@ceu.com"},
154   - :profile => enterprise.identifier
155   - end
156   -
157   - order = ShoppingCartPlugin::PurchaseOrder.last
158   -
159   - assert_equal 1.99, order.products_list[product1.id][:price]
160   - assert_equal 1, order.products_list[product1.id][:quantity]
161   - assert_equal 2.23, order.products_list[product2.id][:price]
162   - assert_equal 2, order.products_list[product2.id][:quantity]
163   - assert_equal ShoppingCartPlugin::PurchaseOrder::Status::OPENED, order.status
164   - end
165   -
166   - should 'register order on send request and not crash if product is not defined' do
167   - product1 = fast_create(Product, :enterprise_id => enterprise.id)
168   - @controller.stubs(:session).returns({:cart => {:items => {product1.id => 1}}})
169   - assert_difference ShoppingCartPlugin::PurchaseOrder, :count, 1 do
170   - post :send_request,
171   - :customer => {:name => "Manuel", :email => "manuel@ceu.com"},
172   - :profile => enterprise.identifier
173   - end
174   -
175   - order = ShoppingCartPlugin::PurchaseOrder.last
176   -
177   - assert_equal 0, order.products_list[product1.id][:price]
178   - end
179   -
180   - private
181   -
182   - def json_response
183   - ActiveSupport::JSON.decode @response.body
184   - end
185   -
186   - def cart?
187   - !session[:cart].nil?
188   - end
189   -
190   - def product_in_cart?(product)
191   - session[:cart][:items].has_key?(product.id)
192   - end
193   -
194   - def product_quantity(product)
195   - session[:cart][:items][product.id]
196   - end
197   -
198   - def response_ok?
199   - json_response['ok']
200   - end
201   -
202   - def reponse_error_code
203   - json_response['error']['code']
204   - end
205   -
206   - # temporary hack...if I don't do this the session stays as an Array instead
207   - # of a TestSession
208   - def instantiate_session
209   - get :add, :profile => enterprise.identifier, :id => product.id
210   - get :remove, :profile => enterprise.identifier, :id => product.id
211   - end
212   -
213   -end
plugins/shopping_cart/test/unit/shopping_cart_plugin_test.rb
... ... @@ -7,7 +7,6 @@ class ShoppingCartPluginTest &lt; ActiveSupport::TestCase
7 7 @context = mock()
8 8 @profile = mock()
9 9 @profile.stubs(:identifier).returns('random-user')
10   - @context.stubs(:profile).returns(@profile)
11 10 @shopping_cart.context = @context
12 11 @shopping_cart.stubs(:profile).returns(@profile)
13 12 end
... ... @@ -23,7 +22,8 @@ class ShoppingCartPluginTest &lt; ActiveSupport::TestCase
23 22 product = fast_create(Product, :available => false)
24 23 enterprise = mock()
25 24 enterprise.stubs(:shopping_cart).returns(true)
  25 + product.stubs(:enterprise).returns(enterprise)
26 26  
27   - assert_nil shopping_cart.add_to_cart_button(product, enterprise)
  27 + assert_nil shopping_cart.add_to_cart_button(product)
28 28 end
29 29 end
... ...
plugins/shopping_cart/views/cart.html.erb
... ... @@ -7,7 +7,7 @@
7 7 <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean basket')%></a>
8 8 <ul class="cart-items"></ul>
9 9 <div class="cart-total"><%=_('Total:')%> <b></b></div>
10   - <a href="cart:buy" class="cart-buy"><%=_('Shopping checkout')%></a>
  10 + <a href="/plugin/shopping_cart/buy" class="cart-buy"><%=_('Shopping checkout')%></a>
11 11 </div>
12 12 <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle">
13 13 <span class="str-show"><%=_('Show basket')%></span>
... ... @@ -15,9 +15,3 @@
15 15 </a>
16 16 </div>
17 17 </div>
18   -
19   -<script type="text/javascript">
20   -//<![CDATA[
21   - new Cart({hasProducts:<%= !locals[:cart].nil? ? "true, enterprise:'#{Enterprise.find(locals[:cart][:enterprise_id]).identifier}'" : "false" %>});
22   -//]]>
23   -</script>
... ...
plugins/shopping_cart/views/shopping_cart_plugin/buy.html.erb 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +<% person = user.nil? ? Person.new : user %>
  2 +<div id='cart-request-box'>
  3 + <% form_for(:customer, person, :url => {:action => 'send_request'},
  4 + :html => {:onsubmit => "return Cart.send_request(this)", :id => 'cart-request-form' }) do |f| %>
  5 + <div id="cart-form-main">
  6 + <%= labelled_form_field('* ' + _("Name"), f.text_field(:name, :class => 'required') ) %>
  7 + <%= labelled_form_field('* ' + _("Email"), f.text_field(:email, :class => 'required email') ) %>
  8 + <%= labelled_form_field('* ' + _("Contact phone"), f.text_field(:contact_phone, :class => 'required') ) %>
  9 + </div>
  10 + <fieldset><legend><%=_('Delivery Address')%></legend>
  11 + <%= labelled_form_field(_('Address (street and number)'), f.text_field(:address)) %>
  12 + <%= labelled_form_field( _("City"), f.text_field(:city)) %>
  13 + <%= labelled_form_field(_('ZIP code'), f.text_field(:zip_code)) %>
  14 + </fieldset>
  15 + <div id="cart-form-actions">
  16 + <%= submit_button(:send, _('Send buy request')) %>
  17 + </div>
  18 + <% end %>
  19 + <%= items_table(@cart[:items], @enterprise) %>
  20 + <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %>
  21 +</div>
  22 +
  23 +<script type="text/javascript">
  24 +//<![CDATA[
  25 + jQuery(document).ready(function(){
  26 + jQuery("#cart-request-form").validate({
  27 + submitHandler: function(form) {
  28 + jQuery(form).find('input.submit').attr('disabled', true);
  29 + jQuery('#cboxLoadingOverlay').show().addClass('loading');
  30 + jQuery('#cboxLoadingGraphic').show().addClass('loading');
  31 + }
  32 + });
  33 + });
  34 +//]]>
  35 +</script>
... ...
plugins/shopping_cart/views/shopping_cart_plugin/mailer/customer_notification.html.erb
... ... @@ -35,7 +35,7 @@
35 35 </ul>
36 36  
37 37 <p><%=_('Here are the products you bought:')%></p>
38   - <%= items_table(@items, @supplier, true) %>
  38 + <%= @helper.items_table(@items, @supplier, true) %>
39 39  
40 40 <p>
41 41 --<br/>
... ...
plugins/shopping_cart/views/shopping_cart_plugin/mailer/supplier_notification.html.erb
... ... @@ -33,7 +33,7 @@
33 33 </ul>
34 34  
35 35 <p><%=_('And here are the items bought by this customer:')%></p>
36   - <%= items_table(@items, @supplier, true) %>
  36 + <%= @helper.items_table(@items, @supplier, true) %>
37 37  
38 38 <p>
39 39 --<br/>
... ...
plugins/shopping_cart/views/shopping_cart_plugin/send_request.html.erb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +<%= _("Request sent successfully check your email.")%>
... ...
plugins/shopping_cart/views/shopping_cart_plugin_profile/buy.html.erb
... ... @@ -1,35 +0,0 @@
1   -<% person = user.nil? ? Person.new : user %>
2   -<div id='cart-request-box'>
3   - <% form_for(:customer, person, :url => {:action => 'send_request'},
4   - :html => {:onsubmit => "return Cart.send_request(this)", :id => 'cart-request-form' }) do |f| %>
5   - <div id="cart-form-main">
6   - <%= labelled_form_field('* ' + _("Name"), f.text_field(:name, :class => 'required') ) %>
7   - <%= labelled_form_field('* ' + _("Email"), f.text_field(:email, :class => 'required email') ) %>
8   - <%= labelled_form_field('* ' + _("Contact phone"), f.text_field(:contact_phone, :class => 'required') ) %>
9   - </div>
10   - <fieldset><legend><%=_('Delivery Address')%></legend>
11   - <%= labelled_form_field(_('Address (street and number)'), f.text_field(:address)) %>
12   - <%= labelled_form_field( _("City"), f.text_field(:city)) %>
13   - <%= labelled_form_field(_('ZIP code'), f.text_field(:zip_code)) %>
14   - </fieldset>
15   - <div id="cart-form-actions">
16   - <%= submit_button(:send, _('Send buy request')) %>
17   - </div>
18   - <% end %>
19   - <%= items_table(session[:cart][:items], profile) %>
20   - <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %>
21   -</div>
22   -
23   -<script type="text/javascript">
24   -//<![CDATA[
25   - jQuery(document).ready(function(){
26   - jQuery("#cart-request-form").validate({
27   - submitHandler: function(form) {
28   - jQuery(form).find('input.submit').attr('disabled', true);
29   - jQuery('#cboxLoadingOverlay').show().addClass('loading');
30   - jQuery('#cboxLoadingGraphic').show().addClass('loading');
31   - }
32   - });
33   - });
34   -//]]>
35   -</script>
plugins/shopping_cart/views/shopping_cart_plugin_profile/send_request.html.erb
... ... @@ -1 +0,0 @@
1   -<%= _("Request sent successfully check your email.")%>
plugins/spaminator/controllers/spaminator_plugin_admin_controller.rb
... ... @@ -34,7 +34,7 @@ class SpaminatorPluginAdminController &lt; AdminController
34 34 settings.scanning = true
35 35 settings.save!
36 36 remove_scheduled_scan
37   - Delayed::Job.enqueue(SpaminatorPlugin::ScanJob.new(environment))
  37 + Delayed::Job.enqueue(SpaminatorPlugin::ScanJob.new(environment.id))
38 38 end
39 39 redirect_to :action => 'index'
40 40 end
... ...
plugins/spaminator/lib/spaminator_plugin/scan_job.rb
... ... @@ -6,7 +6,11 @@ class SpaminatorPlugin::ScanJob &lt; Struct.new(:environment_id)
6 6 settings.scanning = true
7 7 settings.save!
8 8  
9   - SpaminatorPlugin::Spaminator.run(environment)
  9 + begin
  10 + SpaminatorPlugin::Spaminator.run(environment)
  11 + rescue Exception => exception
  12 + SpaminatorPlugin::Spaminator.log("Spaminator failed with the following error: \n ==> #{exception}\n#{exception.backtrace.join("\n")}")
  13 + end
10 14  
11 15 settings.scanning = false
12 16 SpaminatorPlugin.schedule_scan(environment) if settings.deployed
... ...
plugins/spaminator/lib/spaminator_plugin/spaminator.rb
... ... @@ -11,6 +11,14 @@ class SpaminatorPlugin::Spaminator
11 11 def benchmark(environment)
12 12 puts Benchmark.measure { run(environment) }
13 13 end
  14 +
  15 + def initialize_logger(logpath)
  16 + @logger = Logger.new(logpath)
  17 + end
  18 +
  19 + def log(message)
  20 + @logger << "[#{Time.now.strftime("%F %T %z")}] #{message}\n"
  21 + end
14 22 end
15 23  
16 24  
... ... @@ -20,9 +28,12 @@ class SpaminatorPlugin::Spaminator
20 28 @report = SpaminatorPlugin::Report.new(:environment => environment,
21 29 :total_people => Person.count,
22 30 :total_comments => Comment.count)
  31 + logpath = File.join(SpaminatorPlugin.root_path, 'log', "#{environment.name.to_slug}_#{ENV['RAILS_ENV']}_#{Time.now.strftime("%F_%T")}.log")
  32 + self.class.initialize_logger(logpath)
23 33 end
24 34  
25 35 def run
  36 + self.class.log("Starting Spaminator scan")
26 37 start_time = Time.now
27 38  
28 39 process_all_comments
... ... @@ -37,6 +48,7 @@ class SpaminatorPlugin::Spaminator
37 48 finish_report
38 49 @settings.last_run = start_time
39 50 @settings.save!
  51 + self.class.log("Finishing Spaminator scan successfully")
40 52 end
41 53  
42 54 # TODO considering run everything always
... ... @@ -53,6 +65,7 @@ class SpaminatorPlugin::Spaminator
53 65 end
54 66  
55 67 def process_all_comments
  68 + self.class.log("Starting to process all comments")
56 69 comments = comments_to_process
57 70 total = comments.count
58 71 pbar = ProgressBar.new("☢ Comments", total)
... ... @@ -66,9 +79,11 @@ class SpaminatorPlugin::Spaminator
66 79 end
67 80 @report.processed_comments = total
68 81 pbar.finish
  82 + self.class.log("All comments processed")
69 83 end
70 84  
71 85 def process_all_people
  86 + self.class.log("Starting to process all people")
72 87 people = people_to_process
73 88 total = people.count
74 89 pbar = ProgressBar.new("☢ People", total)
... ... @@ -79,9 +94,11 @@ class SpaminatorPlugin::Spaminator
79 94 end
80 95 @report.processed_people = total
81 96 pbar.finish
  97 + self.class.log("All people processed")
82 98 end
83 99  
84 100 def process_comment(comment)
  101 + self.class.log("Processing Comment[#{comment.id.to_s}]")
85 102 comment = Comment.find(comment.id)
86 103 comment.check_for_spam
87 104 @report.spams_by_content += 1 if comment.spam
... ... @@ -97,6 +114,7 @@ class SpaminatorPlugin::Spaminator
97 114 # person is author of more than 2 comments marked as spam
98 115 # → mark as spammer
99 116 #
  117 + self.class.log("Processing Person[#{person.id.to_s}] by comments")
100 118 begin
101 119 number_of_spam_comments = Comment.spam.where(:author_id => person.id).count
102 120 if number_of_spam_comments > 2
... ... @@ -115,6 +133,7 @@ class SpaminatorPlugin::Spaminator
115 133 # → disable the profile
116 134 # ? mark their comments as spam
117 135 #
  136 + self.class.log("Processing Person[#{person.id.to_s}] by network")
118 137 if person.created_at < (Time.now - 1.month) &&
119 138 person.friends.count == 0 &&
120 139 person.communities.count <= 1
... ... @@ -151,6 +170,7 @@ class SpaminatorPlugin::Spaminator
151 170 end
152 171  
153 172 def register_fail(kind, failed)
  173 + self.class.log("Failed #{kind.to_s.camelize}[#{failed.id.to_s}]")
154 174 @report[:failed][kind.to_sym] << failed.id
155 175 end
156 176 end
... ...
test/functional/profile_controller_test.rb
... ... @@ -234,7 +234,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
234 234 login_as(@profile.identifier)
235 235 ent = fast_create(Enterprise, :name => 'my test enterprise', :identifier => 'my-test-enterprise', :enabled => false)
236 236 get :index, :profile => ent.identifier
237   - assert_tag :tag => 'div', :attributes => { :id => 'profile-disabled' }, :content => Environment.default.message_for_disabled_enterprise
  237 + assert_tag :tag => 'div', :attributes => { :id => 'profile-disabled' }, :content => /#{Environment.default.message_for_disabled_enterprise}/
238 238 end
239 239  
240 240 should 'not show message for disabled enterprise to non-enterprises' do
... ...
test/unit/approve_article_test.rb
... ... @@ -414,4 +414,20 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
414 414 assert_match /My Article/, task.task_cancelled_message
415 415 end
416 416  
  417 + should 'not save 4 on the new article\'s last_changed_by_ud after approval if author is nil' do
  418 + article = fast_create(Article)
  419 + task = ApproveArticle.create!(:article => article, :target => community, :requestor => profile)
  420 + task.finish
  421 + new_article = Article.last
  422 + assert_nil new_article.last_changed_by_id
  423 + end
  424 +
  425 + should 'not crash if target has its own domain' do
  426 + article = fast_create(Article)
  427 + profile.domains << Domain.create(:name => 'example.org')
  428 + assert_nothing_raised do
  429 + ApproveArticle.create!(:article => article, :target => profile, :requestor => community)
  430 + end
  431 + end
  432 +
417 433 end
... ...
test/unit/article_test.rb
... ... @@ -1822,4 +1822,15 @@ class ArticleTest &lt; ActiveSupport::TestCase
1822 1822 assert_equal author_name, article.author_name
1823 1823 end
1824 1824  
  1825 + should "author_id return the author id of the article's author" do
  1826 + author = fast_create(Person)
  1827 + article = Article.create!(:name => 'Test', :profile => profile, :last_changed_by => author)
  1828 + assert_equal author.id, article.author_id
  1829 + end
  1830 +
  1831 + should "author_id return nil if there is no article's author" do
  1832 + article = Article.create!(:name => 'Test', :profile => profile, :last_changed_by => nil)
  1833 + assert_nil article.author_id
  1834 + end
  1835 +
1825 1836 end
... ...
test/unit/comment_notifier_test.rb
... ... @@ -8,26 +8,27 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
8 8 ActionMailer::Base.delivery_method = :test
9 9 ActionMailer::Base.perform_deliveries = true
10 10 ActionMailer::Base.deliveries = []
11   - @profile = create_user('user_comment_test').person
  11 + @profile = create_user('content_owner').person
  12 + @author = create_user('author').person
12 13 @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true)
13 14 end
14 15  
15 16 should 'deliver mail after make an article comment' do
16 17 assert_difference ActionMailer::Base.deliveries, :size do
17   - create_comment_and_notify(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article )
  18 + create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'you suck!', :source => @article )
18 19 end
19 20 end
20 21  
21 22 should 'deliver mail to owner of article' do
22   - create_comment_and_notify(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article )
  23 + create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'you suck!', :source => @article )
23 24 sent = ActionMailer::Base.deliveries.first
24 25 assert_equal [@profile.email], sent.to
25 26 end
26 27  
27 28 should 'display author name in delivered mail' do
28   - create_comment_and_notify(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article)
  29 + create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'you suck!', :source => @article)
29 30 sent = ActionMailer::Base.deliveries.first
30   - assert_match /user_comment_test/, sent.body
  31 + assert_match /#{@author.name}/, sent.body
31 32 end
32 33  
33 34 should 'display unauthenticated author name and email in delivered mail' do
... ... @@ -40,18 +41,18 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
40 41 should 'not deliver mail if notify comments is false' do
41 42 @article.update_attribute(:notify_comments, false)
42 43 assert_no_difference ActionMailer::Base.deliveries, :size do
43   - create_comment_and_notify(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article)
  44 + create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'you suck!', :source => @article)
44 45 end
45 46 end
46 47  
47 48 should 'include comment title in the e-mail' do
48   - create_comment_and_notify(:author => @profile, :title => 'comment title', :body => 'comment body', :source => @article)
  49 + create_comment_and_notify(:author => @author, :title => 'comment title', :body => 'comment body', :source => @article)
49 50 sent = ActionMailer::Base.deliveries.first
50 51 assert_match /comment title/, sent.body
51 52 end
52 53  
53 54 should 'include comment text in the e-mail' do
54   - create_comment_and_notify(:author => @profile, :title => 'comment title', :body => 'comment body', :source => @article)
  55 + create_comment_and_notify(:author => @author, :title => 'comment title', :body => 'comment body', :source => @article)
55 56 sent = ActionMailer::Base.deliveries.first
56 57 assert_match /comment body/, sent.body
57 58 end
... ... @@ -61,7 +62,7 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
61 62 assert_equal [], community.notification_emails
62 63 article = fast_create(Article, :name => 'Article test', :profile_id => community.id, :notify_comments => true)
63 64 assert_no_difference ActionMailer::Base.deliveries, :size do
64   - create_comment_and_notify(:author => @profile, :title => 'test comment', :body => 'there is no addresses to send notification', :source => article)
  65 + create_comment_and_notify(:author => @author, :title => 'test comment', :body => 'there is no addresses to send notification', :source => article)
65 66 end
66 67 end
67 68  
... ... @@ -80,6 +81,17 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
80 81 assert_not_includes ActionMailer::Base.deliveries.map(&:bcc).flatten, follower.email
81 82 end
82 83  
  84 + should 'not deliver mail to comments author' do
  85 + community = fast_create(Community)
  86 + community.add_admin @profile
  87 + community.add_admin @author
  88 +
  89 + article = fast_create(Article, :name => 'Article test', :profile_id => community.id, :notify_comments => true)
  90 + create_comment_and_notify(:source => @article, :author => @author, :title => 'comment title', :body => 'comment body')
  91 + sent = ActionMailer::Base.deliveries.first
  92 + assert_not_includes sent.to, @author.email
  93 + end
  94 +
83 95 private
84 96  
85 97 def create_comment_and_notify(args)
... ...
test/unit/disabled_enterprise_message_block_test.rb
... ... @@ -18,17 +18,6 @@ class DisabledEnterpriseMessageBlockTest &lt; ActiveSupport::TestCase
18 18 instance_eval(&block.content)
19 19 end
20 20  
21   - should 'display nothing if environment has no message' do
22   - e = fast_create(Environment)
23   - block = DisabledEnterpriseMessageBlock.new
24   - p = Profile.new
25   - block.expects(:owner).returns(p)
26   - p.expects(:environment).returns(e)
27   -
28   - expects(:render).with(:file => 'blocks/disabled_enterprise_message', :locals => { :message => ''})
29   - instance_eval(&block.content)
30   - end
31   -
32 21 should 'not be editable' do
33 22 assert !DisabledEnterpriseMessageBlock.new.editable?
34 23 end
... ...
test/unit/profile_test.rb
... ... @@ -246,6 +246,13 @@ class ProfileTest &lt; ActiveSupport::TestCase
246 246 assert_equal({ :profile => 'testprofile', :controller => 'profile_editor', :action => 'index'}, profile.admin_url)
247 247 end
248 248  
  249 + should 'provide URL to tasks area' do
  250 + environment = create_environment('mycolivre.net')
  251 + profile = build(Profile, :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
  252 +
  253 + assert_equal({ :host => profile.default_hostname, :profile => 'testprofile', :controller => 'tasks', :action => 'index'}, profile.tasks_url)
  254 + end
  255 +
249 256 should 'provide URL to public profile' do
250 257 environment = create_environment('mycolivre.net')
251 258 profile = build(Profile, :identifier => 'testprofile', :environment_id => environment.id)
... ...
test/unit/task_mailer_test.rb
... ... @@ -84,22 +84,9 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
84 84 end
85 85  
86 86 should 'be able to send a "target notification" message' do
87   - task = Task.new
  87 + task = Task.new(:target => fast_create(Person))
88 88 task.expects(:target_notification_description).returns('the task')
89 89  
90   - target = mock()
91   - target.expects(:notification_emails).returns(['target@example.com'])
92   - target.expects(:name).returns('Target')
93   - target.expects(:url).returns({:host => 'my.domain.com', :profile => 'testprofile'})
94   -
95   - environment = mock()
96   - environment.expects(:contact_email).returns('sender@example.com')
97   - environment.expects(:default_hostname).returns('example.com')
98   - environment.expects(:name).returns('example').at_least_once
99   -
100   - task.expects(:target).returns(target).at_least_once
101   - task.expects(:environment).returns(environment).at_least_once
102   -
103 90 TaskMailer.deliver_target_notification(task, 'the message')
104 91 assert !ActionMailer::Base.deliveries.empty?
105 92 end
... ...
test/unit/user_test.rb
... ... @@ -617,6 +617,19 @@ class UserTest &lt; ActiveSupport::TestCase
617 617 end
618 618 end
619 619  
  620 + should 'create person with name equal to user name if a user name is defined' do
  621 + user = User.new( :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' )
  622 + user.name = "Some name"
  623 + user.save
  624 + assert_equal 'Some name', user.person.name
  625 + end
  626 +
  627 + should 'create person with name equal to user login if no user name is defined' do
  628 + user = User.new( :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' )
  629 + user.save
  630 + assert_equal 'quire', user.person.name
  631 + end
  632 +
620 633 protected
621 634 def new_user(options = {})
622 635 user = User.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options))
... ...
vendor/plugins/noosfero_caching/init.rb
... ... @@ -38,11 +38,24 @@ module NoosferoHttpCaching
38 38 def call(env)
39 39 status, headers, body = @app.call(env)
40 40 if headers['X-Noosfero-Auth'] == 'false'
41   - headers.delete('Set-Cookie')
  41 + headers['Set-Cookie'] = remove_unwanted_cookies(headers['Set-Cookie'])
  42 + headers.delete('Set-Cookie') if headers['Set-Cookie'].blank?
42 43 end
43 44 headers.delete('X-Noosfero-Auth')
44 45 [status, headers, body]
45 46 end
  47 +
  48 + protected
  49 +
  50 + # filter off all cookies except for plugin-provided ones that are
  51 + # path-specific (i.e path != "/").
  52 + def remove_unwanted_cookies(cookie_list)
  53 + return nil if cookie_list.nil?
  54 + cookie_list.select do |c|
  55 + c =~ /^_noosfero_plugin_\w+=/ && c =~ /path=\/\w+/
  56 + end
  57 + end
  58 +
46 59 end
47 60  
48 61 end
... ...