Commit 8d9a57dbb4701d6d51fb2e810dddedbdc23e8727

Authored by Victor Costa
2 parents 738d396b 9e3e94b3

Merge branch 'master' into staging

Conflicts:
	Rakefile
@@ -17,12 +17,6 @@ end.flatten.each do |taskfile| @@ -17,12 +17,6 @@ end.flatten.each do |taskfile|
17 load taskfile 17 load taskfile
18 end 18 end
19 19
20 -# plugins' tasks  
21 -plugins_tasks = Dir.glob("config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort +  
22 - Dir.glob("config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake").sort  
23 -plugins_tasks.each{ |ext| load ext }  
24 -  
25 -  
26 desc "Print out grape routes" 20 desc "Print out grape routes"
27 task :grape_routes => :environment do 21 task :grape_routes => :environment do
28 #require 'api/api.rb' 22 #require 'api/api.rb'
app/controllers/my_profile/maps_controller.rb
1 class MapsController < MyProfileController 1 class MapsController < MyProfileController
2 2
  3 + skip_before_filter :verify_authenticity_token, only: [:google_map]
  4 +
3 protect 'edit_profile', :profile 5 protect 'edit_profile', :profile
4 6
5 def edit_location 7 def edit_location
app/helpers/article_helper.rb
@@ -119,7 +119,7 @@ module ArticleHelper @@ -119,7 +119,7 @@ module ArticleHelper
119 end 119 end
120 120
121 def add_option_to_followers(article, tokenized_children) 121 def add_option_to_followers(article, tokenized_children)
122 - label_message = article.profile.organization? ? _('For all community members') : _('For all your friends') 122 + label_message = article.profile.organization? ? _('Allow all community members to view this content') : _('Allow all your friends to view this content')
123 123
124 check_box( 124 check_box(
125 :article, 125 :article,
@@ -137,7 +137,7 @@ module ArticleHelper @@ -137,7 +137,7 @@ module ArticleHelper
137 'div', 137 'div',
138 content_tag( 138 content_tag(
139 'label', 139 'label',
140 - _('Fill in the search field to add the exception users to see this content'), 140 + _('Allow only community members entered below to view this content'),
141 :id => "text-input-search-exception-users" 141 :id => "text-input-search-exception-users"
142 ) + 142 ) +
143 token_input_field_tag( 143 token_input_field_tag(
@@ -146,7 +146,7 @@ module ArticleHelper @@ -146,7 +146,7 @@ module ArticleHelper
146 {:action => 'search_article_privacy_exceptions'}, 146 {:action => 'search_article_privacy_exceptions'},
147 { 147 {
148 :focus => false, 148 :focus => false,
149 - :hint_text => _('Type in a search term for a user'), 149 + :hint_text => _('Type in a name of a community member'),
150 :pre_populate => tokenized_children 150 :pre_populate => tokenized_children
151 } 151 }
152 ) 152 )
app/models/enterprise.rb
@@ -25,10 +25,6 @@ class Enterprise &lt; Organization @@ -25,10 +25,6 @@ class Enterprise &lt; Organization
25 has_many :favorite_enterprise_people 25 has_many :favorite_enterprise_people
26 has_many :fans, source: :person, through: :favorite_enterprise_people 26 has_many :fans, source: :person, through: :favorite_enterprise_people
27 27
28 - def product_categories  
29 - ProductCategory.by_enterprise(self)  
30 - end  
31 -  
32 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') 28 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code')
33 29
34 settings_items :organization_website, :historic_and_current_context, :activities_short_description 30 settings_items :organization_website, :historic_and_current_context, :activities_short_description
app/models/product_category.rb
@@ -7,7 +7,7 @@ class ProductCategory &lt; Category @@ -7,7 +7,7 @@ class ProductCategory &lt; Category
7 7
8 scope :unique, :select => 'DISTINCT ON (path) categories.*' 8 scope :unique, :select => 'DISTINCT ON (path) categories.*'
9 scope :by_enterprise, -> enterprise { 9 scope :by_enterprise, -> enterprise {
10 - joins(:products). 10 + distinct.joins(:products).
11 where('products.profile_id = ?', enterprise.id) 11 where('products.profile_id = ?', enterprise.id)
12 } 12 }
13 scope :by_environment, -> environment { 13 scope :by_environment, -> environment {
app/views/person_notifier/mailer/_create_article.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> 12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
13 <br/> 13 <br/>
14 <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span> 14 <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span>
15 - <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> 15 + <%= image_tag(activity.params['first_image'], :style => 'max-width:100%;') unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %>
16 </p> 16 </p>
17 <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p> 17 <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p>
18 </td> 18 </td>
app/views/person_notifier/mailer/content_summary.html.erb
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 </div> 24 </div>
25 <% @notifications.each do |activity| %> 25 <% @notifications.each do |activity| %>
26 <div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px"> 26 <div style="border-bottom:1px solid #e2e2e2;padding:15px 0;width:600px">
27 - <table style="width:100%;"> 27 + <table style="width:100%;table-layout:fixed;">
28 <%= render activity.verb, activity: activity %> 28 <%= render activity.verb, activity: activity %>
29 </table> 29 </table>
30 </div> 30 </div>
features/support/env.rb
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 # instead of editing this one. Cucumber will automatically load all features/**/*.rb 4 # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5 # files. 5 # files.
6 6
  7 +ENV["RAILS_ENV"] ||= "cucumber"
  8 +
7 require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') 9 require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
8 require 'cucumber/rails' 10 require 'cucumber/rails'
9 11
lib/noosfero/plugin.rb
@@ -157,7 +157,7 @@ class Noosfero::Plugin @@ -157,7 +157,7 @@ class Noosfero::Plugin
157 unless @available_plugins 157 unless @available_plugins
158 path = File.join(Rails.root, '{baseplugins,config/plugins}', '*') 158 path = File.join(Rails.root, '{baseplugins,config/plugins}', '*')
159 @available_plugins = Dir.glob(path).select{ |i| File.directory?(i) } 159 @available_plugins = Dir.glob(path).select{ |i| File.directory?(i) }
160 - if Rails.env.test? && !@available_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo')) 160 + if (Rails.env.test? || Rails.env.cucumber?) && !@available_plugins.include?(File.join(Rails.root, 'config', 'plugins', 'foo'))
161 @available_plugins << File.join(Rails.root, 'plugins', 'foo') 161 @available_plugins << File.join(Rails.root, 'plugins', 'foo')
162 end 162 end
163 end 163 end
plugins/orders/lib/ext/profile.rb
@@ -12,10 +12,7 @@ subclass.class_eval do @@ -12,10 +12,7 @@ subclass.class_eval do
12 has_many :ordered_items, -> { order 'name ASC' }, through: :orders, source: :items 12 has_many :ordered_items, -> { order 'name ASC' }, through: :orders, source: :items
13 13
14 has_many :sales_consumers, through: :sales, source: :consumer 14 has_many :sales_consumers, through: :sales, source: :consumer
15 - has_many :purchases_consumers, through: :sales, source: :consumer  
16 -  
17 - has_many :sales_profiles, through: :sales, source: :profile  
18 - has_many :purchases_profiles, through: :sales, source: :profile 15 + has_many :purchases_suppliers, through: :purchases, source: :profile
19 16
20 end 17 end
21 end 18 end
@@ -30,12 +27,12 @@ class Profile @@ -30,12 +27,12 @@ class Profile
30 27
31 def sales_all_consumers 28 def sales_all_consumers
32 consumers = self.sales_consumers.order 'name ASC' 29 consumers = self.sales_consumers.order 'name ASC'
33 - consumers.concat self.suppliers.except_self.order('name ASC') if self.respond_to? :suppliers 30 + consumers.concat self.consumers.except_self.order('name ASC') if self.respond_to? :consumers
34 consumers.uniq 31 consumers.uniq
35 end 32 end
36 - def purchases_all_consumers  
37 - consumers = self.purchases_consumers.order 'name ASC'  
38 - consumers.concat self.consumers.except_self.order('name ASC') if self.respond_to? :consumers 33 + def purchases_all_suppliers
  34 + consumers = self.purchases_suppliers.order 'name ASC'
  35 + consumers.concat self.suppliers.except_self.order('name ASC') if self.respond_to? :suppliers
39 consumers.uniq 36 consumers.uniq
40 end 37 end
41 38
plugins/orders/views/orders_plugin/mailer/order_confirmation.html.erb
@@ -28,10 +28,11 @@ @@ -28,10 +28,11 @@
28 28
29 <%= render "orders_plugin_order/show_simple", order: @order, actor_name: :consumer %> 29 <%= render "orders_plugin_order/show_simple", order: @order, actor_name: :consumer %>
30 30
  31 +
31 <p> 32 <p>
32 <%= t('orders_plugin.views.mailer.order_confirmation.your_order_can_be_che') %><br /> 33 <%= t('orders_plugin.views.mailer.order_confirmation.your_order_can_be_che') %><br />
33 <%= link_to t('orders_plugin.views.mailer.order_confirmation.order_code_of_profile') % {code: @order.code, name: @profile.name }, 34 <%= link_to t('orders_plugin.views.mailer.order_confirmation.order_code_of_profile') % {code: @order.code, name: @profile.name },
34 - {controller: :orders_cycle_plugin_order, action: :edit, profile: @profile.identifier, id: @order.id, protocol: "http"} %> 35 + {controller: :orders_plugin_order, action: :edit, profile: @profile.identifier, id: @order.id, protocol: "http"} %>
35 </p> 36 </p>
36 37
37 <p> 38 <p>
plugins/orders/views/orders_plugin_admin/_index.html.erb
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -<h1> <%= t('orders_plugin.lib.plugin.panel_button') %> </h1>  
2 -  
3 -<%= button :back, _('Back to control panel'), controller: 'profile_editor' %>  
4 -  
5 -<div>  
6 - <% if @purchases.present? and @sales.present? %>  
7 - <ul id="orders-tabs" class='nav nav-pills' data-tabs="orders-tabs">  
8 - <li class='active' data-toggle="orders-tabs"><a href='#purchases'><%= t('orders_plugin.terms.purchase.plural') %></a></li>  
9 - <li class='<%= 'active' if @purchases.blank? %>' data-toggle="orders-tabs"><a href='#sales'><%= t('orders_plugin.terms.sale.plural') %></a></li>  
10 - </ul>  
11 - <% end %>  
12 -  
13 - <% if @purchases.present? %>  
14 - <div id='purchases' class="tab-pane">  
15 - <%= render 'orders_plugin_admin/purchases', actors: profile.sales_all_consumers,  
16 - orders_owner: profile, orders: @purchases, month: @purchases_month, year: @purchases_year, wireframe_size: false %>  
17 - </div>  
18 - <% end %>  
19 -  
20 - <% if @sales.present? %>  
21 - <div id='sales' class="tab-pane">  
22 - <%= render 'orders_plugin_admin/sales', actors: profile.purchases_all_consumers,  
23 - orders_owner: profile, orders: @sales, month: @sales_month, year: @purchases_year, wireframe_size: false %>  
24 - </div>  
25 - <% end %>  
26 -</div>  
plugins/orders/views/orders_plugin_admin/_index.html.slim 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +h1
  2 + = t('orders_plugin.lib.plugin.panel_button')
  3 +
  4 += button :back, _('Back to control panel'), controller: 'profile_editor'
  5 +
  6 +div
  7 + - if @purchases.present? and @sales.present?
  8 + ul#orders-tabs.nav.nav-pills data-tabs="orders-tabs"
  9 + li.active data-toggle="orders-tabs"
  10 + a href="#purchases" = t('orders_plugin.terms.purchase.plural')
  11 + li class=("#{'active' if @purchases.blank?}") data-toggle="orders-tabs"
  12 + a href="#sales" = t('orders_plugin.terms.sale.plural')
  13 +
  14 + - if @purchases.present?
  15 + #purchases.tab-pane
  16 + = render 'orders_plugin_admin/purchases', actors: profile.purchases_all_suppliers,
  17 + orders_owner: profile, orders: @purchases, month: @purchases_month, year: @purchases_year, wireframe_size: false
  18 +
  19 + - if @sales.present?
  20 + #sales.tab-pane
  21 + = render 'orders_plugin_admin/sales', actors: profile.sales_all_consumers,
  22 + orders_owner: profile, orders: @sales, month: @sales_month, year: @purchases_year, wireframe_size: false
plugins/orders/views/orders_plugin_admin/_order.html.erb
@@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
1 -<% other_actor_name = if actor_name == :supplier then :consumer else :supplier end %>  
2 -<% edit = true if edit.nil? %>  
3 -  
4 -<div id="order-row-<%=order.id%>" data-id="<%=order.id%>" class="order value-row <%=order.status%>" onclick="orders.admin.load_edit(this, '<%= url_for action: :edit, id: order.id, actor_name: actor_name %>')" toggle-edit="orders.admin.toggle_edit();">  
5 - <div class="box-view with-inner">  
6 - <div class="box-field select" toggle-ignore><%= check_box_tag "order_ids[]", order.id %></div>  
7 -  
8 - <div class="box-view-inner">  
9 - <span class='box-field code'><%= order.code %></span>  
10 - <span class='box-field actor-name'><%= order.send("#{other_actor_name}_data")[:name] %></span>  
11 - <span class='box-field order-date'><%= datetime_full order.created_at %></span>  
12 - <span class='box-field last-update'><%= datetime_full order.updated_at %></span>  
13 - <span class='box-field total'><%= order.total_price_as_currency_number actor_name %></span>  
14 - <span class='box-field situation'><%= order_situation order %></span>  
15 - </div>  
16 -  
17 - <%= edit_arrow "#order-row-#{order.id}", true, class: 'actions' %>  
18 -  
19 - <div class="clean"></div>  
20 - </div>  
21 -  
22 - <div class="box-edit <%= 'loading' if not edit %>">  
23 - <% if edit %>  
24 - <%= render 'orders_plugin_admin/edit', order: order, actor_name: actor_name, other_actor_name: other_actor_name %>  
25 - <% end %>  
26 - </div>  
27 -  
28 - <div class="clean"></div>  
29 -</div>  
plugins/orders/views/orders_plugin_admin/index.html.erb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -_index.html.erb  
2 \ No newline at end of file 0 \ No newline at end of file
plugins/orders/views/orders_plugin_admin/index.html.slim 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_index.html.slim
0 \ No newline at end of file 2 \ No newline at end of file
plugins/responsive/views/layouts/_content.html.erb
plugins/shopping_cart/features/delivery_client.feature
@@ -37,7 +37,7 @@ Feature: delivery client @@ -37,7 +37,7 @@ Feature: delivery client
37 And I should see "Show basket" 37 And I should see "Show basket"
38 And I follow "Show basket" 38 And I follow "Show basket"
39 And I follow "Shopping checkout" 39 And I follow "Shopping checkout"
40 - And I fill in "Contact phone" with "123456789" 40 + And I fill in "order_consumer_data_contact_phone" with "123456789"
41 When I select "Bike ($8.00)" from "Option" 41 When I select "Bike ($8.00)" from "Option"
42 Then I should see "My good old bike." within ".instructions" 42 Then I should see "My good old bike." within ".instructions"
43 And I should see "Address" 43 And I should see "Address"
@@ -51,7 +51,7 @@ Feature: delivery client @@ -51,7 +51,7 @@ Feature: delivery client
51 And I should see "Show basket" 51 And I should see "Show basket"
52 And I follow "Show basket" 52 And I follow "Show basket"
53 And I follow "Shopping checkout" 53 And I follow "Shopping checkout"
54 - And I fill in "Contact phone" with "123456789" 54 + And I fill in "order_consumer_data_contact_phone" with "123456789"
55 When I select "Bar" from "Option" 55 When I select "Bar" from "Option"
56 Then I should see "Come to my bar and drink it!" within ".instructions" 56 Then I should see "Come to my bar and drink it!" within ".instructions"
57 And I should not see "Address" 57 And I should not see "Address"
@@ -69,7 +69,7 @@ Feature: delivery client @@ -69,7 +69,7 @@ Feature: delivery client
69 And I should see "Show basket" 69 And I should see "Show basket"
70 And I follow "Show basket" 70 And I follow "Show basket"
71 And I follow "Shopping checkout" 71 And I follow "Shopping checkout"
72 - And I fill in "Contact phone" with "123456789" 72 + And I fill in "order_consumer_data_contact_phone" with "123456789"
73 When I select "Bike ($8.00)" from "Option" 73 When I select "Bike ($8.00)" from "Option"
74 Then I should see "My good old bike." within ".instructions" 74 Then I should see "My good old bike." within ".instructions"
75 And I should see "Address" 75 And I should see "Address"
plugins/shopping_cart/features/purchases.feature
@@ -108,7 +108,7 @@ Feature: purchases @@ -108,7 +108,7 @@ Feature: purchases
108 And I follow "Purchases made" 108 And I follow "Purchases made"
109 And I should see "Moes Tavern" within any ".actor-name" 109 And I should see "Moes Tavern" within any ".actor-name"
110 And I should see "First Church of Springfield" within any ".actor-name" 110 And I should see "First Church of Springfield" within any ".actor-name"
111 - And I select "Moes Tavern" from "supplier" 111 + And I select "Moes Tavern" from "supplier_id"
112 When I press "Filter" 112 When I press "Filter"
113 Then I should see "Moes Tavern" within any ".actor-name" 113 Then I should see "Moes Tavern" within any ".actor-name"
114 And I should not see "First Church of Springfield" within any ".actor-name" 114 And I should not see "First Church of Springfield" within any ".actor-name"
@@ -125,7 +125,7 @@ Feature: purchases @@ -125,7 +125,7 @@ Feature: purchases
125 And I follow "Add to basket" 125 And I follow "Add to basket"
126 And I follow "Show basket" 126 And I follow "Show basket"
127 And I follow "Shopping checkout" 127 And I follow "Shopping checkout"
128 - And I fill in "Contact phone" with "123456789" 128 + And I fill in "order_consumer_data_contact_phone" with "123456789"
129 And I select "Bike ($8.00)" from "Option" 129 And I select "Bike ($8.00)" from "Option"
130 And I press "Send buy request" 130 And I press "Send buy request"
131 And I go to homer's control panel 131 And I go to homer's control panel
plugins/shopping_cart/features/sales.feature
@@ -98,7 +98,7 @@ Feature: sales @@ -98,7 +98,7 @@ Feature: sales
98 And I follow "Purchases and Sales" 98 And I follow "Purchases and Sales"
99 And I should see "Homer" within any ".actor-name" 99 And I should see "Homer" within any ".actor-name"
100 And I should see "Reverend Lovejoy" within any ".actor-name" 100 And I should see "Reverend Lovejoy" within any ".actor-name"
101 - And I select "Homer" from "consumer" 101 + And I select "Homer" from "consumer_id"
102 When I press "Filter" 102 When I press "Filter"
103 Then I should see "Homer" within any ".actor-name" 103 Then I should see "Homer" within any ".actor-name"
104 And I should not see "Reverend Lovejoy" within any ".actor-name" 104 And I should not see "Reverend Lovejoy" within any ".actor-name"
plugins/shopping_cart/test/functional/shopping_cart_plugin_controller_test.rb
@@ -16,11 +16,11 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase @@ -16,11 +16,11 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
16 16
17 should 'force cookie expiration with explicit path for an empty cart' do 17 should 'force cookie expiration with explicit path for an empty cart' do
18 get :get, id: product.id 18 get :get, id: product.id
19 - assert @response.headers['Set-Cookie'] =~ /_noosfero_plugin_shopping_cart=; path=\/plugin\/shopping_cart; expires=.*1970.*/ 19 + assert @response.headers['Set-Cookie'] =~ /_noosfero_plugin_shopping_cart=; path=\/plugin\/shopping_cart/
20 20
21 get :add, id: product.id 21 get :add, id: product.id
22 get :remove, id: product.id 22 get :remove, id: product.id
23 - assert @response.headers['Set-Cookie'] =~ /_noosfero_plugin_shopping_cart=; path=\/plugin\/shopping_cart; expires=.*1970.*/ 23 + assert @response.headers['Set-Cookie'] =~ /_noosfero_plugin_shopping_cart=; path=\/plugin\/shopping_cart/
24 end 24 end
25 25
26 should 'add a new product to cart' do 26 should 'add a new product to cart' do
test/functional/cms_controller_test.rb
@@ -528,7 +528,7 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -528,7 +528,7 @@ class CmsControllerTest &lt; ActionController::TestCase
528 post :new, :type => TextileArticle.name, :profile => profile.identifier, :article => { :name => 'adding-categories-test', :category_ids => [ c1.id, c3.id, c3.id ] } 528 post :new, :type => TextileArticle.name, :profile => profile.identifier, :article => { :name => 'adding-categories-test', :category_ids => [ c1.id, c3.id, c3.id ] }
529 529
530 saved = profile.articles.find_by_name('adding-categories-test') 530 saved = profile.articles.find_by_name('adding-categories-test')
531 - assert_equal [c1, c3], saved.categories 531 + assert_equal [c1, c3], saved.categories.all
532 end 532 end
533 533
534 should 'filter html with white_list from tiny mce article name' do 534 should 'filter html with white_list from tiny mce article name' do
test/test_helper.rb
@@ -87,9 +87,11 @@ class ActiveSupport::TestCase @@ -87,9 +87,11 @@ class ActiveSupport::TestCase
87 alias :ok :assert_block 87 alias :ok :assert_block
88 88
89 def assert_equivalent(enum1, enum2) 89 def assert_equivalent(enum1, enum2)
90 - enum1 = enum1.group_by{|e|e}.values  
91 - enum2 = enum2.group_by{|e|e}.values  
92 - assert( (enum1.length == enum2.length) && ((enum1 - enum2) == []), "<#{enum1.inspect}> expected to be equivalent to <#{enum2.inspect}>") 90 + norm1 = enum1.group_by{|e|e}.values
  91 + norm2 = enum2.group_by{|e|e}.values
  92 + assert_equal norm1.size, norm2.size, "Size mismatch: #{enum1.inspect} vs #{enum2.inspect}"
  93 + assert_equal [], norm1 - norm2
  94 + assert_equal [], norm2 - norm1
93 end 95 end
94 96
95 def assert_mandatory(object, attribute, test_value = 'some random string') 97 def assert_mandatory(object, attribute, test_value = 'some random string')
test/unit/helper_test.rb 0 → 100644
@@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class HelperTest < ActiveSupport::TestCase
  4 +
  5 + should 'assert_equivalent be true for the same arrays' do
  6 + a1 = [1,2,3]
  7 + a2 = [1,2,3]
  8 + assert_equivalent a1, a2
  9 + end
  10 +
  11 + should 'assert_equivalent be true for equivalent arrays' do
  12 + a1 = [1,2,3]
  13 + a2 = [3,2,1]
  14 + assert_equivalent a1, a2
  15 + end
  16 +
  17 + should 'assert_equivalent be true for equivalent arrays independent of parameter order' do
  18 + a1 = [1,2,3]
  19 + a2 = [3,2,1]
  20 + assert_equivalent a2, a1
  21 + end
  22 +
  23 + should 'assert_equivalent be false for different arrays' do
  24 + a1 = [1,2,3]
  25 + a2 = [4,2,1]
  26 + assert_raise Minitest::Assertion do
  27 + assert_equivalent(a1, a2)
  28 + end
  29 + end
  30 +
  31 + should 'assert_equivalent be false for different arrays independent of parameter order' do
  32 + a1 = [1,2,3]
  33 + a2 = [4,2,1]
  34 + assert_raise Minitest::Assertion do
  35 + assert_equivalent(a2, a1)
  36 + end
  37 + end
  38 +
  39 + should 'assert_equivalent be false for arrays with different sizes' do
  40 + a1 = [1,2,3]
  41 + a2 = [1,2,3,4]
  42 + assert_raise Minitest::Assertion do
  43 + assert_equivalent(a1, a2)
  44 + end
  45 + end
  46 +
  47 + should 'assert_equivalent be false for arrays with same elements duplicated' do
  48 + a1 = [2,2,3]
  49 + a2 = [2,3,3]
  50 + assert_raise Minitest::Assertion do
  51 + assert_equivalent(a1, a2)
  52 + end
  53 + end
  54 +
  55 + should 'assert_equivalent be false for arrays with same elements duplicated of different sizes' do
  56 + a1 = [2,2,3]
  57 + a2 = [2,3,3,3]
  58 + assert_raise Minitest::Assertion do
  59 + assert_equivalent(a1, a2)
  60 + end
  61 + end
  62 +end
vendor/plugins/xss_terminate/lib/xss_terminate.rb
1 module XssTerminate 1 module XssTerminate
  2 + ALLOWED_CORE_ATTRIBUTES = %w(name href cite class title src xml:lang height datetime alt abbr width)
  3 + ALLOWED_CUSTOM_ATTRIBUTES = %w(data-macro)
2 4
3 def self.sanitize_by_default=(value) 5 def self.sanitize_by_default=(value)
4 @@sanitize_by_default = value 6 @@sanitize_by_default = value
@@ -38,21 +40,25 @@ module XssTerminate @@ -38,21 +40,25 @@ module XssTerminate
38 40
39 module InstanceMethods 41 module InstanceMethods
40 42
  43 + def sanitize_allowed_attributes
  44 + ALLOWED_CORE_ATTRIBUTES | ALLOWED_CUSTOM_ATTRIBUTES
  45 + end
  46 +
41 def sanitize_field(sanitizer, field, serialized = false) 47 def sanitize_field(sanitizer, field, serialized = false)
42 field = field.to_sym 48 field = field.to_sym
43 if serialized 49 if serialized
44 puts field 50 puts field
45 self[field].each_key { |key| 51 self[field].each_key { |key|
46 key = key.to_sym 52 key = key.to_sym
47 - self[field][key] = sanitizer.sanitize(self[field][key], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false) 53 + self[field][key] = sanitizer.sanitize(self[field][key], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes)
48 } 54 }
49 else 55 else
50 if self[field] 56 if self[field]
51 - self[field] = sanitizer.sanitize(self[field], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false) 57 + self[field] = sanitizer.sanitize(self[field], scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes)
52 else 58 else
53 value = self.send("#{field}") 59 value = self.send("#{field}")
54 return unless value 60 return unless value
55 - value = sanitizer.sanitize(value, scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false) 61 + value = sanitizer.sanitize(value, scrubber: Rails::Html::PermitScrubber.new, encode_special_chars: false, attributes: sanitize_allowed_attributes)
56 self.send("#{field}=", value) 62 self.send("#{field}=", value)
57 end 63 end
58 end 64 end