Commit 1e4063df909242eb8f9dc4cd157041fd87613943
Committed by
Joenio Costa
1 parent
b361aebc
Exists in
master
and in
29 other branches
Create a block to make the products highlighted:
* This block must be available to Enterprises and the enterprise administrator could choose what products will be highlighted * The environment could have this block and in this case the products are choosen randomically (ActionItem1576)
Showing
21 changed files
with
586 additions
and
8 deletions
Show diff stats
app/controllers/admin/environment_design_controller.rb
... | ... | @@ -3,7 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController |
3 | 3 | protect 'edit_environment_design', :environment |
4 | 4 | |
5 | 5 | def available_blocks |
6 | - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock ] | |
6 | + @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock ] | |
7 | 7 | end |
8 | 8 | |
9 | 9 | end | ... | ... |
app/controllers/my_profile/profile_design_controller.rb
... | ... | @@ -24,6 +24,7 @@ class ProfileDesignController < BoxOrganizerController |
24 | 24 | if profile.enterprise? |
25 | 25 | blocks << DisabledEnterpriseMessageBlock |
26 | 26 | blocks << HighlightsBlock |
27 | + blocks << FeaturedProductsBlock | |
27 | 28 | end |
28 | 29 | |
29 | 30 | # product block exclusive for enterprises in environments that permits it | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -960,4 +960,9 @@ module ApplicationHelper |
960 | 960 | text_field_tag(name, value, options.merge(:class => 'colorpicker_field')) |
961 | 961 | end |
962 | 962 | |
963 | + # for now force currency to Brazillian format, like: "12.345,20" | |
964 | + def float_to_currency(price) | |
965 | + number_to_currency(price, :unit => 'R$', :separator => ',', :delimiter => '.') | |
966 | + end | |
967 | + | |
963 | 968 | end | ... | ... |
app/models/enterprise.rb
... | ... | @@ -51,6 +51,10 @@ class Enterprise < Organization |
51 | 51 | environment ? environment.active_enterprise_fields : [] |
52 | 52 | end |
53 | 53 | |
54 | + def highlighted_products_with_image(options = {}) | |
55 | + Product.find(:all, {:conditions => {:highlighted => true}, :joins => :image}.merge(options)) | |
56 | + end | |
57 | + | |
54 | 58 | def required_fields |
55 | 59 | environment ? environment.required_enterprise_fields : [] |
56 | 60 | end | ... | ... |
app/models/environment.rb
... | ... | @@ -628,4 +628,9 @@ class Environment < ActiveRecord::Base |
628 | 628 | end |
629 | 629 | end |
630 | 630 | |
631 | + def highlighted_products_with_image(options = {}) | |
632 | + Product.find(:all, {:conditions => {:highlighted => true, :enterprise_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options)) | |
633 | + end | |
634 | + | |
631 | 635 | end |
636 | + | ... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +class FeaturedProductsBlock < Block | |
2 | + | |
3 | + settings_items :product_ids, :type => Array, :default => [] | |
4 | + settings_items :groups_of, :type => :integer, :default => 3 | |
5 | + settings_items :speed, :type => :integer, :default => 1000 | |
6 | + settings_items :reflect, :type => :boolean, :default => true | |
7 | + | |
8 | + before_save do |block| | |
9 | + if block.owner.kind_of?(Environment) && block.product_ids.blank? | |
10 | + seed = block.owner.products.count | |
11 | + block.product_ids = block.owner.highlighted_products_with_image(:offset => (rand(seed) % (seed - block.groups_of * 3)), :limit => block.groups_of * 3).map(&:id) | |
12 | + end | |
13 | + block.groups_of = block.groups_of.to_i | |
14 | + end | |
15 | + | |
16 | + def self.description | |
17 | + _('Featured Products') | |
18 | + end | |
19 | + | |
20 | + def products | |
21 | + Product.find(self.product_ids) || [] | |
22 | + end | |
23 | + | |
24 | + def products_for_selection | |
25 | + self.owner.highlighted_products_with_image | |
26 | + end | |
27 | + | |
28 | + def content | |
29 | + block = self | |
30 | + lambda do | |
31 | + render :file => 'blocks/featured_products', :locals => { :block => block } | |
32 | + end | |
33 | + end | |
34 | + | |
35 | +end | ... | ... |
... | ... | @@ -0,0 +1,55 @@ |
1 | +<%= block_title(block.title) %> | |
2 | +<% unless block.products.blank? %> | |
3 | + <%= link_to content_tag(:span, _('Previous')), '#', :class => 'featured-product-prev featured-product-arrow' %> | |
4 | + <div class="featured-products-block-container"> | |
5 | + <ul class="featured-products-list"> | |
6 | + <% block.products.in_groups_of(block.groups_of).each do |group| %> | |
7 | + <li class="featured-products-group"> | |
8 | + <div class="featured-product-items"> | |
9 | + <ul> | |
10 | + <% group.reject{ |x| x.nil? }.each_with_index do |p, i| %> | |
11 | + <li class="featured-product-item"> | |
12 | + <%= link_to content_tag(:img, nil, :src => p.image.public_filename(:thumb), :alt => p.name, :class => ('reflect' if block.reflect)), product_path(p.enterprise.identifier, p), :class => 'featured-product-image' %> | |
13 | + <div class="featured-product-info position-<%= i + 1 %>" style="display: none"> | |
14 | + <div class="featured-product-text"> | |
15 | + <h3><%= p.name %></h3> | |
16 | + <p class="featured-product-price"><%= float_to_currency(p.price) %></p> | |
17 | + <p class="featured-product-desc"><%= p.description.chars[0...50].to_s + '...' %></p> | |
18 | + <p><%= link_to _('See More'), product_path(p.enterprise.identifier, p), :class => 'featured-product-link' %></p> | |
19 | + </div> | |
20 | + </div> | |
21 | + </li> | |
22 | + <% end %> | |
23 | + </ul> | |
24 | + </div> | |
25 | + </li> | |
26 | + <% end %> | |
27 | + </ul> | |
28 | + </div> | |
29 | + <%= link_to content_tag(:span, _('Next')), '#', :class => 'featured-product-next featured-product-arrow' %> | |
30 | + <script type="text/javascript"> | |
31 | + (function($) { | |
32 | + var options = { | |
33 | + fx : 'scrollHorz', | |
34 | + timeout: 0, | |
35 | + prev: '#block-<%= block.id %> .featured-product-prev', | |
36 | + next: '#block-<%= block.id %> .featured-product-next', | |
37 | + speed: <%= block.speed || 2000 %> | |
38 | + } | |
39 | + $('#block-<%= block.id %> .featured-products-list').cycle(options); | |
40 | + | |
41 | + $(document).ready(function(){ | |
42 | + $(".featured-product-item").hover( | |
43 | + function() { | |
44 | + $(".featured-product-info", this).fadeIn('slow'); | |
45 | + }, | |
46 | + function() { | |
47 | + $(".featured-product-info", this).fadeOut('slow'); | |
48 | + }); | |
49 | + }); | |
50 | + })(jQuery); | |
51 | + </script> | |
52 | + <p class="featured-products-footer"></p> | |
53 | +<% else %> | |
54 | + <em><%= _('Please, edit this block and choose some products') %></em> | |
55 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +<strong><%= _('Featured Products') %></strong> | |
2 | +<div id='edit-featured-products-block'> | |
3 | + <p><%= label_tag _('Choose some products') %></p> | |
4 | + <p><%= select_tag 'block[product_ids][]', options_for_select(@block.products_for_selection.map{|p| [p.name, p.id.to_s]}, @block.product_ids), :multiple => true %></p> | |
5 | + <p><%= labelled_form_field check_box(:block, :reflect) + _('Reflect products'), '' %></p> | |
6 | + <p><%= labelled_form_field(_('Transition speed (in seconds)'), select('block', 'speed', (1..10).to_a.collect{|i| [i, i*1000] })) %> | |
7 | + <p><%= labelled_form_field(_('In groups of'), select('block', 'groups_of', (1..10).to_a)) %> | |
8 | +</div> | ... | ... |
app/views/layouts/_javascript.rhtml
1 | -<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', :cache => 'cache-general' %> | |
1 | +<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', 'reflection', :cache => 'cache-general' %> | ... | ... |
app/views/manage_products/_form.rhtml
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | <%= required display_form_field( _('Name:'), f.text_field(:name) ) %> |
7 | 7 | <%= display_form_field( _('Price:'), f.text_field(:price) ) %> |
8 | 8 | <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %> |
9 | + <%= labelled_form_field(f.check_box(:highlighted) + _('Highlight this product'),'') %> | |
9 | 10 | <% f.fields_for :image_builder, @product.image do |i| %> |
10 | 11 | <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %> |
11 | 12 | <% end %> | ... | ... |
db/schema.rb
... | ... | @@ -9,7 +9,8 @@ |
9 | 9 | # |
10 | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | |
12 | -ActiveRecord::Schema.define(:version => 20100514133346) do | |
12 | + | |
13 | +ActiveRecord::Schema.define(:version => 20100619031945) do | |
13 | 14 | |
14 | 15 | create_table "article_versions", :force => true do |t| |
15 | 16 | t.integer "article_id" |
... | ... | @@ -240,6 +241,7 @@ ActiveRecord::Schema.define(:version => 20100514133346) do |
240 | 241 | t.datetime "updated_at" |
241 | 242 | t.float "lat" |
242 | 243 | t.float "lng" |
244 | + t.boolean "highlighted" | |
243 | 245 | end |
244 | 246 | |
245 | 247 | add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id" | ... | ... |
... | ... | @@ -0,0 +1,177 @@ |
1 | +/** | |
2 | + * reflection.js v2.0 | |
3 | + * http://cow.neondragon.net/stuff/reflection/ | |
4 | + * Freely distributable under MIT-style license. | |
5 | + */ | |
6 | + | |
7 | +/* From prototype.js */ | |
8 | +if (!document.myGetElementsByClassName) { | |
9 | + document.myGetElementsByClassName = function(className) { | |
10 | + var children = document.getElementsByTagName('*') || document.all; | |
11 | + var elements = new Array(); | |
12 | + | |
13 | + for (var i = 0; i < children.length; i++) { | |
14 | + var child = children[i]; | |
15 | + var classNames = child.className.split(' '); | |
16 | + for (var j = 0; j < classNames.length; j++) { | |
17 | + if (classNames[j] == className) { | |
18 | + elements.push(child); | |
19 | + break; | |
20 | + } | |
21 | + } | |
22 | + } | |
23 | + return elements; | |
24 | + } | |
25 | +} | |
26 | + | |
27 | +var Reflection = { | |
28 | + defaultHeight : 0.5, | |
29 | + defaultOpacity: 0.5, | |
30 | + | |
31 | + add: function(image, options) { | |
32 | + Reflection.remove(image); | |
33 | + | |
34 | + doptions = { "height" : Reflection.defaultHeight, "opacity" : Reflection.defaultOpacity } | |
35 | + if (options) { | |
36 | + for (var i in doptions) { | |
37 | + if (!options[i]) { | |
38 | + options[i] = doptions[i]; | |
39 | + } | |
40 | + } | |
41 | + } else { | |
42 | + options = doptions; | |
43 | + } | |
44 | + | |
45 | + try { | |
46 | + var d = document.createElement('div'); | |
47 | + var p = image; | |
48 | + | |
49 | + var classes = p.className.split(' '); | |
50 | + var newClasses = ''; | |
51 | + for (j=0;j<classes.length;j++) { | |
52 | + if (classes[j] != "reflect") { | |
53 | + if (newClasses) { | |
54 | + newClasses += ' ' | |
55 | + } | |
56 | + | |
57 | + newClasses += classes[j]; | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + var reflectionHeight = Math.floor(p.height*options['height']); | |
62 | + var divHeight = Math.floor(p.height*(1+options['height'])); | |
63 | + | |
64 | + var reflectionWidth = p.width; | |
65 | + | |
66 | + if (document.all && !window.opera) { | |
67 | + /* Fix hyperlinks */ | |
68 | + if(p.parentElement.tagName == 'A') { | |
69 | + var d = document.createElement('a'); | |
70 | + d.href = p.parentElement.href; | |
71 | + } | |
72 | + | |
73 | + /* Copy original image's classes & styles to div */ | |
74 | + d.className = newClasses; | |
75 | + p.className = 'reflected'; | |
76 | + | |
77 | + d.style.cssText = p.style.cssText; | |
78 | + p.style.cssText = 'vertical-align: bottom'; | |
79 | + | |
80 | + var reflection = document.createElement('img'); | |
81 | + reflection.src = p.src; | |
82 | + reflection.style.width = reflectionWidth+'px'; | |
83 | + reflection.style.display = 'block'; | |
84 | + reflection.style.height = p.height+"px"; | |
85 | + | |
86 | + reflection.style.marginBottom = "-"+(p.height-reflectionHeight)+'px'; | |
87 | + reflection.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity='+(options['opacity']*100)+', style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy='+(options['height']*100)+')'; | |
88 | + | |
89 | + d.style.width = reflectionWidth+'px'; | |
90 | + d.style.height = divHeight+'px'; | |
91 | + p.parentNode.replaceChild(d, p); | |
92 | + | |
93 | + d.appendChild(p); | |
94 | + d.appendChild(reflection); | |
95 | + } else { | |
96 | + var canvas = document.createElement('canvas'); | |
97 | + if (canvas.getContext) { | |
98 | + /* Copy original image's classes & styles to div */ | |
99 | + d.className = newClasses; | |
100 | + p.className = 'reflected'; | |
101 | + | |
102 | + d.style.cssText = p.style.cssText; | |
103 | + p.style.cssText = 'vertical-align: bottom'; | |
104 | + | |
105 | + var context = canvas.getContext("2d"); | |
106 | + | |
107 | + canvas.style.height = reflectionHeight+'px'; | |
108 | + canvas.style.width = reflectionWidth+'px'; | |
109 | + canvas.height = reflectionHeight; | |
110 | + canvas.width = reflectionWidth; | |
111 | + | |
112 | + d.style.width = reflectionWidth+'px'; | |
113 | + d.style.height = divHeight+'px'; | |
114 | + p.parentNode.replaceChild(d, p); | |
115 | + | |
116 | + d.appendChild(p); | |
117 | + d.appendChild(canvas); | |
118 | + | |
119 | + context.save(); | |
120 | + | |
121 | + context.translate(0,image.height-1); | |
122 | + context.scale(1,-1); | |
123 | + | |
124 | + context.drawImage(image, 0, 0, reflectionWidth, image.height); | |
125 | + | |
126 | + context.restore(); | |
127 | + | |
128 | + context.globalCompositeOperation = "destination-out"; | |
129 | + var gradient = context.createLinearGradient(0, 0, 0, reflectionHeight); | |
130 | + | |
131 | + gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)"); | |
132 | + gradient.addColorStop(0, "rgba(255, 255, 255, "+(1-options['opacity'])+")"); | |
133 | + | |
134 | + context.fillStyle = gradient; | |
135 | + context.rect(0, 0, reflectionWidth, reflectionHeight*2); | |
136 | + context.fill(); | |
137 | + } | |
138 | + } | |
139 | + } catch (e) { | |
140 | + } | |
141 | + }, | |
142 | + | |
143 | + remove : function(image) { | |
144 | + if (image.className == "reflected") { | |
145 | + image.className = image.parentNode.className; | |
146 | + image.parentNode.parentNode.replaceChild(image, image.parentNode); | |
147 | + } | |
148 | + } | |
149 | +} | |
150 | + | |
151 | +function addReflections() { | |
152 | + var rimages = document.myGetElementsByClassName('reflect'); | |
153 | + for (i=0;i<rimages.length;i++) { | |
154 | + var rheight = null; | |
155 | + var ropacity = null; | |
156 | + | |
157 | + var classes = rimages[i].className.split(' '); | |
158 | + for (j=0;j<classes.length;j++) { | |
159 | + if (classes[j].indexOf("rheight") == 0) { | |
160 | + var rheight = classes[j].substring(7)/100; | |
161 | + } else if (classes[j].indexOf("ropacity") == 0) { | |
162 | + var ropacity = classes[j].substring(8)/100; | |
163 | + } | |
164 | + } | |
165 | + | |
166 | + Reflection.add(rimages[i], { height: rheight, opacity : ropacity}); | |
167 | + } | |
168 | +} | |
169 | + | |
170 | +if (window.addEventListener) { // DOM method for binding an event | |
171 | + window.addEventListener("load", addReflections, false); | |
172 | +} else if (window.attachEvent) { // IE exclusive method for binding an event | |
173 | + window.attachEvent("onload", addReflections); | |
174 | +} else { // Support older browsers | |
175 | + var previousOnload = window.onload; | |
176 | + window.onload = function() { if (previousOnload) previousOnload(); addReflections(); } | |
177 | +} | ... | ... |
public/stylesheets/application.css
... | ... | @@ -3692,3 +3692,110 @@ h1#agenda-title { |
3692 | 3692 | .highlights-image-link { |
3693 | 3693 | border: 1px solid #ccc; |
3694 | 3694 | } |
3695 | + | |
3696 | +/* Featured Products stuff */ | |
3697 | + | |
3698 | +.featured-product-items { | |
3699 | + width: 100%; | |
3700 | + display: table; | |
3701 | + margin: 0 auto; | |
3702 | + text-align: center; | |
3703 | +} | |
3704 | + | |
3705 | +.featured-product-items ul { | |
3706 | + display: table-row; | |
3707 | +} | |
3708 | + | |
3709 | +.featured-product-item { | |
3710 | + list-style-type: none; | |
3711 | + display: table-cell !important; | |
3712 | +} | |
3713 | + | |
3714 | +.featured-product-item div { | |
3715 | + margin: 0 auto; | |
3716 | +} | |
3717 | + | |
3718 | +.featured-products-list { | |
3719 | + padding: 0; | |
3720 | +} | |
3721 | + | |
3722 | +.featured-product-arrow { | |
3723 | + float: left; | |
3724 | + width: 20px; | |
3725 | + background-repeat: no-repeat; | |
3726 | + height: 160px; | |
3727 | + background-position: center 55px; | |
3728 | +} | |
3729 | + | |
3730 | +.featured-product-arrow span { | |
3731 | + display: none; | |
3732 | +} | |
3733 | + | |
3734 | +.featured-product-prev { | |
3735 | + background-image: url(/designs/icons/tango/Tango/16x16/actions/go-previous.png); | |
3736 | +} | |
3737 | + | |
3738 | +.featured-product-next { | |
3739 | + background-image: url(/designs/icons/tango/Tango/16x16/actions/go-next.png); | |
3740 | +} | |
3741 | + | |
3742 | +.featured-products-block-container { | |
3743 | + width: 92%; | |
3744 | +} | |
3745 | + | |
3746 | +.box-2 .featured-products-block-container, | |
3747 | +.box-3 .featured-products-block-container { | |
3748 | + width: 78%; | |
3749 | +} | |
3750 | + | |
3751 | +.featured-products-group { | |
3752 | + width: 100%; | |
3753 | + margin: 0 auto; | |
3754 | + text-align: center; | |
3755 | +} | |
3756 | + | |
3757 | +.featured-product-desc { | |
3758 | + display: none; | |
3759 | +} | |
3760 | + | |
3761 | +.featured-products-block-container, | |
3762 | +.featured-products-group { | |
3763 | + overflow: hidden; | |
3764 | + float: left; | |
3765 | + height: 160px; | |
3766 | + position: relative; | |
3767 | +} | |
3768 | + | |
3769 | +.featured-products-group ul { | |
3770 | + padding: 0; | |
3771 | + padding-left: 4px; | |
3772 | +} | |
3773 | + | |
3774 | +.featured-products-footer { | |
3775 | + clear: both; | |
3776 | +} | |
3777 | + | |
3778 | +.featured-product-info { | |
3779 | + position: absolute; | |
3780 | + top: 0; | |
3781 | + z-index: 9999; | |
3782 | + height: 125px; | |
3783 | + overflow: hidden; | |
3784 | + font-size: 11px; | |
3785 | + background-color: #fff; | |
3786 | + opacity: 0.7; | |
3787 | + border: 1px solid #333; | |
3788 | + padding: 5px; | |
3789 | + text-align: left; | |
3790 | +} | |
3791 | + | |
3792 | +.box-2 .featured-product-info, | |
3793 | +.box-3 .featured-product-info { | |
3794 | + width: 110px; | |
3795 | + margin-left: 50%; | |
3796 | + left: -60px; | |
3797 | +} | |
3798 | + | |
3799 | +#content .featured-product-info h3 { | |
3800 | + font-size: 11px; | |
3801 | +} | ... | ... |
test/functional/environment_design_controller_test.rb
... | ... | @@ -6,7 +6,7 @@ class EnvironmentDesignController; def rescue_action(e) raise e end; end |
6 | 6 | |
7 | 7 | class EnvironmentDesignControllerTest < Test::Unit::TestCase |
8 | 8 | |
9 | - ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock ] | |
9 | + ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock ] | |
10 | 10 | |
11 | 11 | def setup |
12 | 12 | @controller = EnvironmentDesignController.new | ... | ... |
test/functional/profile_design_controller_test.rb
... | ... | @@ -10,7 +10,7 @@ class ProfileDesignControllerTest < Test::Unit::TestCase |
10 | 10 | PERSON_BLOCKS_WITH_MEMBERS = PERSON_BLOCKS + [MembersBlock] |
11 | 11 | PERSON_BLOCKS_WITH_BLOG = PERSON_BLOCKS + [BlogArchivesBlock] |
12 | 12 | |
13 | - ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, HighlightsBlock] | |
13 | + ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, HighlightsBlock, FeaturedProductsBlock] | |
14 | 14 | ENTERPRISE_BLOCKS_WITH_PRODUCTS_ENABLE = ENTERPRISE_BLOCKS + [ProductsBlock] |
15 | 15 | |
16 | 16 | attr_reader :holder | ... | ... |
test/unit/application_helper_test.rb
... | ... | @@ -579,6 +579,11 @@ class ApplicationHelperTest < Test::Unit::TestCase |
579 | 579 | assert_equal 'filename.mp3', short_filename('filename.mp3') |
580 | 580 | end |
581 | 581 | |
582 | + include ActionView::Helpers::NumberHelper | |
583 | + should 'format float to money as Brazillian currency' do | |
584 | + assert_equal 'R$10,00', float_to_currency(10.0) | |
585 | + end | |
586 | + | |
582 | 587 | protected |
583 | 588 | |
584 | 589 | def url_for(args = {}) | ... | ... |
test/unit/enterprise_test.rb
... | ... | @@ -377,4 +377,22 @@ class EnterpriseTest < Test::Unit::TestCase |
377 | 377 | ent = Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent') |
378 | 378 | assert_equal 3, ent.boxes.size |
379 | 379 | end |
380 | + | |
381 | + should 'collect the highlighted products with image' do | |
382 | + env = Environment.default | |
383 | + e1 = fast_create(Enterprise) | |
384 | + p1 = e1.products.create!(:name => 'test_prod1') | |
385 | + products = [] | |
386 | + 3.times {|n| | |
387 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { | |
388 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
389 | + })) | |
390 | + } | |
391 | + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) | |
392 | + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { | |
393 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
394 | + }) | |
395 | + assert_equal products, e1.highlighted_products_with_image | |
396 | + end | |
397 | + | |
380 | 398 | end | ... | ... |
test/unit/environment_test.rb
... | ... | @@ -374,6 +374,23 @@ class EnvironmentTest < Test::Unit::TestCase |
374 | 374 | assert_includes env.products, p1 |
375 | 375 | end |
376 | 376 | |
377 | + should 'collect the highlighted products with image through enterprises' do | |
378 | + env = Environment.default | |
379 | + e1 = fast_create(Enterprise) | |
380 | + p1 = e1.products.create!(:name => 'test_prod1') | |
381 | + products = [] | |
382 | + 3.times {|n| | |
383 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { | |
384 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
385 | + })) | |
386 | + } | |
387 | + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) | |
388 | + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { | |
389 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
390 | + }) | |
391 | + assert_equal products, env.highlighted_products_with_image | |
392 | + end | |
393 | + | |
377 | 394 | should 'not have person through communities' do |
378 | 395 | env = Environment.default |
379 | 396 | com = fast_create(Community) | ... | ... |
... | ... | @@ -0,0 +1,127 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class FeaturedProductsBlockTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @profile = fast_create(Profile) | |
7 | + @environment = Environment.default | |
8 | + @environment.boxes << Box.new | |
9 | + end | |
10 | + attr_reader :profile | |
11 | + | |
12 | + should 'refer to products' do | |
13 | + products = [] | |
14 | + 3.times {|n| products.push(Product.create!(:name => "product #{n}", :enterprise_id => profile.id)) } | |
15 | + featured_products_block = FeaturedProductsBlock.create!(:product_ids => products.map(&:id)) | |
16 | + assert_equal products, featured_products_block.products | |
17 | + end | |
18 | + | |
19 | + should "have method products_for_selection" do | |
20 | + block = FeaturedProductsBlock.new | |
21 | + assert_respond_to block, 'products_for_selection' | |
22 | + end | |
23 | + | |
24 | + should " the defaul product_ids be an empty array" do | |
25 | + block = FeaturedProductsBlock.new | |
26 | + assert_equal [], block.product_ids | |
27 | + end | |
28 | + | |
29 | + should " the defaul groups_of be 3" do | |
30 | + block = FeaturedProductsBlock.new | |
31 | + assert_equal 3, block.groups_of | |
32 | + end | |
33 | + | |
34 | + should 'default interval between transitions is 1000 miliseconds' do | |
35 | + block = FeaturedProductsBlock.new | |
36 | + assert_equal 1000, block.speed | |
37 | + end | |
38 | + | |
39 | + should "reflect by default" do | |
40 | + block = FeaturedProductsBlock.new | |
41 | + assert_equal true, block.reflect | |
42 | + end | |
43 | + | |
44 | + should 'describe itself' do | |
45 | + assert_not_equal Block.description, FeaturedProductsBlock.description | |
46 | + end | |
47 | + | |
48 | + should "the groups_of variabe be a integer" do | |
49 | + block = FeaturedProductsBlock.new | |
50 | + assert_kind_of Integer, block.groups_of | |
51 | + block.groups_of = 2 | |
52 | + block.save | |
53 | + block.reload | |
54 | + assert_kind_of Integer, block.groups_of | |
55 | + block.groups_of = '2' | |
56 | + block.save | |
57 | + block.reload | |
58 | + assert_kind_of Integer, block.groups_of | |
59 | + end | |
60 | + | |
61 | + should "an environment block collect product automatically" do | |
62 | + block = FeaturedProductsBlock.new() | |
63 | + block.product_ids = [] | |
64 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | |
65 | + 3.times {|n| | |
66 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { | |
67 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
68 | + }) | |
69 | + } | |
70 | + @environment.boxes.first.blocks<< block | |
71 | + | |
72 | + assert_not_equal [], block.product_ids | |
73 | + end | |
74 | + | |
75 | + should "an environment block collect just product with image automatically" do | |
76 | + block = FeaturedProductsBlock.new() | |
77 | + block.product_ids = [] | |
78 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | |
79 | + 3.times {|n| | |
80 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true) | |
81 | + } | |
82 | + @environment.boxes.first.blocks<< block | |
83 | + | |
84 | + assert_equal [], block.product_ids | |
85 | + end | |
86 | + | |
87 | + should "an environment block collect just highlighted product automatically" do | |
88 | + block = FeaturedProductsBlock.new() | |
89 | + block.product_ids = [] | |
90 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | |
91 | + 3.times {|n| | |
92 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :image_builder => { | |
93 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
94 | + }) | |
95 | + } | |
96 | + @environment.boxes.first.blocks<< block | |
97 | + | |
98 | + assert_equal [], block.product_ids | |
99 | + end | |
100 | + | |
101 | + should 'display feature products block' do | |
102 | + block = FeaturedProductsBlock.new | |
103 | + | |
104 | + self.expects(:render).with(:file => 'blocks/featured_products', :locals => { :block => block}) | |
105 | + instance_eval(& block.content) | |
106 | + end | |
107 | + | |
108 | + should "return just highlighted products with image for selection" do | |
109 | + block = FeaturedProductsBlock.new() | |
110 | + block.product_ids = [] | |
111 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | |
112 | + products = [] | |
113 | + 3.times {|n| | |
114 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { | |
115 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
116 | + })) | |
117 | + } | |
118 | + Product.create!(:name => "product 4", :enterprise_id => enterprise.id, :highlighted => true) | |
119 | + Product.create!(:name => "product 5", :enterprise_id => enterprise.id, :image_builder => { | |
120 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | |
121 | + }) | |
122 | + @environment.boxes.first.blocks<< block | |
123 | + | |
124 | + assert_equal products, block.products_for_selection | |
125 | + end | |
126 | + | |
127 | +end | ... | ... |
test/unit/highlights_block_test.rb
... | ... | @@ -119,12 +119,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase |
119 | 119 | i1 = {:image_id => 1, :address => '/address', :position => 3, :title => 'address'} |
120 | 120 | i2 = {:image_id => 2, :address => '/address', :position => 1, :title => 'address'} |
121 | 121 | i3 = {:image_id => 3, :address => '/address', :position => 2, :title => 'address'} |
122 | - block.images = [i1,i2,i3] | |
122 | + i4 = {:image_id => 4, :address => '/address', :position => 5, :title => 'address'} | |
123 | + i5 = {:image_id => 5, :address => '/address', :position => 4, :title => 'address'} | |
124 | + block.images = [i1,i2,i3,i4,i5] | |
123 | 125 | block.shuffle = true |
124 | 126 | block.save! |
125 | 127 | block.reload |
126 | - assert_equal [i1,i2,i3], block.images | |
127 | - assert_not_equal [i2,i3,i1], block.featured_images | |
128 | + assert_equal [i1,i2,i3,i4,i5], block.images | |
129 | + assert_not_equal [i2,i3,i1,i4,i5], block.featured_images | |
128 | 130 | end |
129 | 131 | |
130 | 132 | end | ... | ... |