Commit d9eb363116e58df526147cfdc1d529caa203484f
1 parent
6602995b
Exists in
master
and in
29 other branches
Adding new features to SlideshowBlock, and blocks in general
* added option to shuffle images * added navigation buttons * other changes: * Removed "toggle visibility" button and action in BoxOrganizer Controller * Bock#visible? now receives an optional context so that blocks can decide where they must be shown or not * BoxesHelper now passes the context into the Block#visible? method * Added title to Uploaded files and displaying it instead of the description when viewing files (ActionItem1358)
Showing
24 changed files
with
323 additions
and
95 deletions
Show diff stats
app/controllers/box_organizer_controller.rb
... | ... | @@ -100,13 +100,6 @@ class BoxOrganizerController < ApplicationController |
100 | 100 | end |
101 | 101 | end |
102 | 102 | |
103 | - def toggle_visibility | |
104 | - @block = boxes_holder.blocks.find(params[:id]) | |
105 | - @block.visible = !@block.visible? | |
106 | - @block.save | |
107 | - redirect_to :action => 'index' | |
108 | - end | |
109 | - | |
110 | 103 | protected :boxes_editor? |
111 | 104 | |
112 | 105 | end | ... | ... |
app/helpers/boxes_helper.rb
... | ... | @@ -59,10 +59,11 @@ module BoxesHelper |
59 | 59 | end |
60 | 60 | |
61 | 61 | def display_box_content(box, main_content) |
62 | - box_decorator.select_blocks(box.blocks).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) | |
62 | + context = { :article => @page } | |
63 | + box_decorator.select_blocks(box.blocks, context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) | |
63 | 64 | end |
64 | 65 | |
65 | - def select_blocks(arr) | |
66 | + def select_blocks(arr, context) | |
66 | 67 | arr |
67 | 68 | end |
68 | 69 | |
... | ... | @@ -83,7 +84,7 @@ module BoxesHelper |
83 | 84 | end |
84 | 85 | |
85 | 86 | options = { |
86 | - :class => classes = ['block', block.css_classes ].uniq.join(' '), | |
87 | + :class => classes = ['block', block_css_classes(block) ].uniq.join(' '), | |
87 | 88 | :id => "block-#{block.id}" |
88 | 89 | } |
89 | 90 | if ( block.respond_to? 'help' ) |
... | ... | @@ -134,8 +135,8 @@ module BoxesHelper |
134 | 135 | def self.block_edit_buttons(block) |
135 | 136 | '' |
136 | 137 | end |
137 | - def self.select_blocks(arr) | |
138 | - arr.select(&:visible?) | |
138 | + def self.select_blocks(arr, context) | |
139 | + arr.select { |block| block.visible?(context) } | |
139 | 140 | end |
140 | 141 | end |
141 | 142 | |
... | ... | @@ -201,7 +202,6 @@ module BoxesHelper |
201 | 202 | end |
202 | 203 | |
203 | 204 | if !block.main? |
204 | - buttons << icon_button(:eyes, _('Toggle block visibility'), {:action => 'toggle_visibility', :id => block.id}) | |
205 | 205 | buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) |
206 | 206 | end |
207 | 207 | |
... | ... | @@ -217,8 +217,18 @@ module BoxesHelper |
217 | 217 | end |
218 | 218 | |
219 | 219 | def import_blocks_stylesheets(options = {}) |
220 | - @blocks_css_files ||= current_blocks.map{|b|'blocks/' + b.css_class_name}.uniq | |
220 | + @blocks_css_files ||= current_blocks.map{|b|'blocks/' + block_css_class_name(b)}.uniq | |
221 | 221 | stylesheet_import(@blocks_css_files, options) |
222 | 222 | end |
223 | 223 | |
224 | + def block_css_class_name(block) | |
225 | + block.class.name.underscore.gsub('_', '-') | |
226 | + end | |
227 | + def block_css_classes(block) | |
228 | + classes = block_css_class_name(block) | |
229 | + classes += ' invisible-block' if block.display == 'never' | |
230 | + classes | |
231 | + end | |
232 | + | |
233 | + | |
224 | 234 | end | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -13,7 +13,7 @@ module ContentViewerHelper |
13 | 13 | end |
14 | 14 | |
15 | 15 | def article_title(article, args = {}) |
16 | - title = article.abstract if article.kind_of?(UploadedFile) && article.image? | |
16 | + title = article.display_title if article.kind_of?(UploadedFile) && article.image? | |
17 | 17 | title = article.title if title.blank? |
18 | 18 | title = content_tag('h1', title, :class => 'title') |
19 | 19 | if article.belongs_to_blog? |
... | ... | @@ -35,4 +35,9 @@ module ContentViewerHelper |
35 | 35 | link_to( number_of_comments(article), article.url.merge(:anchor => 'comments_list') ) |
36 | 36 | end |
37 | 37 | |
38 | + def image_label(image) | |
39 | + text = image.title || image.abstract | |
40 | + text && (text.first(40) + (text.size > 40 ? '…' : '')) | |
41 | + end | |
42 | + | |
38 | 43 | end | ... | ... |
app/models/block.rb
... | ... | @@ -11,14 +11,46 @@ class Block < ActiveRecord::Base |
11 | 11 | belongs_to :box |
12 | 12 | |
13 | 13 | acts_as_having_settings |
14 | - settings_items :visible, :type => :boolean, :default => true | |
15 | 14 | |
16 | 15 | named_scope :enabled, :conditions => { :enabled => true } |
17 | 16 | |
18 | - def visible? | |
19 | - visible | |
17 | + # Determines whether a given block must be visible. Optionally a | |
18 | + # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and | |
19 | + # may contain the following keys: | |
20 | + # | |
21 | + # * <tt>:article</tt>: the article being viewed currently | |
22 | + def visible?(context = nil) | |
23 | + if settings[:visible] == false || display == 'never' | |
24 | + return false | |
25 | + end | |
26 | + if context && context[:article] && display == 'home_page_only' | |
27 | + return context[:article] == owner.home_page | |
28 | + end | |
29 | + true | |
30 | + end | |
31 | + | |
32 | + # The condition for displaying a block. It can assume the following values: | |
33 | + # | |
34 | + # * <tt>'always'</tt>: the block is always displayed | |
35 | + # * <tt>'never'</tt>: the block is hidden (it does not appear for visitors) | |
36 | + # * <tt>'home_page_only'</tt> the block is displayed only when viewing the | |
37 | + # homepage of its owner. | |
38 | + def display | |
39 | + if settings[:visible] == false | |
40 | + 'never' | |
41 | + else | |
42 | + settings[:display] || 'always' | |
43 | + end | |
44 | + end | |
45 | + | |
46 | + # Sets the <tt>value</tt> attribute. | |
47 | + def display=(value) | |
48 | + settings[:display] = value | |
49 | + # clear the old setting | |
50 | + settings[:visible] = nil | |
20 | 51 | end |
21 | 52 | |
53 | + | |
22 | 54 | # returns the description of the block, used when the user sees a list of |
23 | 55 | # blocks to choose one to include in the design. |
24 | 56 | # |
... | ... | @@ -66,16 +98,6 @@ class Block < ActiveRecord::Base |
66 | 98 | box ? box.owner : nil |
67 | 99 | end |
68 | 100 | |
69 | - def css_class_name | |
70 | - self.class.name.underscore.gsub('_', '-') | |
71 | - end | |
72 | - | |
73 | - def css_classes | |
74 | - classes = css_class_name | |
75 | - classes += ' invisible-block' unless visible? | |
76 | - classes | |
77 | - end | |
78 | - | |
79 | 101 | def default_title |
80 | 102 | '' |
81 | 103 | end | ... | ... |
app/models/slideshow_block.rb
... | ... | @@ -2,9 +2,11 @@ class SlideshowBlock < Block |
2 | 2 | |
3 | 3 | settings_items :gallery_id, :type => 'integer' |
4 | 4 | settings_items :interval, :type => 'integer', :default => 4 |
5 | + settings_items :shuffle, :type => 'boolean', :default => false | |
6 | + settings_items :navigation, :type => 'boolean', :default => false | |
5 | 7 | |
6 | 8 | def self.description |
7 | - _('Display images from gallery as slideshow') | |
9 | + _('Slideshow block') | |
8 | 10 | end |
9 | 11 | |
10 | 12 | def gallery |
... | ... | @@ -12,35 +14,18 @@ class SlideshowBlock < Block |
12 | 14 | end |
13 | 15 | |
14 | 16 | def content |
17 | + block = self | |
15 | 18 | if gallery |
16 | 19 | images = gallery.images |
17 | - block_id = id | |
18 | - block_title = title | |
19 | - lambda do | |
20 | - block_title(block_title) + | |
21 | - content_tag('div', | |
22 | - images.map do |i| | |
23 | - link_to( | |
24 | - content_tag('div', '', :style => "background-image: url(#{i.public_filename(:thumb)})"), | |
25 | - (i.external_link || i.view_url), :target => '_blank' | |
26 | - ) | |
27 | - end.join("\n"), | |
28 | - :class => 'slideshow-container' | |
29 | - ) | |
20 | + if shuffle | |
21 | + images = images.shuffle | |
30 | 22 | end |
31 | - else | |
32 | 23 | lambda do |
33 | - content_tag('em', _('Please select a gallery to display its images.')) | |
24 | + render :file => 'blocks/slideshow', :locals => { :block => block, :images => images } | |
34 | 25 | end |
35 | - end | |
36 | - end | |
37 | - | |
38 | - def footer | |
39 | - if gallery | |
40 | - block_id = id | |
41 | - interval_sec = interval * 1000 | |
26 | + else | |
42 | 27 | lambda do |
43 | - javascript_tag("jQuery('#block-#{block_id} .slideshow-container').cycle({fx: 'fade', timeout: #{interval_sec}})") | |
28 | + render :file => 'blocks/slideshow', :locals => { :block => block, :images => nil } | |
44 | 29 | end |
45 | 30 | end |
46 | 31 | end | ... | ... |
app/models/uploaded_file.rb
... | ... | @@ -4,6 +4,13 @@ |
4 | 4 | # of the file itself is kept. (FIXME?) |
5 | 5 | class UploadedFile < Article |
6 | 6 | |
7 | + settings_items :title, :type => 'string' | |
8 | + validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) | |
9 | + | |
10 | + def display_title | |
11 | + title.blank? ? name : title | |
12 | + end | |
13 | + | |
7 | 14 | def self.max_size |
8 | 15 | UploadedFile.attachment_options[:max_size] |
9 | 16 | end |
... | ... | @@ -74,11 +81,14 @@ class UploadedFile < Article |
74 | 81 | :class => 'gallery-navigation' |
75 | 82 | ) |
76 | 83 | end.to_s + |
77 | - tag('img', :src => article.public_filename(:display), :class => article.css_class_name, :style => 'max-width: 100%') | |
84 | + tag('img', :src => article.public_filename(:display), :class => article.css_class_name, :style => 'max-width: 100%') + | |
85 | + content_tag('p', article.abstract, :class => 'uploaded-file-description') | |
86 | + | |
78 | 87 | end |
79 | 88 | else |
80 | 89 | lambda do |
81 | - content_tag('ul', content_tag('li', link_to(article.name, article.url, :class => article.css_class_name))) | |
90 | + content_tag('ul', content_tag('li', link_to(article.name, article.url, :class => article.css_class_name))) + | |
91 | + content_tag('p', article.abstract, :class => 'uploaded-file-description') | |
82 | 92 | end |
83 | 93 | end |
84 | 94 | end | ... | ... |
... | ... | @@ -0,0 +1,49 @@ |
1 | +<%= block_title(block.title) %> | |
2 | +<% if images %> | |
3 | + <% description = images.any? { |img| !img.abstract.blank? } %> | |
4 | + <div class='slideshow-border<%= (description ? ' with-descriptions' : '')%>'> | |
5 | + <div class='slideshow-container'> | |
6 | + <% images.each do |img| %> | |
7 | + <a href="<%= url_for(img.external_link.blank? ? img.view_url: img.external_link) %>"> | |
8 | + <%= content_tag('div', '', :style => "background-image: url(#{img.public_filename(:thumb)})", :title => (img.abstract.blank? ? '' : img.abstract)) %> | |
9 | + <% if !img.abstract.blank? %> | |
10 | + <span class='image-description'><%= img.abstract %></span> | |
11 | + <% end %> | |
12 | + </a> | |
13 | + <% end %> | |
14 | + </div> | |
15 | + <% if block.navigation %> | |
16 | + <div class='slideshow-block-navigation'> | |
17 | + <%= link_to _('Previous'), '#', :class => 'icon-media-prev' %> | |
18 | + <% if block.interval > 0 %> | |
19 | + <%= link_to ' ', '#', :class => 'icon-media-pause', :onclick => "togglePlayback('#block-#{block.id} .slideshow-container', this); return false;" %> | |
20 | + <% end %> | |
21 | + <%= link_to _('Next'), '#', :class => 'icon-media-next' %> | |
22 | + </div> | |
23 | + <% end %> | |
24 | + </div> | |
25 | + <script type="text/javascript"> | |
26 | + (function($) { | |
27 | + var options = {fx: 'fade', pause: 1, fastOnEvent: 1, timeout: <%= block.interval * 1000 %>}; | |
28 | + <% if block.navigation %> | |
29 | + options.prev = '#block-<%= block.id %> .icon-media-prev'; | |
30 | + options.next = '#block-<%= block.id %> .icon-media-next'; | |
31 | + <% end %> | |
32 | + $('#block-<%= block.id %> .slideshow-container').cycle(options); | |
33 | + })(jQuery); | |
34 | + | |
35 | + function togglePlayback(slideshow, button) { | |
36 | + var $ = jQuery; | |
37 | + if (button.className == 'icon-media-pause') { | |
38 | + button.className = 'icon-media-play'; | |
39 | + $(slideshow).cycle('pause'); | |
40 | + } else { | |
41 | + button.className = 'icon-media-pause'; | |
42 | + $(slideshow).cycle('resume'); | |
43 | + } | |
44 | + } | |
45 | + </script> | |
46 | +<% else %> | |
47 | + <em><%= _('Please, edit this block and select an image gallery.') %></em> | |
48 | +<% end %> | |
49 | + | ... | ... |
app/views/box_organizer/_slideshow_block.rhtml
... | ... | @@ -3,4 +3,8 @@ |
3 | 3 | [ _('%{gallery} (%{count} images)') % {:gallery => item.path, :count => item.images.count}, item.id ] |
4 | 4 | }) %> |
5 | 5 | |
6 | -<%= labelled_form_field _('Seconds between image transitions'), select('block', 'interval', [1, 2, 3, 4, 5, 10, 20, 30, 60] ) %> | |
6 | +<%= labelled_form_field _('Image transition:'), select('block', 'interval', [[_('No automatic transition'), 0]] + [1, 2, 3, 4, 5, 10, 20, 30, 60].map {|item| [n_('Every 1 second', 'Every %d seconds', item) % item, item]}) %> | |
7 | + | |
8 | +<%= labelled_form_field check_box(:block, :shuffle) + _('Show images in random order'), '' %> | |
9 | + | |
10 | +<%= labelled_form_field check_box(:block, :navigation) + _('Display navigation buttons'), '' %> | ... | ... |
app/views/box_organizer/edit.rhtml
... | ... | @@ -6,6 +6,18 @@ |
6 | 6 | |
7 | 7 | <%= render :partial => partial_for_class(@block.class) %> |
8 | 8 | |
9 | + <%= labelled_form_field _('Display this block:'), '' %> | |
10 | + <div style='margin-left: 10px'> | |
11 | + <%= radio_button(:block, :display, 'always') %> | |
12 | + <%= label_tag('block_display_always', _('In all pages')) %> | |
13 | + <br/> | |
14 | + <%= radio_button(:block, :display, 'home_page_only') %> | |
15 | + <%= label_tag('block_display_home_page_only', _('Only in the homepage')) %> | |
16 | + <br/> | |
17 | + <%= radio_button(:block, :display, 'never') %> | |
18 | + <%= label_tag('block_display_never', _("Don't display")) %> | |
19 | + </div> | |
20 | + | |
9 | 21 | <% button_bar do %> |
10 | 22 | <%= submit_button(:save, _('Save')) %> |
11 | 23 | <%= lightbox_close_button(_('Cancel')) %> | ... | ... |
app/views/cms/_uploaded_file.rhtml
1 | -<%= labelled_form_field(_('Describe this file:'), text_area(:article, :abstract, :rows => 3, :cols => 64)) %> | |
1 | +<%= labelled_form_field(_('Title'), text_field(:article, :title, :maxlength => 60)) %> | |
2 | +<%= labelled_form_field(_('Description'), text_area(:article, :abstract, :rows => 3, :cols => 64)) %> | |
2 | 3 | <% if @article.image? %> |
3 | 4 | <%= f.text_field(:external_link, :size => 64) %> |
4 | 5 | <% end %> | ... | ... |
app/views/content_viewer/_uploaded_file.rhtml
1 | 1 | <% if uploaded_file.image? %> |
2 | - <div> <%= link_to image_tag(uploaded_file.public_filename(:thumb), :alt => uploaded_file.abstract), uploaded_file.view_url %> </div> | |
2 | + <div> <%= link_to image_tag(uploaded_file.public_filename(:thumb), :alt => uploaded_file.display_title), uploaded_file.view_url %> </div> | |
3 | + <span><%= image_label(uploaded_file) %></span> | |
3 | 4 | <% else %> |
4 | 5 | <%= render :partial => 'article', :object => uploaded_file %> |
5 | 6 | <% end %> |
6 | - | ... | ... |
app/views/content_viewer/image_gallery.rhtml
... | ... | @@ -8,7 +8,6 @@ |
8 | 8 | <% @images.each do |a| %> |
9 | 9 | <% content_tag('li', :title => a.abstract, :class => 'image-gallery-item' ) do %> |
10 | 10 | <%= render :partial => partial_for_class(a.class), :object => a %> |
11 | - <span><%= a.abstract && (a.abstract.first(40) + (a.abstract.size > 40 ? '…' : ''))%></span> | |
12 | 11 | <% end %> |
13 | 12 | <% end %> |
14 | 13 | </ul> | ... | ... |
app/views/content_viewer/view_page.rhtml
lib/tasks/release.rake
... | ... | @@ -10,7 +10,7 @@ namespace :noosfero do |
10 | 10 | end |
11 | 11 | |
12 | 12 | version = Noosfero::VERSION |
13 | - desc 'checks if there is already a tag for the curren version' | |
13 | + desc 'checks if there is already a tag for the current version' | |
14 | 14 | task :check_tag do |
15 | 15 | sh "git tag | grep '^#{version}$' >/dev/null" do |ok, res| |
16 | 16 | if ok | ... | ... |
public/designs/icons/tango/style.css
... | ... | @@ -64,3 +64,8 @@ |
64 | 64 | .icon-slideshow { background-image: url(Tango/16x16/mimetypes/x-office-presentation.png) } |
65 | 65 | .icon-photos { background-image: url(Tango/16x16/devices/camera-photo.png) } |
66 | 66 | |
67 | +.icon-media-pause { background-image: url(Tango/16x16/actions/media-playback-pause.png) } | |
68 | +.icon-media-play { background-image: url(Tango/16x16/actions/media-playback-start.png) } | |
69 | +.icon-media-prev { background-image: url(Tango/16x16/actions/media-skip-backward.png) } | |
70 | +.icon-media-next { background-image: url(Tango/16x16/actions/media-skip-forward.png) } | |
71 | + | ... | ... |
public/designs/themes/base/article.css
public/stylesheets/blocks/slideshow-block.css
1 | 1 | .slideshow-block .slideshow-container { |
2 | - margin: auto; | |
2 | + margin-bottom: 10px; | |
3 | +} | |
4 | + | |
5 | +.slideshow-block .slideshow-container a { | |
6 | + width: 100%; | |
7 | + display: block; | |
8 | + text-decoration: none; | |
9 | +} | |
10 | +.slideshow-block .slideshow-container a:hover { | |
11 | + text-decoration: none; | |
3 | 12 | } |
4 | 13 | |
5 | 14 | .slideshow-block .slideshow-container div { |
6 | - width: 130px; | |
7 | 15 | height: 130px; |
8 | 16 | background-position: 50% 50%; |
9 | 17 | background-repeat: no-repeat; |
10 | - margin: auto; | |
18 | +} | |
19 | + | |
20 | +.slideshow-block .with-descriptions { | |
21 | + border: 1px solid #ddd; | |
22 | +} | |
23 | + | |
24 | +.slideshow-block .image-description { | |
25 | + display: block; | |
26 | + padding: 10px; | |
27 | + height: 34px; | |
28 | + overflow: hidden; | |
29 | + border-top: 1px solid #ddd; | |
30 | + background-color: white; | |
31 | + color: black; | |
11 | 32 | } |
12 | 33 | |
13 | 34 | .msie .slideshow-block .slideshow-container div { |
14 | 35 | cursor: pointer; |
15 | 36 | } |
37 | + | |
38 | +.slideshow-block { | |
39 | + text-align: center; | |
40 | +} | |
41 | + | |
42 | +.slideshow-block .slideshow-block-navigation { | |
43 | + margin: 8px 0px; | |
44 | +} | |
45 | +.slideshow-block .slideshow-block-navigation a { | |
46 | + background-color: white; | |
47 | + background-repeat: no-repeat; | |
48 | + border: 1px solid #ddd; | |
49 | + padding: 2px; | |
50 | + text-decoration: none; | |
51 | + font-variant: small-caps; | |
52 | + font-size: 10px; | |
53 | +} | |
54 | +.slideshow-block .slideshow-block-navigation a:hover { | |
55 | + text-decoration: none; | |
56 | + border-color: #999; | |
57 | +} | |
58 | + | |
59 | +.slideshow-block .slideshow-block-navigation .icon-media-prev { | |
60 | + padding-left: 18px; | |
61 | + background-position: left; | |
62 | +} | |
63 | +.slideshow-block .slideshow-block-navigation .icon-media-next { | |
64 | + padding-right: 18px; | |
65 | + background-position: right; | |
66 | + | |
67 | +} | |
68 | +.slideshow-block .slideshow-block-navigation .icon-media-pause, | |
69 | +.slideshow-block .slideshow-block-navigation .icon-media-play { | |
70 | + background-position: 50% 50%; | |
71 | + display: inline-block; | |
72 | + width: 16px; | |
73 | +} | ... | ... |
public/stylesheets/controller_content_viewer.css
... | ... | @@ -65,3 +65,10 @@ div#article-parent { |
65 | 65 | #article .gallery-navigation .total-of-images { |
66 | 66 | font-weight: bold; |
67 | 67 | } |
68 | + | |
69 | +#article .uploaded-file-description { | |
70 | + background: #f6f6f6; | |
71 | + border-top: 1px solid #ccc; | |
72 | + border-bottom: 1px solid #ccc; | |
73 | + padding: 1em; | |
74 | +} | ... | ... |
test/functional/application_controller_test.rb
... | ... | @@ -406,7 +406,7 @@ class ApplicationControllerTest < Test::Unit::TestCase |
406 | 406 | p = create_user_full('test_user').person |
407 | 407 | @controller.expects(:profile).at_least_once.returns(p) |
408 | 408 | b = p.blocks[1] |
409 | - b.expects(:visible).returns(false) | |
409 | + b.expects(:visible?).returns(false) | |
410 | 410 | b.save! |
411 | 411 | |
412 | 412 | get :index, :profile => p.identifier | ... | ... |
test/functional/profile_design_controller_test.rb
... | ... | @@ -285,15 +285,6 @@ class ProfileDesignControllerTest < Test::Unit::TestCase |
285 | 285 | assert_no_tag :tag => 'input', :attributes => { :id => 'type_blogarchivesblock', :value => 'BlogArchivesBlock' } |
286 | 286 | end |
287 | 287 | |
288 | - should 'toggle block visibility' do | |
289 | - state = @b1.visible? | |
290 | - get :toggle_visibility, :id => @b1.id, :profile => holder.identifier | |
291 | - block = Block.find(@b1.id) | |
292 | - | |
293 | - assert_equal block, assigns(:block) | |
294 | - assert_equal !state, block.visible? | |
295 | - end | |
296 | - | |
297 | 288 | should 'offer to create feed reader block' do |
298 | 289 | get :add_block, :profile => 'designtestuser' |
299 | 290 | assert_tag :tag => 'input', :attributes => { :id => 'type_feedreaderblock', :value => 'FeedReaderBlock' } | ... | ... |
test/unit/block_test.rb
... | ... | @@ -22,12 +22,6 @@ class BlockTest < Test::Unit::TestCase |
22 | 22 | assert_nil Block.new.owner |
23 | 23 | end |
24 | 24 | |
25 | - should 'generate CSS class name' do | |
26 | - block = Block.new | |
27 | - block.class.expects(:name).returns('SomethingBlock') | |
28 | - assert_equal 'something-block', block.css_class_name | |
29 | - end | |
30 | - | |
31 | 25 | should 'provide no footer by default' do |
32 | 26 | assert_nil Block.new.footer |
33 | 27 | end |
... | ... | @@ -52,12 +46,18 @@ class BlockTest < Test::Unit::TestCase |
52 | 46 | assert_equal 'my title', b.view_title |
53 | 47 | end |
54 | 48 | |
55 | - should 'have a visible setting' do | |
49 | + should 'be backwards compatible with old "visible" setting' do | |
56 | 50 | b = Block.new |
57 | - assert b.visible? | |
58 | - b.visible = false | |
59 | - b.save | |
51 | + b.settings[:visible] = false | |
60 | 52 | assert !b.visible? |
53 | + assert_equal 'never', b.display | |
54 | + end | |
55 | + | |
56 | + should 'clean old "visible setting" when display is set' do | |
57 | + b = Block.new | |
58 | + b.settings[:visible] = false | |
59 | + b.display = 'never' | |
60 | + assert_nil b.settings[:visible] | |
61 | 61 | end |
62 | 62 | |
63 | 63 | should 'be cacheable' do |
... | ... | @@ -80,4 +80,24 @@ class BlockTest < Test::Unit::TestCase |
80 | 80 | assert_not_includes Block.enabled, block2 |
81 | 81 | end |
82 | 82 | |
83 | + should 'be displayed everywhere by default' do | |
84 | + assert_equal true, Block.new.visible? | |
85 | + end | |
86 | + | |
87 | + should 'not display when set to hidden' do | |
88 | + assert_equal false, Block.new(:display => 'never').visible? | |
89 | + assert_equal false, Block.new(:display => 'never').visible?(:article => Article.new) | |
90 | + end | |
91 | + | |
92 | + should 'be able to be displayed only in the homepage' do | |
93 | + profile = Profile.new | |
94 | + home_page = Article.new | |
95 | + profile.home_page = home_page | |
96 | + block = Block.new(:display => 'home_page_only') | |
97 | + block.stubs(:owner).returns(profile) | |
98 | + | |
99 | + assert_equal true, block.visible?(:article => home_page) | |
100 | + assert_equal false, block.visible?(:article => Article.new) | |
101 | + end | |
102 | + | |
83 | 103 | end | ... | ... |
test/unit/boxes_helper_test.rb
... | ... | @@ -41,7 +41,7 @@ class BoxesHelperTest < Test::Unit::TestCase |
41 | 41 | p = create_user_with_blocks |
42 | 42 | |
43 | 43 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] |
44 | - b.visible = false; b.save! | |
44 | + b.display = 'never'; b.save! | |
45 | 45 | box = b.box |
46 | 46 | box.expects(:blocks).returns([b]) |
47 | 47 | expects(:display_block).with(b, '') |
... | ... | @@ -55,7 +55,7 @@ class BoxesHelperTest < Test::Unit::TestCase |
55 | 55 | p = create_user_with_blocks |
56 | 56 | |
57 | 57 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] |
58 | - b.visible = false; b.save! | |
58 | + b.display = 'never'; b.save! | |
59 | 59 | box = b.box |
60 | 60 | box.expects(:blocks).returns([b]) |
61 | 61 | expects(:display_block).with(b, '').never |
... | ... | @@ -85,4 +85,13 @@ class BoxesHelperTest < Test::Unit::TestCase |
85 | 85 | assert_tag_in_string insert_boxes('main content'), :tag => "div", :attributes => { :id => 'profile-footer' }, :content => 'my custom footer' |
86 | 86 | end |
87 | 87 | |
88 | + should 'calculate CSS class names correctly' do | |
89 | + assert_equal 'slideshow-block', block_css_class_name(SlideshowBlock.new) | |
90 | + assert_equal 'main-block', block_css_class_name(MainBlock.new) | |
91 | + end | |
92 | + | |
93 | + should 'add invisible CSS class name for invisible blocks' do | |
94 | + assert !block_css_classes(Block.new(:display => 'always')).split.any? { |item| item == 'invisible-block'} | |
95 | + assert block_css_classes(Block.new(:display => 'never')).split.any? { |item| item == 'invisible-block'} | |
96 | + end | |
88 | 97 | end | ... | ... |
test/unit/slideshow_block_test.rb
... | ... | @@ -20,15 +20,35 @@ class SlideshowBlockTest < ActiveSupport::TestCase |
20 | 20 | assert_equal 4, slideshow.interval |
21 | 21 | end |
22 | 22 | |
23 | - should 'not invoke javascript when has no gallery' do | |
24 | - slideshow_block = SlideshowBlock.new() | |
25 | - assert_nil slideshow_block.footer | |
23 | + should 'list in the same order' do | |
24 | + gallery = mock | |
25 | + images = [] | |
26 | + images.expects(:shuffle).never | |
27 | + gallery.stubs(:images).returns(images) | |
28 | + | |
29 | + block = SlideshowBlock.new | |
30 | + block.stubs(:gallery).returns(gallery) | |
31 | + block.content | |
26 | 32 | end |
27 | 33 | |
28 | - should 'invoke javascript when has gallery' do | |
29 | - gallery = fast_create(Folder, :profile_id => profile.id) | |
30 | - slideshow_block = SlideshowBlock.new(:gallery_id => gallery.id) | |
31 | - assert_not_nil slideshow_block.footer | |
34 | + should 'list in random order' do | |
35 | + gallery = mock | |
36 | + images = [] | |
37 | + shuffled = [] | |
38 | + gallery.stubs(:images).returns(images) | |
39 | + images.expects(:shuffle).once.returns(shuffled) | |
40 | + | |
41 | + block = SlideshowBlock.new(:shuffle => true) | |
42 | + block.stubs(:gallery).returns(gallery) | |
43 | + block.content | |
44 | + end | |
45 | + | |
46 | + should 'not shuffle by default' do | |
47 | + assert_equal false, SlideshowBlock.new.shuffle | |
48 | + end | |
49 | + | |
50 | + should 'not display navigation by default' do | |
51 | + assert_equal false, SlideshowBlock.new.navigation | |
32 | 52 | end |
33 | 53 | |
34 | 54 | end | ... | ... |
test/unit/uploaded_file_test.rb
... | ... | @@ -113,10 +113,34 @@ class UploadedFileTest < Test::Unit::TestCase |
113 | 113 | p = create_user('test_user').person |
114 | 114 | file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :profile => p) |
115 | 115 | |
116 | - stubs(:content_tag) | |
116 | + stubs(:content_tag).returns('link') | |
117 | 117 | expects(:link_to).with(file.name, file.url, :class => file.css_class_name) |
118 | 118 | |
119 | 119 | instance_eval(&file.to_html) |
120 | 120 | end |
121 | 121 | |
122 | + should 'have title' do | |
123 | + assert_equal 'my title', UploadedFile.new(:title => 'my title').title | |
124 | + end | |
125 | + | |
126 | + should 'limit title to 140 characters' do | |
127 | + upload = UploadedFile.new | |
128 | + | |
129 | + upload.title = '+' * 61; upload.valid? | |
130 | + assert upload.errors[:title] | |
131 | + | |
132 | + upload.title = '+' * 60; upload.valid? | |
133 | + assert !upload.errors[:title] | |
134 | + | |
135 | + end | |
136 | + | |
137 | + should 'always provide a display title' do | |
138 | + upload = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain')) | |
139 | + assert_equal 'test.txt', upload.display_title | |
140 | + upload.title = 'My text file' | |
141 | + assert_equal 'My text file', upload.display_title | |
142 | + upload.title = '' | |
143 | + assert_equal 'test.txt', upload.display_title | |
144 | + end | |
145 | + | |
122 | 146 | end | ... | ... |