Commit 932d74f8b65c6cad2ed4db8f009d8237d604180c
Committed by
Joenio Costa
1 parent
56d303cc
Exists in
master
and in
23 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 | ... | ... |