Commit 932d74f8b65c6cad2ed4db8f009d8237d604180c
Committed by
Joenio Costa
1 parent
56d303cc
Exists in
master
and in
28 other branches
Added structure to add inputs to a product
* Created a new table inputs * For each consumption of a profile was created an input to each product of the profile * Removed consumptions table (ActionItem1435)
Showing
30 changed files
with
328 additions
and
107 deletions
Show diff stats
app/controllers/my_profile/manage_products_controller.rb
... | ... | @@ -18,7 +18,6 @@ class ManageProductsController < ApplicationController |
18 | 18 | |
19 | 19 | def index |
20 | 20 | @products = @profile.products |
21 | - @consumptions = @profile.consumptions | |
22 | 21 | end |
23 | 22 | |
24 | 23 | def show |
... | ... | @@ -38,7 +37,7 @@ class ManageProductsController < ApplicationController |
38 | 37 | end |
39 | 38 | |
40 | 39 | def new |
41 | - @product = @profile.products.build(params[:product]) | |
40 | + @product = @profile.products.build(:product_category_id => params[:selected_category_id]) | |
42 | 41 | @category = @product.product_category |
43 | 42 | @categories = ProductCategory.top_level_for(environment) |
44 | 43 | @level = 0 |
... | ... | @@ -75,12 +74,25 @@ class ManageProductsController < ApplicationController |
75 | 74 | @edit = true |
76 | 75 | @level = @category.level |
77 | 76 | if request.post? |
78 | - begin | |
79 | - @product.update_attributes!(params[:product]) | |
77 | + if @product.update_attributes(:product_category_id => params[:selected_category_id]) | |
80 | 78 | render :partial => 'shared/redirect_via_javascript', |
81 | 79 | :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } |
82 | - rescue Exception => e | |
83 | - flash[:notice] = _('Could not update the product') | |
80 | + else | |
81 | + render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } | |
82 | + end | |
83 | + end | |
84 | + end | |
85 | + | |
86 | + def add_input | |
87 | + @product = @profile.products.find(params[:id]) | |
88 | + @input = @product.inputs.build | |
89 | + @categories = ProductCategory.top_level_for(environment) | |
90 | + @level = 0 | |
91 | + if request.post? | |
92 | + if @input.update_attributes(:product_category_id => params[:selected_category_id]) | |
93 | + render :partial => 'shared/redirect_via_javascript', | |
94 | + :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } | |
95 | + else | |
84 | 96 | render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } |
85 | 97 | end |
86 | 98 | end | ... | ... |
app/helpers/manage_products_helper.rb
... | ... | @@ -89,8 +89,8 @@ module ManageProductsHelper |
89 | 89 | ) |
90 | 90 | end |
91 | 91 | |
92 | - def categories_container(field_id_html, categories_selection_html, hierarchy_html = '') | |
93 | - field_id_html + | |
92 | + def categories_container(categories_selection_html, hierarchy_html = '') | |
93 | + hidden_field_tag('selected_category_id') + | |
94 | 94 | content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') + |
95 | 95 | content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') |
96 | 96 | end |
... | ... | @@ -108,7 +108,13 @@ module ManageProductsHelper |
108 | 108 | end |
109 | 109 | end |
110 | 110 | |
111 | - def edit_product_link(product, field, label, html_options = {}) | |
111 | + def edit_product_link(field, label, url, html_options = {}) | |
112 | + return '' unless (user && user.has_permission?('manage_products', profile)) | |
113 | + options = html_options.merge(:id => "link-edit-#{field}") | |
114 | + link_to(label, url, options) | |
115 | + end | |
116 | + | |
117 | + def edit_product_link_to_remote(product, field, label, html_options = {}) | |
112 | 118 | return '' unless (user && user.has_permission?('manage_products', profile)) |
113 | 119 | options = html_options.merge(:id => 'link-edit-product-' + field) |
114 | 120 | |
... | ... | @@ -124,12 +130,18 @@ module ManageProductsHelper |
124 | 130 | if html_options.has_key?(:class) |
125 | 131 | the_class << ' ' << html_options[:class] |
126 | 132 | end |
127 | - edit_product_link(product, field, label, html_options.merge(:class => the_class)) | |
133 | + edit_product_link_to_remote(product, field, label, html_options.merge(:class => the_class)) | |
128 | 134 | end |
129 | 135 | |
130 | - def edit_product_ui_button(product, field, label, html_options = {}) | |
136 | + def edit_product_ui_button(field, label, url, html_options = {}) | |
131 | 137 | return '' unless (user && user.has_permission?('manage_products', profile)) |
132 | 138 | options = html_options.merge(:id => 'edit-product-button-ui-' + field) |
139 | + ui_button(label, url, options) | |
140 | + end | |
141 | + | |
142 | + def edit_product_ui_button_to_remote(product, field, label, html_options = {}) | |
143 | + return '' unless (user && user.has_permission?('manage_products', profile)) | |
144 | + options = html_options.merge(:id => 'edit-product-remote-button-ui-' + field) | |
133 | 145 | |
134 | 146 | ui_button_to_remote(label, |
135 | 147 | {:update => "product-#{field}", |
... | ... | @@ -146,12 +158,6 @@ module ManageProductsHelper |
146 | 158 | end |
147 | 159 | end |
148 | 160 | |
149 | - def edit_product_category_link(product, html_options = {}) | |
150 | - return '' unless (user && user.has_permission?('manage_products', profile)) | |
151 | - options = html_options.merge(:id => 'link-edit-product-category') | |
152 | - link_to(_('Change category'), { :action => 'edit_category', :id => product.id}, options) | |
153 | - end | |
154 | - | |
155 | 161 | def float_to_currency(value) |
156 | 162 | number_to_currency(value, :unit => environment.currency_unit, :separator => environment.currency_separator, :delimiter => environment.currency_delimiter, :format => "%u %n") |
157 | 163 | end | ... | ... |
app/models/consumption.rb
app/models/product.rb
... | ... | @@ -4,9 +4,11 @@ class Product < ActiveRecord::Base |
4 | 4 | has_many :product_categorizations |
5 | 5 | has_many :product_qualifiers |
6 | 6 | has_many :qualifiers, :through => :product_qualifiers |
7 | + has_many :inputs, :dependent => :destroy | |
7 | 8 | |
8 | 9 | validates_uniqueness_of :name, :scope => :enterprise_id, :allow_nil => true |
9 | - validates_presence_of :product_category | |
10 | + validates_presence_of :product_category_id | |
11 | + validates_associated :product_category | |
10 | 12 | |
11 | 13 | validates_numericality_of :price, :allow_nil => true |
12 | 14 | validates_numericality_of :discount, :allow_nil => true | ... | ... |
app/models/product_category.rb
1 | 1 | class ProductCategory < Category |
2 | 2 | has_many :products |
3 | - has_many :consumptions | |
4 | - has_many :consumers, :through => :consumptions, :source => :profile | |
3 | + has_many :inputs | |
5 | 4 | |
6 | 5 | def all_products |
7 | 6 | Product.find(:all, :conditions => { :product_category_id => (all_children << self).map(&:id) }) | ... | ... |
app/models/profile.rb
... | ... | @@ -120,9 +120,6 @@ class Profile < ActiveRecord::Base |
120 | 120 | |
121 | 121 | acts_as_having_image |
122 | 122 | |
123 | - has_many :consumptions | |
124 | - has_many :consumed_product_categories, :through => :consumptions, :source => :product_category | |
125 | - | |
126 | 123 | has_many :tasks, :dependent => :destroy, :as => 'target' |
127 | 124 | |
128 | 125 | has_many :events, :source => 'articles', :class_name => 'Event', :order => 'name' | ... | ... |
app/views/manage_products/_categories_for_selection.rhtml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | |
3 | 3 | <% javascript_tag do %> |
4 | 4 | jQuery('#categories_container_wrapper').scrollTo('100%', 1000) |
5 | - $('product_product_category_id').value = <%= @category && @category.id %> | |
5 | + $('selected_category_id').value = <%= @category && @category.id %> | |
6 | 6 | $('hierarchy_navigation').update('<%= escape_javascript(hierarchy_category_navigation(@category, :make_links => true)) %>') |
7 | 7 | toggleDisabled(<%= @category && @category.accept_products? ? 'true' : 'false' %>, $('save_and_continue')) |
8 | 8 | <% end %> | ... | ... |
app/views/manage_products/_display_category.rhtml
1 | 1 | <div id='display-product-category'> |
2 | 2 | <p><%= hierarchy_category_navigation(@product.product_category, :make_links => false)%></p> |
3 | - <%= edit_product_category_link(@product) %> | |
3 | + <%= edit_product_link('product-category', _('Change category'), { :action => 'edit_category', :id => @product.id}) %> | |
4 | 4 | </div> | ... | ... |
app/views/manage_products/_display_image.rhtml
... | ... | @@ -2,4 +2,4 @@ |
2 | 2 | <%= image_tag (@product.reload.image ? @product.image.public_filename : @product.default_image('thumb')), :class => 'product-pic' %> |
3 | 3 | </div> |
4 | 4 | |
5 | -<%= edit_product_link(@product, 'image', _('Change image')) %> | |
5 | +<%= edit_product_link_to_remote(@product, 'image', _('Change image')) %> | ... | ... |
app/views/manage_products/_display_info.rhtml
... | ... | @@ -9,6 +9,6 @@ |
9 | 9 | <% if @product.has_basic_info? %> |
10 | 10 | <%= edit_product_button(@product, 'info', _('Edit basic information')) %> |
11 | 11 | <% else %> |
12 | - <%= edit_product_ui_button(@product, 'info', _('Add description, price and other basic information'), :title => _('Click here to add description, price, discount and qualifiers/certifiers to make your product more attractive and detailed for the consumers'), 'data-primary-icon' => 'ui-icon-pencil', 'data-secondary-icon' => 'ui-icon-triangle-1-s') %> | |
13 | - <%= javascript_tag("render_jquery_ui_buttons('edit-product-button-ui-info')") %> | |
12 | + <%= edit_product_ui_button_to_remote(@product, 'info', _('Add description, price and other basic information'), :title => _('Click here to add description, price, discount and qualifiers/certifiers to make your product more attractive and detailed for the consumers'), 'data-primary-icon' => 'ui-icon-pencil', 'data-secondary-icon' => 'ui-icon-triangle-1-s') %> | |
13 | + <%= javascript_tag("render_jquery_ui_buttons('edit-product-remote-button-ui-info')") %> | |
14 | 14 | <% end%> | ... | ... |
... | ... | @@ -0,0 +1,2 @@ |
1 | +<%= edit_product_ui_button('inputs', _('Add the inputs used by this product'), {:action => 'add_input', :id => @product.id}, 'data-primary-icon' => 'ui-icon-pencil', 'data-secondary-icon' => 'ui-icon-triangle-1-s') %> | |
2 | +<%= javascript_tag("render_jquery_ui_buttons('edit-product-button-ui-inputs')") %> | ... | ... |
app/views/manage_products/_display_name.rhtml
... | ... | @@ -0,0 +1,33 @@ |
1 | +<div class=product-category-hierarchy> | |
2 | + <%= hierarchy_category_navigation(@product.product_category, :make_links => false)%> | |
3 | +</div> | |
4 | + | |
5 | +<div id="category-product-edition"> | |
6 | + | |
7 | + <h2><%= @product.name %></h2> | |
8 | + | |
9 | + <div id='request_result_message' style='display: none'></div> | |
10 | + | |
11 | + <% remote_form_for(@input, | |
12 | + :loading => "open_loading('#{ _('loading...') }')", | |
13 | + :update => "request_result_message", | |
14 | + :url => {:action => 'add_input', :id => @product, :field => 'category'}, | |
15 | + :html => {:method => 'post', :id => 'category_form'}) do |f| %> | |
16 | + | |
17 | + <h3><%= _('Choose an input to this product:') %></h3> | |
18 | + | |
19 | + <%= categories_container(select_for_new_category) %> | |
20 | + | |
21 | + <div id='categories_selection_actionbar'> | |
22 | + <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> | |
23 | + <span id='save_and_continue_wrapper'> | |
24 | + <%= submit_button(:save, _('Save and continue'), :id => 'save_and_continue') %> | |
25 | + <span class='tooltip' id='save_and_continue_disabled_tooltip'> | |
26 | + <%= ui_icon('ui-icon-alert') %> | |
27 | + <%= _('This category does not allow registration of products, select a more specific category') %> | |
28 | + </span> | |
29 | + </span> | |
30 | + </div> | |
31 | + | |
32 | + <% end %> | |
33 | +</div> | ... | ... |
app/views/manage_products/edit_category.rhtml
1 | 1 | <div class=product-category-hierarchy> |
2 | - <%= hierarchy_category_navigation(@product.product_category, :make_links => false)%> | |
2 | + <%= hierarchy_category_navigation(@category, :make_links => false)%> | |
3 | 3 | </div> |
4 | 4 | |
5 | 5 | <div id="category-product-edition"> |
... | ... | @@ -8,16 +8,15 @@ |
8 | 8 | |
9 | 9 | <div id='request_result_message' style='display: none'></div> |
10 | 10 | |
11 | - <% remote_form_for(:product, @product, | |
11 | + <% remote_form_for(@product, | |
12 | 12 | :loading => "open_loading('#{ _('loading...') }')", |
13 | - :loaded => "close_loading()", | |
14 | 13 | :update => "request_result_message", |
15 | - :url => {:action => 'edit_category', :id => @product, :field => 'category'}, | |
16 | - :html => {:method => 'post', :id => 'product_category_form'}) do |f| %> | |
14 | + :url => {:action => 'edit_category', :id => @product}, | |
15 | + :html => {:method => 'post', :id => 'category_form'}) do |f| %> | |
17 | 16 | |
18 | 17 | <h3><%= _('Edit category of this product:') %></h3> |
19 | 18 | |
20 | - <%= categories_container(f.hidden_field('product_category_id'), selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> | |
19 | + <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> | |
21 | 20 | |
22 | 21 | <div id='categories_selection_actionbar'> |
23 | 22 | <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> | ... | ... |
app/views/manage_products/new.rhtml
... | ... | @@ -6,11 +6,11 @@ |
6 | 6 | :loading => "open_loading('#{ _('loading...') }')", |
7 | 7 | :update => "request_result_message", |
8 | 8 | :url => {:action => 'new'}, |
9 | - :html => {:method => 'post', :id => 'product_category_form'} do |f| %> | |
9 | + :html => {:method => 'post', :id => 'category_form'} do |f| %> | |
10 | 10 | |
11 | 11 | <h3><%= _('Select the category of the new product or service') %></h3> |
12 | 12 | |
13 | - <%= categories_container(f.hidden_field('product_category_id'), select_for_new_category) %> | |
13 | + <%= categories_container(select_for_new_category) %> | |
14 | 14 | |
15 | 15 | <div id='categories_selection_actionbar'> |
16 | 16 | <%= button :back, _('Back to the product listing'), :action => 'index' %> | ... | ... |
app/views/manage_products/show.rhtml
... | ... | @@ -17,6 +17,10 @@ |
17 | 17 | <%= render :partial => 'manage_products/display_info', :locals => {:product => @product} %> |
18 | 18 | </div> |
19 | 19 | |
20 | + <div id='product-inputs'> | |
21 | + <%= render :partial => 'manage_products/display_inputs', :locals => {:product => @product} %> | |
22 | + </div> | |
23 | + | |
20 | 24 | </div> |
21 | 25 | </div> |
22 | 26 | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +class CreateInputs < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + create_table :inputs do |t| | |
4 | + t.references :product, :null => false | |
5 | + t.references :product_category, :null => false | |
6 | + | |
7 | + t.timestamps | |
8 | + end | |
9 | + end | |
10 | + | |
11 | + def self.down | |
12 | + drop_table :inputs | |
13 | + end | |
14 | +end | ... | ... |
db/migrate/20100719142737_move_consumptions_to_inputs_and_destroy_consumptions.rb
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +class MoveConsumptionsToInputsAndDestroyConsumptions < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + select_all('SELECT product_category_id, profile_id FROM consumptions').each do |consumption| | |
4 | + Profile.find(consumption['profile_id']).products.each do |product| | |
5 | + Input.create(:product_category_id => consumption['product_category_id'], :product_id => product.id) | |
6 | + end | |
7 | + end | |
8 | + drop_table :consumptions | |
9 | + end | |
10 | + | |
11 | + def self.down | |
12 | + say 'Warning: This migration cant recover data from old cunsumptions table' | |
13 | + create_table :consumptions do |t| | |
14 | + t.column :product_category_id, :integer | |
15 | + t.column :profile_id, :integer | |
16 | + t.column :aditional_specifications, :text | |
17 | + end | |
18 | + end | |
19 | +end | ... | ... |
db/schema.rb
... | ... | @@ -160,12 +160,6 @@ ActiveRecord::Schema.define(:version => 20100722020357) do |
160 | 160 | t.datetime "created_at" |
161 | 161 | end |
162 | 162 | |
163 | - create_table "consumptions", :force => true do |t| | |
164 | - t.integer "product_category_id" | |
165 | - t.integer "profile_id" | |
166 | - t.text "aditional_specifications" | |
167 | - end | |
168 | - | |
169 | 163 | create_table "domains", :force => true do |t| |
170 | 164 | t.string "name" |
171 | 165 | t.string "owner_type" |
... | ... | @@ -228,6 +222,13 @@ ActiveRecord::Schema.define(:version => 20100722020357) do |
228 | 222 | t.integer "height" |
229 | 223 | end |
230 | 224 | |
225 | + create_table "inputs", :force => true do |t| | |
226 | + t.integer "product_category_id", :null => false | |
227 | + t.integer "product_id", :null => false | |
228 | + t.datetime "created_at" | |
229 | + t.datetime "updated_at" | |
230 | + end | |
231 | + | |
231 | 232 | create_table "product_categorizations", :force => true do |t| |
232 | 233 | t.integer "category_id" |
233 | 234 | t.integer "product_id" | ... | ... |
features/manage_products.feature
... | ... | @@ -351,3 +351,37 @@ Feature: manage products |
351 | 351 | When I follow "Cancel" |
352 | 352 | Then I should see "A new red bicycle" |
353 | 353 | And I should be on Rede Moinho's page of product Bike |
354 | + | |
355 | + @selenium | |
356 | + Scenario: add an input to a product | |
357 | + Given the following product_category | |
358 | + | name | | |
359 | + | Food | | |
360 | + And the following product_categories | |
361 | + | name | parent | | |
362 | + | Cake | food | | |
363 | + | Sugar | food | | |
364 | + And the following products | |
365 | + | owner | category | name | | |
366 | + | redemoinho | cake | Chocolate cake | | |
367 | + And I am logged in as "joaosilva" | |
368 | + When I go to Rede Moinho's page of product Chocolate cake | |
369 | + And I follow "Add the inputs used by this product" | |
370 | + And I select "Food »" | |
371 | + And I select "Sugar" | |
372 | + And I press "Save and continue" | |
373 | + Then I should see "Sugar" | |
374 | + | |
375 | + @selenium | |
376 | + Scenario: cancel addition of a product input | |
377 | + Given the following product_category | |
378 | + | name | | |
379 | + | Food | | |
380 | + And the following products | |
381 | + | owner | category | name | | |
382 | + | redemoinho | food | Cake | | |
383 | + And I am logged in as "joaosilva" | |
384 | + When I go to Rede Moinho's page of product Cake | |
385 | + And I follow "Add the inputs used by this product" | |
386 | + When I follow "Back to product" | |
387 | + Then I should see "Cake" | ... | ... |
public/stylesheets/application.css
... | ... | @@ -2613,7 +2613,7 @@ div#activation_enterprise div { |
2613 | 2613 | list-style: none; |
2614 | 2614 | } |
2615 | 2615 | |
2616 | -#edit-product-button-ui-info { | |
2616 | +#edit-product-remote-button-ui-info { | |
2617 | 2617 | margin-top: 40px; |
2618 | 2618 | } |
2619 | 2619 | |
... | ... | @@ -2655,6 +2655,11 @@ div#activation_enterprise div { |
2655 | 2655 | #product-qualifiers-list .product-certifier-title { |
2656 | 2656 | margin-right: 20px; |
2657 | 2657 | } |
2658 | + | |
2659 | +#edit-product-button-ui-inputs { | |
2660 | + margin-top: 20px; | |
2661 | +} | |
2662 | + | |
2658 | 2663 | /* ==> public/stylesheets/controller_cms.css <== */ |
2659 | 2664 | |
2660 | 2665 | .controller-cms #article_types li { |
... | ... | @@ -3142,7 +3147,7 @@ h1#agenda-title { |
3142 | 3147 | |
3143 | 3148 | /* ==> public/stylesheets/controller_manage_products.css <== */ |
3144 | 3149 | |
3145 | -#product_category_form { | |
3150 | +#category_form { | |
3146 | 3151 | border: 1px solid #AABB88; |
3147 | 3152 | -moz-border-radius: 5px; |
3148 | 3153 | -webkit-border-radius: 5px; | ... | ... |
test/factories.rb
... | ... | @@ -330,4 +330,12 @@ module Noosfero::Factory |
330 | 330 | { :name => 'Product ' + factory_num_seq.to_s } |
331 | 331 | end |
332 | 332 | |
333 | + ############################################### | |
334 | + # Input | |
335 | + ############################################### | |
336 | + | |
337 | + def defaults_for_input | |
338 | + { } | |
339 | + end | |
340 | + | |
333 | 341 | end | ... | ... |
test/fixtures/consumptions.yml
test/functional/manage_products_controller_test.rb
... | ... | @@ -50,7 +50,7 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
50 | 50 | |
51 | 51 | should "create new product" do |
52 | 52 | assert_difference Product, :count do |
53 | - post 'new', :profile => @enterprise.identifier, :product => {:name => 'test product', :product_category_id => @product_category.id} | |
53 | + post 'new', :profile => @enterprise.identifier, :product => {:name => 'test product'}, :selected_category_id => @product_category.id | |
54 | 54 | assert assigns(:product) |
55 | 55 | assert !assigns(:product).new_record? |
56 | 56 | end |
... | ... | @@ -117,17 +117,16 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
117 | 117 | end |
118 | 118 | |
119 | 119 | should "not edit to invalid parameters" do |
120 | - product = fast_create(Product, :name => 'test product', :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
121 | - post 'edit_category', :profile => @enterprise.identifier, :product => {:product_category => nil}, :id => product.id | |
120 | + product = fast_create(Product, :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
121 | + post 'edit_category', :profile => @enterprise.identifier, :selected_category_id => nil, :id => product.id | |
122 | 122 | assert_response :success |
123 | - assert assigns(:product) | |
124 | - assert ! assigns(:product).valid? | |
123 | + assert_template 'shared/_dialog_error_messages' | |
125 | 124 | end |
126 | 125 | |
127 | 126 | should "destroy product" do |
128 | - p = @enterprise.products.create!(:name => 'test product', :product_category => @product_category) | |
127 | + product = fast_create(Product, :name => 'test product', :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
129 | 128 | assert_difference Product, :count, -1 do |
130 | - post 'destroy', :profile => @enterprise.identifier, :id => p.id | |
129 | + post 'destroy', :profile => @enterprise.identifier, :id => product.id | |
131 | 130 | assert_response :redirect |
132 | 131 | assert_redirected_to :action => 'index' |
133 | 132 | assert assigns(:product) |
... | ... | @@ -136,10 +135,10 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
136 | 135 | end |
137 | 136 | |
138 | 137 | should "fail to destroy product" do |
139 | - p = @enterprise.products.create!(:name => 'test product', :product_category => @product_category) | |
138 | + product = fast_create(Product, :name => 'test product', :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
140 | 139 | Product.any_instance.stubs(:destroy).returns(false) |
141 | 140 | assert_no_difference Product, :count do |
142 | - post 'destroy', :profile => @enterprise.identifier, :id => p.id | |
141 | + post 'destroy', :profile => @enterprise.identifier, :id => product.id | |
143 | 142 | assert_response :redirect |
144 | 143 | assert_redirected_to :action => 'show' |
145 | 144 | assert assigns(:product) |
... | ... | @@ -159,20 +158,20 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
159 | 158 | category1 = fast_create(ProductCategory, :name => 'Category 1') |
160 | 159 | category2 = fast_create(ProductCategory, :name => 'Category 2', :parent_id => category1) |
161 | 160 | assert_difference Product, :count do |
162 | - post 'new', :profile => @enterprise.identifier, :product => { :name => 'test product', :product_category_id => category2.id } | |
161 | + post 'new', :profile => @enterprise.identifier, :product => { :name => 'test product' }, :selected_category_id => category2.id | |
163 | 162 | assert_equal category2, assigns(:product).product_category |
164 | 163 | end |
165 | 164 | end |
166 | 165 | |
167 | 166 | should 'filter html from name of product' do |
168 | 167 | category = fast_create(ProductCategory, :name => 'Category 1') |
169 | - post 'new', :profile => @enterprise.identifier, :product => { :name => "<b id='html_name'>name bold</b>", :product_category_id => category.id } | |
168 | + post 'new', :profile => @enterprise.identifier, :product => { :name => "<b id='html_name'>name bold</b>" }, :selected_category_id => category.id | |
170 | 169 | assert_sanitized assigns(:product).name |
171 | 170 | end |
172 | 171 | |
173 | - should 'filter html with whit list from description of product' do | |
174 | - category = fast_create(ProductCategory, :name => 'Category 1') | |
175 | - post 'new', :profile => @enterprise.identifier, :product => { :name => 'name', :description => "<b id='html_descr'>descr bold</b>", :product_category_id => category.id } | |
172 | + should 'filter html with white list from description of product' do | |
173 | + product = fast_create(Product, :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
174 | + post 'edit', :profile => @enterprise.identifier, :id => product.id, :field => 'info', :product => { :name => 'name', :description => "<b id='html_descr'>descr bold</b>" } | |
176 | 175 | assert_equal "<b>descr bold</b>", assigns(:product).description |
177 | 176 | end |
178 | 177 | |
... | ... | @@ -235,7 +234,7 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
235 | 234 | |
236 | 235 | should 'render redirect_via_javascript template after save' do |
237 | 236 | assert_difference Product, :count do |
238 | - post :new, :profile => @enterprise.identifier, :product => { :name => 'Invalid product', :product_category_id => @product_category.id } | |
237 | + post :new, :profile => @enterprise.identifier, :product => { :name => 'Invalid product' }, :selected_category_id => @product_category.id | |
239 | 238 | assert_template 'shared/_redirect_via_javascript' |
240 | 239 | end |
241 | 240 | end |
... | ... | @@ -273,25 +272,37 @@ class ManageProductsControllerTest < Test::Unit::TestCase |
273 | 272 | end |
274 | 273 | |
275 | 274 | should 'show product price when showing product if unit was informed' do |
276 | - prod = @enterprise.products.create!(:name => 'Product test', :price => 50.00, :unit => 'unit', :product_category => @product_category) | |
277 | - get :show, :id => prod.id, :profile => @enterprise.identifier | |
275 | + product = fast_create(Product, :name => 'test product', :price => 50.00, :unit => 'unit', :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
276 | + get :show, :id => product.id, :profile => @enterprise.identifier | |
278 | 277 | |
279 | 278 | assert_tag :tag => 'span', :attributes => { :class => 'field-name' }, :content => /Price:/ |
279 | + assert_tag :tag => 'span', :attributes => { :class => 'field-value' }, :content => '$ 50.00' | |
280 | 280 | end |
281 | 281 | |
282 | 282 | should 'show product price when showing product if discount was informed' do |
283 | - prod = @enterprise.products.create!(:name => 'Product test', :price => 50.00, :discount => 3.50, :unit => 'unit', :product_category => @product_category) | |
284 | - get :show, :id => prod.id, :profile => @enterprise.identifier | |
283 | + product = fast_create(Product, :name => 'test product', :price => 50.00, :unit => 'unit', :discount => 3.50, :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
284 | + get :show, :id => product.id, :profile => @enterprise.identifier | |
285 | 285 | |
286 | 286 | assert_tag :tag => 'span', :attributes => { :class => 'field-name' }, :content => /List price:/ |
287 | + assert_tag :tag => 'span', :attributes => { :class => 'field-value' }, :content => '$ 50.00' | |
287 | 288 | assert_tag :tag => 'span', :attributes => { :class => 'field-name' }, :content => /On sale:/ |
289 | + assert_tag :tag => 'span', :attributes => { :class => 'field-value' }, :content => '$ 46.50' | |
288 | 290 | end |
289 | 291 | |
290 | 292 | should 'not show product price when showing product if unit not informed' do |
291 | - prod = @enterprise.products.create!(:name => 'Product test', :price => 50.00, :product_category => @product_category) | |
292 | - get :show, :id => prod.id, :profile => @enterprise.identifier | |
293 | + product = fast_create(Product, :name => 'test product', :price => 50.00, :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
294 | + get :show, :id => product.id, :profile => @enterprise.identifier | |
293 | 295 | |
294 | - assert_no_tag :tag => 'span', :attributes => { :class => 'product_price' }, :content => /Price:/ | |
296 | + assert_no_tag :tag => 'span', :attributes => { :class => 'field-name' }, :content => /Price:/ | |
297 | + assert_no_tag :tag => 'span', :attributes => { :class => 'field-value' }, :content => '$ 50.00' | |
298 | + end | |
299 | + | |
300 | + should 'display button to add input when product has no input' do | |
301 | + product = fast_create(Product, :name => 'test product', :enterprise_id => @enterprise.id, :product_category_id => @product_category.id) | |
302 | + get :show, :id => product.id, :profile => @enterprise.identifier | |
303 | + | |
304 | + assert_tag :tag => 'div', :attributes => { :id => 'product-inputs'}, | |
305 | + :descendant => {:tag => 'a', :attributes => { :id => 'edit-product-button-ui-inputs' }, :content => 'Add the inputs used by this product'} | |
295 | 306 | end |
296 | 307 | |
297 | 308 | end | ... | ... |
test/unit/consumption_test.rb
... | ... | @@ -1,14 +0,0 @@ |
1 | -require File.dirname(__FILE__) + '/../test_helper' | |
2 | - | |
3 | -class ConsumptionTest < Test::Unit::TestCase | |
4 | - fixtures :consumptions | |
5 | - | |
6 | - should 'escape malformed html tags' do | |
7 | - consumption = Consumption.new | |
8 | - consumption.aditional_specifications = "<h1 Malformed >> html >< tag" | |
9 | - consumption.valid? | |
10 | - | |
11 | - assert_no_match /[<>]/, consumption.aditional_specifications | |
12 | - end | |
13 | - | |
14 | -end |
... | ... | @@ -0,0 +1,30 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class InputTest < Test::Unit::TestCase | |
4 | + | |
5 | + should 'require product_category' do | |
6 | + product_category = fast_create(ProductCategory, :name => 'Products') | |
7 | + | |
8 | + input = Input.new | |
9 | + input.valid? | |
10 | + assert input.errors.invalid?(:product_category) | |
11 | + | |
12 | + input.product_category = product_category | |
13 | + input.valid? | |
14 | + assert !input.errors.invalid?(:product_category) | |
15 | + end | |
16 | + | |
17 | + should 'require product' do | |
18 | + product_category = fast_create(ProductCategory, :name => 'Products') | |
19 | + product = fast_create(Product, :name => 'Computer', :product_category_id => product_category.id) | |
20 | + | |
21 | + input = Input.new | |
22 | + input.valid? | |
23 | + assert input.errors.invalid?(:product) | |
24 | + | |
25 | + input.product = product | |
26 | + input.valid? | |
27 | + assert !input.errors.invalid?(:product) | |
28 | + end | |
29 | + | |
30 | +end | ... | ... |
test/unit/manage_products_helper_test.rb
... | ... | @@ -55,7 +55,7 @@ class ManageProductsHelperTest < Test::Unit::TestCase |
55 | 55 | @controller.expects(:profile).returns(mock) |
56 | 56 | category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) |
57 | 57 | product = fast_create(Product, :product_category_id => category.id) |
58 | - assert_equal '', edit_product_link(product, 'field', 'link to edit') | |
58 | + assert_equal '', edit_product_link_to_remote(product, 'field', 'link to edit') | |
59 | 59 | end |
60 | 60 | |
61 | 61 | should 'display link to edit product when user has permission' do |
... | ... | @@ -69,7 +69,7 @@ class ManageProductsHelperTest < Test::Unit::TestCase |
69 | 69 | |
70 | 70 | expects(:link_to_remote).with('link to edit', {:update => "product-name", :url => {:controller => 'manage_products', :action => 'edit', :id => product.id, :field => 'name'}, :method => :get}, anything).returns('LINK') |
71 | 71 | |
72 | - assert_equal 'LINK', edit_product_link(product, 'name', 'link to edit') | |
72 | + assert_equal 'LINK', edit_product_link_to_remote(product, 'name', 'link to edit') | |
73 | 73 | end |
74 | 74 | |
75 | 75 | should 'not display link to edit product category when user does not have permission' do |
... | ... | @@ -80,7 +80,7 @@ class ManageProductsHelperTest < Test::Unit::TestCase |
80 | 80 | @controller.expects(:profile).returns(mock) |
81 | 81 | category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) |
82 | 82 | product = fast_create(Product, :product_category_id => category.id) |
83 | - assert_equal '', edit_product_category_link(product) | |
83 | + assert_equal '', edit_product_link('product-category', 'link to edit category', { :action => 'edit_category', :id => product.id }) | |
84 | 84 | end |
85 | 85 | |
86 | 86 | should 'display link to edit product category when user has permission' do |
... | ... | @@ -92,7 +92,49 @@ class ManageProductsHelperTest < Test::Unit::TestCase |
92 | 92 | category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) |
93 | 93 | product = fast_create(Product, :product_category_id => category.id) |
94 | 94 | |
95 | - assert_tag_in_string edit_product_category_link(product), {:tag => 'a', :content => 'Change category'} | |
95 | + expects(:link_to).with('link to edit category', { :action => 'edit_category', :id => product.id }, {:id => 'link-edit-product-category'} ).returns('LINK') | |
96 | + | |
97 | + assert_equal 'LINK', edit_product_link('product-category', 'link to edit category', { :action => 'edit_category', :id => product.id }) | |
98 | + end | |
99 | + | |
100 | + should 'not display ui_button to edit product when user does not have permission' do | |
101 | + user = mock | |
102 | + user.expects(:has_permission?).with(anything, anything).returns(false) | |
103 | + @controller = mock | |
104 | + @controller.expects(:user).returns(user).at_least_once | |
105 | + @controller.expects(:profile).returns(mock) | |
106 | + category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) | |
107 | + product = fast_create(Product, :product_category_id => category.id) | |
108 | + assert_equal '', edit_product_ui_button(product, 'field', 'link to edit') | |
109 | + end | |
110 | + | |
111 | + should 'display ui_button_to_remote to edit product when user has permission' do | |
112 | + user = mock | |
113 | + user.expects(:has_permission?).with(anything, anything).returns(true) | |
114 | + @controller = mock | |
115 | + @controller.expects(:user).returns(user).at_least_once | |
116 | + @controller.expects(:profile).returns(mock) | |
117 | + category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) | |
118 | + product = fast_create(Product, :product_category_id => category.id) | |
119 | + | |
120 | + expects(:ui_button_to_remote).with('link to edit', {:update => "product-info", :url => {:controller => 'manage_products', :action => 'edit', :id => product.id, :field => 'info'}, :complete => "$('edit-product-button-ui-info').hide()", :method => :get}, :id => 'edit-product-remote-button-ui-info').returns('LINK') | |
121 | + | |
122 | + assert_equal 'LINK', edit_product_ui_button_to_remote(product, 'info', 'link to edit') | |
123 | + end | |
124 | + | |
125 | + | |
126 | + should 'display ui_button to edit product when user has permission' do | |
127 | + user = mock | |
128 | + user.expects(:has_permission?).with(anything, anything).returns(true) | |
129 | + @controller = mock | |
130 | + @controller.expects(:user).returns(user).at_least_once | |
131 | + @controller.expects(:profile).returns(mock) | |
132 | + category = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id) | |
133 | + product = fast_create(Product, :product_category_id => category.id) | |
134 | + | |
135 | + expects(:ui_button).with('link to edit', { :action => 'add_input', :id => product.id }, {:id => 'edit-product-button-ui-info'}).returns('LINK') | |
136 | + | |
137 | + assert_equal 'LINK', edit_product_ui_button('info', 'link to edit', {:action => 'add_input', :id => product.id}) | |
96 | 138 | end |
97 | 139 | |
98 | 140 | protected | ... | ... |
test/unit/product_category_test.rb
... | ... | @@ -17,13 +17,6 @@ class ProductCategoryTest < Test::Unit::TestCase |
17 | 17 | assert_equivalent [p1], c1.all_products |
18 | 18 | end |
19 | 19 | |
20 | - should 'have consumers' do | |
21 | - c = ProductCategory.create!(:name => 'base_cat', :environment => Environment.default) | |
22 | - person = create_user('test_user').person | |
23 | - c.consumers << person | |
24 | - assert_includes c.consumers, person | |
25 | - end | |
26 | - | |
27 | 20 | should 'return top level product categories for environment when no parent product category specified' do |
28 | 21 | env1 = Environment.create!(:name => 'test env 1') |
29 | 22 | env2 = Environment.create!(:name => 'test env 2') | ... | ... |
test/unit/product_test.rb
... | ... | @@ -241,7 +241,7 @@ class ProductTest < Test::Unit::TestCase |
241 | 241 | should 'not save without category' do |
242 | 242 | product = Product.new(:name => 'A product without category') |
243 | 243 | product.valid? |
244 | - assert product.errors.invalid?(:product_category) | |
244 | + assert product.errors.invalid?(:product_category_id) | |
245 | 245 | end |
246 | 246 | |
247 | 247 | should 'format values to float with 2 decimals' do |
... | ... | @@ -263,4 +263,35 @@ class ProductTest < Test::Unit::TestCase |
263 | 263 | product = Product.new |
264 | 264 | assert_equal '/images/icons-app/product-default-pic-thumb.png', product.default_image |
265 | 265 | end |
266 | + | |
267 | + should 'have inputs' do | |
268 | + product = Product.new | |
269 | + assert_respond_to product, :inputs | |
270 | + end | |
271 | + | |
272 | + should 'return empty array if has no input' do | |
273 | + product = Product.new | |
274 | + assert product.inputs.empty? | |
275 | + end | |
276 | + | |
277 | + should 'return product inputs' do | |
278 | + ent = fast_create(Enterprise) | |
279 | + product = fast_create(Product, :enterprise_id => ent.id) | |
280 | + input = fast_create(Input, :product_id => product.id, :product_category_id => @product_category.id) | |
281 | + | |
282 | + assert_equal [input], product.inputs | |
283 | + end | |
284 | + | |
285 | + should 'destroy inputs when product is removed' do | |
286 | + ent = fast_create(Enterprise) | |
287 | + product = fast_create(Product, :enterprise_id => ent.id) | |
288 | + input = fast_create(Input, :product_id => product.id, :product_category_id => @product_category.id) | |
289 | + | |
290 | + services_category = fast_create(ProductCategory, :name => 'Services') | |
291 | + input2 = fast_create(Input, :product_id => product.id, :product_category_id => services_category.id) | |
292 | + | |
293 | + assert_difference Input, :count, -2 do | |
294 | + product.destroy | |
295 | + end | |
296 | + end | |
266 | 297 | end | ... | ... |