Commit f2b0ed69f1ff0a7fadb525a62ba6f7a79f23d209
Committed by
Antonio Terceiro
1 parent
2edf8709
Exists in
master
and in
8 other branches
Forum content type and refactoring image gallery implementation
(ActionItem1769)
Showing
44 changed files
with
963 additions
and
148 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
| ... | ... | @@ -44,7 +44,7 @@ class CmsController < MyProfileController |
| 44 | 44 | Event |
| 45 | 45 | ] |
| 46 | 46 | parent_id = params ? params[:parent_id] : nil |
| 47 | - if !parent_id or !Article.find(parent_id).blog? | |
| 47 | + if !parent_id or !Article.find(parent_id).has_posts? | |
| 48 | 48 | articles += [ |
| 49 | 49 | RssFeed |
| 50 | 50 | ] |
| ... | ... | @@ -56,13 +56,13 @@ class CmsController < MyProfileController |
| 56 | 56 | end |
| 57 | 57 | |
| 58 | 58 | def special_article_types |
| 59 | - [Folder, Blog, UploadedFile] | |
| 59 | + [Folder, Blog, UploadedFile, Forum, Gallery] | |
| 60 | 60 | end |
| 61 | 61 | |
| 62 | 62 | def view |
| 63 | 63 | @article = profile.articles.find(params[:id]) |
| 64 | 64 | conditions = [] |
| 65 | - if @article.blog? | |
| 65 | + if @article.has_posts? | |
| 66 | 66 | conditions = ['type != ?', 'RssFeed'] |
| 67 | 67 | end |
| 68 | 68 | ... | ... |
app/controllers/public/content_viewer_controller.rb
| ... | ... | @@ -77,7 +77,7 @@ class ContentViewerController < ApplicationController |
| 77 | 77 | remove_comment |
| 78 | 78 | end |
| 79 | 79 | |
| 80 | - if @page.blog? | |
| 80 | + if @page.has_posts? | |
| 81 | 81 | posts = if params[:year] and params[:month] |
| 82 | 82 | filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01") |
| 83 | 83 | @page.posts.by_range(filter_date..filter_date.at_end_of_month) |
| ... | ... | @@ -88,7 +88,7 @@ class ContentViewerController < ApplicationController |
| 88 | 88 | @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))) |
| 89 | 89 | end |
| 90 | 90 | |
| 91 | - if @page.folder? && @page.view_as == 'image_gallery' | |
| 91 | + if @page.folder? && @page.gallery? | |
| 92 | 92 | @images = @page.images |
| 93 | 93 | @images = @images.paginate(:per_page => per_page, :page => params[:npage]) unless params[:slideshow] |
| 94 | 94 | end | ... | ... |
app/helpers/content_viewer_helper.rb
| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | +module ForumHelper | |
| 2 | + | |
| 3 | + def cms_label_for_new_children | |
| 4 | + _('New discussion topic') | |
| 5 | + end | |
| 6 | + | |
| 7 | + def cms_label_for_edit | |
| 8 | + _('Configure forum') | |
| 9 | + end | |
| 10 | + | |
| 11 | + def list_forum_posts(articles) | |
| 12 | + pagination = will_paginate(articles, { | |
| 13 | + :param_name => 'npage', | |
| 14 | + :prev_label => _('« Newer posts'), | |
| 15 | + :next_label => _('Older posts »') | |
| 16 | + }) | |
| 17 | + content = [content_tag('tr', | |
| 18 | + content_tag('th', _('Discussion topic')) + | |
| 19 | + content_tag('th', _('Posts')) + | |
| 20 | + content_tag('th', _('Last post')) | |
| 21 | + ) | |
| 22 | + ] | |
| 23 | + artic_len = articles.length | |
| 24 | + articles.each_with_index{ |art,i| | |
| 25 | + css_add = [ 'position-'+(i+1).to_s() ] | |
| 26 | + position = (i%2 == 0) ? 'odd-post' : 'even-post' | |
| 27 | + css_add << 'first' if i == 0 | |
| 28 | + css_add << 'last' if i == (artic_len-1) | |
| 29 | + css_add << 'not-published' if !art.published? | |
| 30 | + css_add << position | |
| 31 | + content << content_tag('tr', | |
| 32 | + content_tag('td', link_to(art.title, art.url)) + | |
| 33 | + content_tag('td', link_to(art.comments.count, art.url.merge(:anchor => 'comments_list'))) + | |
| 34 | + content_tag('td', last_topic_update(art)), | |
| 35 | + :class => 'forum-post ' + css_add.join(' '), | |
| 36 | + :id => "post-#{art.id}" | |
| 37 | + ) | |
| 38 | + } | |
| 39 | + content_tag('table', content) + (pagination or '') | |
| 40 | + end | |
| 41 | + | |
| 42 | + def last_topic_update(article) | |
| 43 | + last_update_at, last_update_by = (article.comments.count.zero? ? [article.updated_at, article.author] : [article.comments.last.created_at, article.comments.last.author]) | |
| 44 | + time_ago_as_sentence(last_update_at) + ' ' + _('ago') + ' ' + _('by') + ' ' + link_to(last_update_by.name, last_update_by.url) | |
| 45 | + end | |
| 46 | + | |
| 47 | +end | ... | ... |
app/models/article.rb
| ... | ... | @@ -237,6 +237,14 @@ class Article < ActiveRecord::Base |
| 237 | 237 | false |
| 238 | 238 | end |
| 239 | 239 | |
| 240 | + def forum? | |
| 241 | + false | |
| 242 | + end | |
| 243 | + | |
| 244 | + def has_posts? | |
| 245 | + false | |
| 246 | + end | |
| 247 | + | |
| 240 | 248 | def published? |
| 241 | 249 | if self.published |
| 242 | 250 | if self.parent && !self.parent.published? |
| ... | ... | @@ -248,8 +256,9 @@ class Article < ActiveRecord::Base |
| 248 | 256 | end |
| 249 | 257 | end |
| 250 | 258 | |
| 251 | - named_scope :published, :conditions => { :published => true } | |
| 252 | - named_scope :folders, :conditions => { :type => ['Folder', 'Blog'] } | |
| 259 | + named_scope :published, :conditions => { :published => true } | |
| 260 | + named_scope :folders, :conditions => { :type => ['Folder', 'Blog', 'Forum', 'Gallery'] } | |
| 261 | + named_scope :galleries, :conditions => { :type => 'Gallery' } | |
| 253 | 262 | named_scope :images, :conditions => { :is_image => true } |
| 254 | 263 | |
| 255 | 264 | def self.display_filter(user, profile) |
| ... | ... | @@ -350,7 +359,7 @@ class Article < ActiveRecord::Base |
| 350 | 359 | false |
| 351 | 360 | end |
| 352 | 361 | |
| 353 | - def display_as_gallery? | |
| 362 | + def gallery? | |
| 354 | 363 | false |
| 355 | 364 | end |
| 356 | 365 | ... | ... |
app/models/blog.rb
| 1 | 1 | class Blog < Folder |
| 2 | 2 | |
| 3 | - has_many :posts, :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'articles.type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC' | |
| 4 | - | |
| 5 | - attr_accessor :feed_attrs | |
| 6 | - | |
| 7 | - after_create do |blog| | |
| 8 | - blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile) | |
| 9 | - blog.feed = blog.feed_attrs | |
| 10 | - end | |
| 11 | - | |
| 12 | - settings_items :posts_per_page, :type => :integer, :default => 5 | |
| 3 | + acts_as_having_posts | |
| 13 | 4 | |
| 14 | 5 | def self.short_description |
| 15 | 6 | _('Blog') |
| ... | ... | @@ -35,21 +26,6 @@ class Blog < Folder |
| 35 | 26 | true |
| 36 | 27 | end |
| 37 | 28 | |
| 38 | - def feed | |
| 39 | - self.children.find(:first, :conditions => {:type => 'RssFeed'}) | |
| 40 | - end | |
| 41 | - | |
| 42 | - def feed=(attrs) | |
| 43 | - if attrs | |
| 44 | - if self.feed | |
| 45 | - self.feed.update_attributes(attrs) | |
| 46 | - else | |
| 47 | - self.feed_attrs = attrs | |
| 48 | - end | |
| 49 | - end | |
| 50 | - self.feed | |
| 51 | - end | |
| 52 | - | |
| 53 | 29 | has_one :external_feed, :foreign_key => 'blog_id', :dependent => :destroy |
| 54 | 30 | |
| 55 | 31 | attr_accessor :external_feed_data |
| ... | ... | @@ -78,17 +54,7 @@ class Blog < Folder |
| 78 | 54 | end |
| 79 | 55 | end |
| 80 | 56 | |
| 81 | - def name=(value) | |
| 82 | - self.set_name(value) | |
| 83 | - if self.slug.blank? | |
| 84 | - self.slug = self.name.to_slug | |
| 85 | - else | |
| 86 | - self.slug = self.slug.to_slug | |
| 87 | - end | |
| 88 | - end | |
| 89 | - | |
| 90 | 57 | settings_items :visualization_format, :type => :string, :default => 'full' |
| 91 | 58 | validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format |
| 92 | 59 | |
| 93 | - | |
| 94 | 60 | end | ... | ... |
app/models/folder.rb
| ... | ... | @@ -2,23 +2,11 @@ class Folder < Article |
| 2 | 2 | |
| 3 | 3 | acts_as_having_settings :field => :setting |
| 4 | 4 | |
| 5 | - settings_items :view_as, :type => :string, :default => 'folder' | |
| 6 | - | |
| 7 | 5 | xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation' |
| 8 | 6 | |
| 9 | 7 | include WhiteListFilter |
| 10 | 8 | filter_iframes :body, :whitelist => lambda { profile && profile.environment && profile.environment.trusted_sites_for_iframe } |
| 11 | 9 | |
| 12 | - def self.select_views | |
| 13 | - [[_('Folder'), 'folder'], [_('Image gallery'), 'image_gallery']] | |
| 14 | - end | |
| 15 | - | |
| 16 | - def self.views | |
| 17 | - select_views.map(&:last) | |
| 18 | - end | |
| 19 | - | |
| 20 | - validates_inclusion_of :view_as, :in => self.views | |
| 21 | - | |
| 22 | 10 | def self.short_description |
| 23 | 11 | _('Folder') |
| 24 | 12 | end |
| ... | ... | @@ -31,33 +19,18 @@ class Folder < Article |
| 31 | 19 | 'folder' |
| 32 | 20 | end |
| 33 | 21 | |
| 34 | - | |
| 22 | + include ActionView::Helpers::TagHelper | |
| 35 | 23 | def to_html(options = {}) |
| 36 | - send(view_as) | |
| 37 | - end | |
| 38 | - | |
| 39 | - def folder | |
| 40 | 24 | folder = self |
| 41 | 25 | lambda do |
| 42 | 26 | render :file => 'content_viewer/folder', :locals => { :folder => folder } |
| 43 | 27 | end |
| 44 | 28 | end |
| 45 | 29 | |
| 46 | - def image_gallery | |
| 47 | - article = self | |
| 48 | - lambda do | |
| 49 | - render :file => 'content_viewer/image_gallery', :locals => {:article => article} | |
| 50 | - end | |
| 51 | - end | |
| 52 | - | |
| 53 | 30 | def folder? |
| 54 | 31 | true |
| 55 | 32 | end |
| 56 | 33 | |
| 57 | - def display_as_gallery? | |
| 58 | - view_as == 'image_gallery' | |
| 59 | - end | |
| 60 | - | |
| 61 | 34 | def can_display_hits? |
| 62 | 35 | false |
| 63 | 36 | end |
| ... | ... | @@ -74,6 +47,6 @@ class Folder < Article |
| 74 | 47 | :foreign_key => 'parent_id', |
| 75 | 48 | :order => 'articles.type, articles.name', |
| 76 | 49 | :include => :reference_article, |
| 77 | - :conditions => ["articles.type = 'UploadedFile' and articles.content_type in (?) or articles.type = 'Folder' or (articles.type = 'PublishedArticle' and reference_articles_articles.type = 'UploadedFile' and reference_articles_articles.content_type in (?))", UploadedFile.content_types, UploadedFile.content_types] | |
| 50 | + :conditions => ["articles.type = 'UploadedFile' and articles.content_type in (?) or articles.type in ('Folder','Gallery') or (articles.type = 'PublishedArticle' and reference_articles_articles.type = 'UploadedFile' and reference_articles_articles.content_type in (?))", UploadedFile.content_types, UploadedFile.content_types] | |
| 78 | 51 | |
| 79 | 52 | end | ... | ... |
| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | +class Forum < Folder | |
| 2 | + | |
| 3 | + acts_as_having_posts :order => 'updated_at DESC' | |
| 4 | + | |
| 5 | + def self.short_description | |
| 6 | + _('Forum') | |
| 7 | + end | |
| 8 | + | |
| 9 | + def self.description | |
| 10 | + _('An internet forum, also called message board, where discussions can be held.') | |
| 11 | + end | |
| 12 | + | |
| 13 | + include ActionView::Helpers::TagHelper | |
| 14 | + def to_html(options = {}) | |
| 15 | + lambda do | |
| 16 | + render :file => 'content_viewer/forum_page' | |
| 17 | + end | |
| 18 | + end | |
| 19 | + | |
| 20 | + def forum? | |
| 21 | + true | |
| 22 | + end | |
| 23 | + | |
| 24 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | +class Gallery < Folder | |
| 2 | + | |
| 3 | + def self.short_description | |
| 4 | + _('Gallery') | |
| 5 | + end | |
| 6 | + | |
| 7 | + def self.description | |
| 8 | + _('A gallery, inside which you can put images.') | |
| 9 | + end | |
| 10 | + | |
| 11 | + include ActionView::Helpers::TagHelper | |
| 12 | + def to_html(options) | |
| 13 | + article = self | |
| 14 | + lambda do | |
| 15 | + render :file => 'content_viewer/image_gallery', :locals => {:article => article} | |
| 16 | + end | |
| 17 | + end | |
| 18 | + | |
| 19 | + def gallery? | |
| 20 | + true | |
| 21 | + end | |
| 22 | + | |
| 23 | +end | ... | ... |
app/models/organization.rb
app/models/person.rb
app/models/profile.rb
| ... | ... | @@ -525,7 +525,7 @@ private :generate_url, :url_options |
| 525 | 525 | # associated to the profile before being saved. Example: |
| 526 | 526 | # |
| 527 | 527 | # def default_set_of_articles |
| 528 | - # [Blog.new(:name => 'Blog'), Folder.new(:name => 'Gallery', :view_as => 'image_gallery')] | |
| 528 | + # [Blog.new(:name => 'Blog'), Gallery.new(:name => 'Gallery')] | |
| 529 | 529 | # end |
| 530 | 530 | # |
| 531 | 531 | # By default, this method returns an empty array. |
| ... | ... | @@ -690,6 +690,16 @@ private :generate_url, :url_options |
| 690 | 690 | self.blogs.count.nonzero? |
| 691 | 691 | end |
| 692 | 692 | |
| 693 | + has_many :forums, :source => 'articles', :class_name => 'Forum' | |
| 694 | + | |
| 695 | + def forum | |
| 696 | + self.has_forum? ? self.forums.first(:order => 'id') : nil | |
| 697 | + end | |
| 698 | + | |
| 699 | + def has_forum? | |
| 700 | + self.forums.count.nonzero? | |
| 701 | + end | |
| 702 | + | |
| 693 | 703 | def admins |
| 694 | 704 | self.members_by_role(Profile::Roles.admin(environment.id)) |
| 695 | 705 | end |
| ... | ... | @@ -703,7 +713,7 @@ private :generate_url, :url_options |
| 703 | 713 | end |
| 704 | 714 | |
| 705 | 715 | def image_galleries |
| 706 | - folders.select { |folder| folder.display_as_gallery?} | |
| 716 | + articles.galleries | |
| 707 | 717 | end |
| 708 | 718 | |
| 709 | 719 | def blocks_to_expire_cache | ... | ... |
app/models/rss_feed.rb
| ... | ... | @@ -61,7 +61,7 @@ class RssFeed < Article |
| 61 | 61 | |
| 62 | 62 | include ActionController::UrlWriter |
| 63 | 63 | def fetch_articles |
| 64 | - if parent && parent.blog? | |
| 64 | + if parent && parent.has_posts? | |
| 65 | 65 | return parent.posts.find(:all, :conditions => ['published = ?', true], :limit => self.limit, :order => 'id desc') |
| 66 | 66 | end |
| 67 | 67 | ... | ... |
app/models/slideshow_block.rb
| ... | ... | @@ -11,7 +11,7 @@ class SlideshowBlock < Block |
| 11 | 11 | end |
| 12 | 12 | |
| 13 | 13 | def gallery |
| 14 | - gallery_id ? Folder.find(:first, :conditions => { :id => gallery_id }) : nil | |
| 14 | + gallery_id ? Gallery.find(:first, :conditions => { :id => gallery_id }) : nil | |
| 15 | 15 | end |
| 16 | 16 | |
| 17 | 17 | def public_filename_for(image) | ... | ... |
app/models/uploaded_file.rb
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # of the file itself is kept. (FIXME?) |
| 5 | 5 | class UploadedFile < Article |
| 6 | 6 | |
| 7 | - track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.display_as_gallery? } | |
| 7 | + track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? } | |
| 8 | 8 | |
| 9 | 9 | include ShortFilename |
| 10 | 10 | |
| ... | ... | @@ -76,7 +76,7 @@ class UploadedFile < Article |
| 76 | 76 | article = self |
| 77 | 77 | if image? |
| 78 | 78 | lambda do |
| 79 | - if article.display_as_gallery? && options[:gallery_view] | |
| 79 | + if article.gallery? && options[:gallery_view] | |
| 80 | 80 | images = article.parent.images |
| 81 | 81 | current_index = images.index(article) |
| 82 | 82 | total_of_images = images.count |
| ... | ... | @@ -119,7 +119,7 @@ class UploadedFile < Article |
| 119 | 119 | false |
| 120 | 120 | end |
| 121 | 121 | |
| 122 | - def display_as_gallery? | |
| 123 | - self.parent && self.parent.folder? && self.parent.display_as_gallery? | |
| 122 | + def gallery? | |
| 123 | + self.parent && self.parent.folder? && self.parent.gallery? | |
| 124 | 124 | end |
| 125 | 125 | end | ... | ... |
app/views/cms/_folder.rhtml
| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | +<%= error_messages_for 'forum' %> | |
| 2 | + | |
| 3 | +<h1><%= _('My Forum') %></h1> | |
| 4 | + | |
| 5 | +<%= render :file => 'shared/tiny_mce' %> | |
| 6 | + | |
| 7 | +<%= required f.text_field(:name, :size => '64', :onchange => "updateUrlField(this, 'article_slug')") %> | |
| 8 | + | |
| 9 | +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %> | |
| 10 | + | |
| 11 | +<%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, [5, 10, 20, 50, 100])) %> | ... | ... |
app/views/cms/view.rhtml
| ... | ... | @@ -5,9 +5,11 @@ |
| 5 | 5 | <% button_bar(:style => 'margin-bottom: 1em;') do %> |
| 6 | 6 | <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> |
| 7 | 7 | |
| 8 | - <% if !@article or !@article.blog? %> | |
| 8 | + <% if !@article or !@article.has_posts? %> | |
| 9 | 9 | <%= button :newfolder, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %> |
| 10 | 10 | <%= button :newblog, _('New Blog'), :action => 'new', :type => 'Blog', :parent_id => parent_id %> |
| 11 | + <%= button :newforum, _('New Forum'), :action => 'new', :type => 'Forum', :parent_id => parent_id %> | |
| 12 | + <%= button :newgallery, _('New Gallery'), :action => 'new', :type => 'Gallery', :parent_id => parent_id %> | |
| 11 | 13 | <%= button('upload-file', _('Upload files'), :action => 'upload_files', :parent_id => parent_id) %> |
| 12 | 14 | <% end %> |
| 13 | 15 | <%= lightbox_button('new', label_for_new_article(@article), :action => 'new', :parent_id => parent_id) %> | ... | ... |
| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | +<% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.forum? && @page.feed %> | |
| 2 | + | |
| 3 | +<div> | |
| 4 | + <div class='forum-description'> | |
| 5 | + <%= @page.body %> | |
| 6 | + </div> | |
| 7 | +</div> | |
| 8 | +<hr class="pre-posts"/> | |
| 9 | +<div class="forum-posts"> | |
| 10 | + <%= (@posts.compact.empty? ? content_tag('em', _('(no posts)')) : list_forum_posts(@posts)) %> | |
| 11 | +</div> | ... | ... |
app/views/content_viewer/view_page.rhtml
| 1 | 1 | <% |
| 2 | - if @page.parent && @page.parent.blog? && @page.parent.feed | |
| 2 | + if @page.parent && @page.parent.has_posts? && @page.parent.feed | |
| 3 | 3 | add_rss_feed_to_head(@page.parent.name, @page.parent.feed.url) |
| 4 | 4 | end |
| 5 | 5 | %> |
| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }), |
| 16 | 16 | :class => 'button with-text icon-edit' %> |
| 17 | 17 | <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %> |
| 18 | - <% if @page != profile.home_page && !@page.blog? %> | |
| 18 | + <% if @page != profile.home_page && !@page.has_posts? %> | |
| 19 | 19 | <%= link_to content_tag( 'span', _('Delete') ), |
| 20 | 20 | profile.admin_url.merge({ :controller => 'cms', :action => 'destroy', :id => @page }), |
| 21 | 21 | :class => 'button with-text icon-delete' %> |
| ... | ... | @@ -34,20 +34,20 @@ |
| 34 | 34 | <% end %> |
| 35 | 35 | <% end %> |
| 36 | 36 | <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %> |
| 37 | - <% if !@page.display_as_gallery? %> | |
| 37 | + <% if !@page.gallery? %> | |
| 38 | 38 | <%= lightbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) %> |
| 39 | 39 | <% end %> |
| 40 | - <% if (@page.folder? && !@page.blog?) || (@page.parent && @page.parent.folder? && !@page.parent.blog?) %> | |
| 40 | + <% if (@page.folder? && !@page.has_posts?) || (@page.parent && @page.parent.folder? && !@page.parent.has_posts?) %> | |
| 41 | 41 | <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) %> |
| 42 | 42 | <% end %> |
| 43 | 43 | <% end %> |
| 44 | - <% if profile.kind_of?(Enterprise) && @page.display_as_gallery? %> | |
| 44 | + <% if profile.kind_of?(Enterprise) && @page.gallery? %> | |
| 45 | 45 | <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %> |
| 46 | 46 | <% end %> |
| 47 | 47 | </div> |
| 48 | 48 | <% end %> |
| 49 | 49 | <div id="article-header"> |
| 50 | - <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.blog? && @page.feed %> | |
| 50 | + <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> | |
| 51 | 51 | <%= article_title(@page, :no_link => true) %> |
| 52 | 52 | </div> |
| 53 | 53 | </div> | ... | ... |
config/initializers/dependencies.rb
db/migrate/20101129234429_convert_folders_to_galleries.rb
0 → 100644
| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | +class ConvertFoldersToGalleries < ActiveRecord::Migration | |
| 2 | + def self.up | |
| 3 | + select_all("select id, setting from articles where type = 'Folder'").each do |folder| | |
| 4 | + view_as = YAML.load(folder['setting'])[:view_as] | |
| 5 | + update("update articles set type = 'Gallery' where id = %d" % folder['id']) if view_as == 'image_gallery' | |
| 6 | + end | |
| 7 | + end | |
| 8 | + | |
| 9 | + def self.down | |
| 10 | + select_all("select id, setting from articles where type = 'Gallery'").each do |folder| | |
| 11 | + settings = YAML.load(folder['setting']) | |
| 12 | + settings[:view_as] = 'image_gallery' | |
| 13 | + assignments = ActiveRecord::Base.sanitize_sql_for_assignment(:setting => settings.to_yaml) | |
| 14 | + update("update articles set %s, type = 'Folder' where id = %d" % [assignments, folder['id']]) | |
| 15 | + end | |
| 16 | + end | |
| 17 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | +Feature: forum | |
| 2 | + As a noosfero user | |
| 3 | + I want to have one or mutiple forums | |
| 4 | + | |
| 5 | + Background: | |
| 6 | + Given I am on the homepage | |
| 7 | + And the following users | |
| 8 | + | login | name | | |
| 9 | + | joaosilva | Joao Silva | | |
| 10 | + And "joaosilva" has no articles | |
| 11 | + And I am logged in as "joaosilva" | |
| 12 | + | |
| 13 | + Scenario: create a forum | |
| 14 | + Given I go to the Control panel | |
| 15 | + And I follow "Manage Content" | |
| 16 | + When I follow "New Forum" | |
| 17 | + And I fill in "Title" with "My Forum" | |
| 18 | + And I press "Save" | |
| 19 | + Then I should see "Configure forum" | |
| 20 | + | |
| 21 | + Scenario: redirect to forum after create forum from cms | |
| 22 | + Given I go to the Control panel | |
| 23 | + And I follow "Manage Content" | |
| 24 | + When I follow "New Forum" | |
| 25 | + And I fill in "Title" with "Forum from cms" | |
| 26 | + And I press "Save" | |
| 27 | + Then I should be on /joaosilva/forum-from-cms | |
| 28 | + | |
| 29 | + Scenario: create multiple forums | |
| 30 | + Given I go to the Control panel | |
| 31 | + And I follow "Manage Content" | |
| 32 | + And I follow "New Forum" | |
| 33 | + And I fill in "Title" with "Forum One" | |
| 34 | + And I press "Save" | |
| 35 | + Then I go to the Control panel | |
| 36 | + And I follow "Manage Content" | |
| 37 | + And I follow "New Forum" | |
| 38 | + And I fill in "Title" with "Forum Two" | |
| 39 | + And I press "Save" | |
| 40 | + Then I should not see "error" | |
| 41 | + And I should be on /joaosilva/forum-two | |
| 42 | + | |
| 43 | + Scenario: cancel button back to cms | |
| 44 | + Given I go to the Control panel | |
| 45 | + And I follow "Manage Content" | |
| 46 | + And I follow "New Forum" | |
| 47 | + When I follow "Cancel" within ".main-block" | |
| 48 | + Then I should be on /myprofile/joaosilva/cms | |
| 49 | + | |
| 50 | + Scenario: cancel button back to myprofile | |
| 51 | + Given I go to the Control panel | |
| 52 | + And I follow "Manage Content" | |
| 53 | + And I follow "New Forum" | |
| 54 | + When I follow "Cancel" within ".main-block" | |
| 55 | + Then I should be on /myprofile/joaosilva/cms | |
| 56 | + | |
| 57 | + Scenario: configure forum when viewing it | |
| 58 | + Given the following forums | |
| 59 | + | owner | name | | |
| 60 | + | joaosilva | Forum One | | |
| 61 | + And I go to /joaosilva/forum-one | |
| 62 | + When I follow "Configure forum" | |
| 63 | + Then I should be on edit "Forum One" by joaosilva | ... | ... |
features/gallery_navigation.feature
| ... | ... | @@ -6,9 +6,9 @@ Feature: gallery_navigation |
| 6 | 6 | Given the following users |
| 7 | 7 | | login | |
| 8 | 8 | | marciopunk | |
| 9 | - And the following folders | |
| 10 | - | owner | name | view_as | | |
| 11 | - | marciopunk | my-gallery | image_gallery | | |
| 9 | + And the following galleries | |
| 10 | + | owner | name | | |
| 11 | + | marciopunk | my-gallery | | |
| 12 | 12 | And the following files |
| 13 | 13 | | owner | file | mime | parent | |
| 14 | 14 | | marciopunk | rails.png | image/png | my-gallery | | ... | ... |
features/step_definitions/noosfero_steps.rb
| ... | ... | @@ -41,12 +41,14 @@ Given /^the following blocks$/ do |table| |
| 41 | 41 | end |
| 42 | 42 | end |
| 43 | 43 | |
| 44 | -Given /^the following (articles|events|blogs|folders)$/ do |content, table| | |
| 44 | +Given /^the following (articles|events|blogs|folders|forums|galleries)$/ do |content, table| | |
| 45 | 45 | klass = { |
| 46 | 46 | 'articles' => TextileArticle, |
| 47 | 47 | 'events' => Event, |
| 48 | 48 | 'blogs' => Blog, |
| 49 | 49 | 'folders' => Folder, |
| 50 | + 'forums' => Forum, | |
| 51 | + 'galleries' => Gallery | |
| 50 | 52 | }[content] || raise("Don't know how to build %s" % content) |
| 51 | 53 | table.hashes.map{|item| item.dup}.each do |item| |
| 52 | 54 | owner_identifier = item.delete("owner") | ... | ... |
| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | +module ActsAsHavingPosts | |
| 2 | + | |
| 3 | + module ClassMethods | |
| 4 | + def acts_as_having_posts(options = {}) | |
| 5 | + has_many :posts, { :class_name => 'Article', :foreign_key => 'parent_id', :source => :children, :conditions => [ 'articles.type != ?', 'RssFeed' ], :order => 'published_at DESC, id DESC' }.merge(options) | |
| 6 | + | |
| 7 | + attr_accessor :feed_attrs | |
| 8 | + | |
| 9 | + after_create do |blog| | |
| 10 | + blog.children << RssFeed.new(:name => 'feed', :profile => blog.profile) | |
| 11 | + blog.feed = blog.feed_attrs | |
| 12 | + end | |
| 13 | + | |
| 14 | + settings_items :posts_per_page, :type => :integer, :default => 5 | |
| 15 | + | |
| 16 | + self.send(:include, ActsAsHavingPosts) | |
| 17 | + end | |
| 18 | + end | |
| 19 | + | |
| 20 | + def has_posts? | |
| 21 | + true | |
| 22 | + end | |
| 23 | + | |
| 24 | + def feed | |
| 25 | + self.children.find(:first, :conditions => {:type => 'RssFeed'}) | |
| 26 | + end | |
| 27 | + | |
| 28 | + def feed=(attrs) | |
| 29 | + if attrs | |
| 30 | + if self.feed | |
| 31 | + self.feed.update_attributes(attrs) | |
| 32 | + else | |
| 33 | + self.feed_attrs = attrs | |
| 34 | + end | |
| 35 | + end | |
| 36 | + self.feed | |
| 37 | + end | |
| 38 | + | |
| 39 | + def name=(value) | |
| 40 | + self.set_name(value) | |
| 41 | + self.slug = self.slug.blank? ? self.name.to_slug : self.slug.to_slug | |
| 42 | + end | |
| 43 | + | |
| 44 | +end | |
| 45 | + | |
| 46 | +ActiveRecord::Base.extend(ActsAsHavingPosts::ClassMethods) | ... | ... |
public/designs/icons/tango/style.css
| ... | ... | @@ -73,3 +73,5 @@ |
| 73 | 73 | .icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat } |
| 74 | 74 | .icon-scrap { background-image: url(Tango/16x16/actions/format-justify-left.png) } |
| 75 | 75 | .icon-reply { background-image: url(Tango/16x16/actions/mail-reply-sender.png) } |
| 76 | +.icon-newforum { background-image: url(Tango/16x16/apps/system-users.png) } | |
| 77 | +.icon-newgallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | ... | ... |
public/designs/themes/base/style.css
public/stylesheets/application.css
test/factories.rb
| ... | ... | @@ -409,4 +409,22 @@ module Noosfero::Factory |
| 409 | 409 | { :login => username, :email => username + '@noosfero.colivre', :crypted_password => 'test'}.merge(params) |
| 410 | 410 | end |
| 411 | 411 | |
| 412 | + ############################################### | |
| 413 | + # Forum | |
| 414 | + ############################################### | |
| 415 | + | |
| 416 | + def defaults_for_forum(params = {}) | |
| 417 | + name = "forum_#{rand(1000)}" | |
| 418 | + { :profile_id => 1, :path => name, :name => name, :slug => name.to_slug }.merge(params) | |
| 419 | + end | |
| 420 | + | |
| 421 | + ############################################### | |
| 422 | + # Gallery | |
| 423 | + ############################################### | |
| 424 | + | |
| 425 | + def defaults_for_gallery(params = {}) | |
| 426 | + name = "gallery_#{rand(1000)}" | |
| 427 | + { :profile_id => 1, :path => name, :name => name, :slug => name.to_slug }.merge(params) | |
| 428 | + end | |
| 429 | + | |
| 412 | 430 | end | ... | ... |
test/functional/cms_controller_test.rb
| ... | ... | @@ -802,6 +802,7 @@ class CmsControllerTest < Test::Unit::TestCase |
| 802 | 802 | should 'not offer to create special article types' do |
| 803 | 803 | get :new, :profile => profile.identifier |
| 804 | 804 | assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Blog"} |
| 805 | + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Forum"} | |
| 805 | 806 | end |
| 806 | 807 | |
| 807 | 808 | should 'offer to edit a blog' do |
| ... | ... | @@ -918,7 +919,7 @@ class CmsControllerTest < Test::Unit::TestCase |
| 918 | 919 | end |
| 919 | 920 | |
| 920 | 921 | should 'create icon upload file in folder' do |
| 921 | - f = Folder.create!(:name => 'test_folder', :profile => profile, :view_as => 'image_gallery') | |
| 922 | + f = Gallery.create!(:name => 'test_folder', :profile => profile) | |
| 922 | 923 | post :new, :profile => profile.identifier, |
| 923 | 924 | :type => UploadedFile.name, |
| 924 | 925 | :parent_id => f.id, |
| ... | ... | @@ -1155,6 +1156,8 @@ class CmsControllerTest < Test::Unit::TestCase |
| 1155 | 1156 | |
| 1156 | 1157 | image = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 1157 | 1158 | image2 = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :created_at => 1.day.ago) |
| 1159 | + image2.updated_at = 1.day.ago | |
| 1160 | + image2.send :update_without_callbacks | |
| 1158 | 1161 | |
| 1159 | 1162 | get :media_listing, :profile => profile.identifier |
| 1160 | 1163 | |
| ... | ... | @@ -1296,4 +1299,115 @@ class CmsControllerTest < Test::Unit::TestCase |
| 1296 | 1299 | file_2.destroy |
| 1297 | 1300 | end |
| 1298 | 1301 | |
| 1302 | + # Forum | |
| 1303 | + | |
| 1304 | + should 'display posts per page input with default value on edit forum' do | |
| 1305 | + n = Forum.new.posts_per_page.to_s | |
| 1306 | + get :new, :profile => profile.identifier, :type => 'Forum' | |
| 1307 | + assert_tag :tag => 'select', :attributes => { :name => 'article[posts_per_page]' }, :child => { :tag => 'option', :attributes => {:value => n, :selected => 'selected'} } | |
| 1308 | + end | |
| 1309 | + | |
| 1310 | + should 'offer to edit a forum' do | |
| 1311 | + profile.articles << Forum.new(:name => 'forum test', :profile => profile) | |
| 1312 | + | |
| 1313 | + profile.articles.reload | |
| 1314 | + assert profile.has_forum? | |
| 1315 | + | |
| 1316 | + b = profile.forum | |
| 1317 | + get :index, :profile => profile.identifier | |
| 1318 | + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/edit/#{b.id}"} | |
| 1319 | + end | |
| 1320 | + | |
| 1321 | + should 'not offer to add folder to forum' do | |
| 1322 | + profile.articles << Forum.new(:name => 'forum test', :profile => profile) | |
| 1323 | + | |
| 1324 | + profile.articles.reload | |
| 1325 | + assert profile.has_forum? | |
| 1326 | + | |
| 1327 | + get :view, :profile => profile.identifier, :id => profile.forum.id | |
| 1328 | + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?parent_id=#{profile.forum.id}&type=Folder"} | |
| 1329 | + end | |
| 1330 | + | |
| 1331 | + should 'not show feed subitem for forum' do | |
| 1332 | + profile.articles << Forum.new(:name => 'Forum for test', :profile => profile) | |
| 1333 | + | |
| 1334 | + profile.articles.reload | |
| 1335 | + assert profile.has_forum? | |
| 1336 | + | |
| 1337 | + get :view, :profile => profile.identifier, :id => profile.forum.id | |
| 1338 | + | |
| 1339 | + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/edit/#{profile.forum.feed.id}" } | |
| 1340 | + end | |
| 1341 | + | |
| 1342 | + should 'update feed options by edit forum form' do | |
| 1343 | + profile.articles << Forum.new(:name => 'Forum for test', :profile => profile) | |
| 1344 | + post :edit, :profile => profile.identifier, :id => profile.forum.id, :article => { :feed => { :limit => 7 } } | |
| 1345 | + assert_equal 7, profile.forum.feed.limit | |
| 1346 | + end | |
| 1347 | + | |
| 1348 | + should 'not offer folder to forum articles' do | |
| 1349 | + @controller.stubs(:profile).returns(fast_create(Enterprise, :name => 'test_ent', :identifier => 'test_ent')) | |
| 1350 | + forum = Forum.create!(:name => 'Forum for test', :profile => profile) | |
| 1351 | + @controller.stubs(:params).returns({ :parent_id => forum.id }) | |
| 1352 | + | |
| 1353 | + assert_not_includes @controller.available_article_types, Folder | |
| 1354 | + end | |
| 1355 | + | |
| 1356 | + should 'not offer rssfeed to forum articles' do | |
| 1357 | + @controller.stubs(:profile).returns(fast_create(Enterprise, :name => 'test_ent', :identifier => 'test_ent')) | |
| 1358 | + forum = Forum.create!(:name => 'Forum for test', :profile => profile) | |
| 1359 | + @controller.stubs(:params).returns({ :parent_id => forum.id }) | |
| 1360 | + | |
| 1361 | + assert_not_includes @controller.available_article_types, RssFeed | |
| 1362 | + end | |
| 1363 | + | |
| 1364 | + should 'update forum posts_per_page setting' do | |
| 1365 | + profile.articles << Forum.new(:name => 'Forum for test', :profile => profile) | |
| 1366 | + post :edit, :profile => profile.identifier, :id => profile.forum.id, :article => { :posts_per_page => 5 } | |
| 1367 | + profile.forum.reload | |
| 1368 | + assert_equal 5, profile.forum.posts_per_page | |
| 1369 | + end | |
| 1370 | + | |
| 1371 | + should "display 'New post' when create children of forum" do | |
| 1372 | + a = Forum.create!(:name => 'forum_for_test', :profile => profile) | |
| 1373 | + Article.stubs(:short_description).returns('bli') | |
| 1374 | + get :view, :profile => profile.identifier, :id => a | |
| 1375 | + assert_tag :tag => 'a', :content => 'New discussion topic' | |
| 1376 | + end | |
| 1377 | + | |
| 1378 | + should 'go to forum after create it' do | |
| 1379 | + assert_difference Forum, :count do | |
| 1380 | + post :new, :type => Forum.name, :profile => profile.identifier, :article => { :name => 'my-forum' }, :back_to => 'control_panel' | |
| 1381 | + end | |
| 1382 | + assert_redirected_to @profile.articles.find_by_name('my-forum').view_url | |
| 1383 | + end | |
| 1384 | + | |
| 1385 | + should 'back to forum after config forum' do | |
| 1386 | + profile.articles << Forum.new(:name => 'my-forum', :profile => profile) | |
| 1387 | + post :edit, :profile => profile.identifier, :id => profile.forum.id | |
| 1388 | + | |
| 1389 | + assert_redirected_to @profile.articles.find_by_name('my-forum').view_url | |
| 1390 | + end | |
| 1391 | + | |
| 1392 | + should 'back to control panel if cancel create forum' do | |
| 1393 | + get :new, :profile => profile.identifier, :type => Forum.name | |
| 1394 | + assert_tag :tag => 'a', :content => 'Cancel', :attributes => { :href => /\/myprofile\/#{profile.identifier}/ } | |
| 1395 | + end | |
| 1396 | + | |
| 1397 | + should 'back to control panel if cancel config forum' do | |
| 1398 | + profile.articles << Forum.new(:name => 'my-forum', :profile => profile) | |
| 1399 | + get :edit, :profile => profile.identifier, :id => profile.forum.id | |
| 1400 | + assert_tag :tag => 'a', :content => 'Cancel', :attributes => { :href => /\/myprofile\/#{profile.identifier}/ } | |
| 1401 | + end | |
| 1402 | + | |
| 1403 | + should 'not offer to upload files to forum' do | |
| 1404 | + profile.articles << Forum.new(:name => 'forum test', :profile => profile) | |
| 1405 | + | |
| 1406 | + profile.articles.reload | |
| 1407 | + assert profile.has_forum? | |
| 1408 | + | |
| 1409 | + get :view, :profile => profile.identifier, :id => profile.forum.id | |
| 1410 | + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/upload_files?parent_id=#{profile.forum.id}"} | |
| 1411 | + end | |
| 1412 | + | |
| 1299 | 1413 | end | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -743,14 +743,14 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 743 | 743 | |
| 744 | 744 | should "display 'Upload files' when create children of image gallery" do |
| 745 | 745 | login_as(profile.identifier) |
| 746 | - f = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 746 | + f = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 747 | 747 | get :view_page, :profile => profile.identifier, :page => f.explode_path |
| 748 | 748 | assert_tag :tag => 'a', :content => 'Upload files', :attributes => {:href => /parent_id=#{f.id}/} |
| 749 | 749 | end |
| 750 | 750 | |
| 751 | 751 | should "display 'New article' when showing folder child of image gallery" do |
| 752 | 752 | login_as(profile.identifier) |
| 753 | - folder1 = Folder.create!(:name => 'gallery1', :profile => profile, :view_as => 'image_gallery') | |
| 753 | + folder1 = Gallery.create!(:name => 'gallery1', :profile => profile) | |
| 754 | 754 | folder1.children << folder2 = Folder.new(:name => 'gallery2', :profile => profile) |
| 755 | 755 | |
| 756 | 756 | get :view_page, :profile => profile.identifier, :page => folder2.explode_path |
| ... | ... | @@ -759,7 +759,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 759 | 759 | |
| 760 | 760 | should "display 'Upload files' to image gallery when showing its children" do |
| 761 | 761 | login_as(profile.identifier) |
| 762 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 762 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 763 | 763 | file = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) |
| 764 | 764 | get :view_page, :profile => profile.identifier, :page => file.explode_path, :view => true |
| 765 | 765 | |
| ... | ... | @@ -784,7 +784,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 784 | 784 | |
| 785 | 785 | should 'display all images from profile in the slideshow' do |
| 786 | 786 | @controller.stubs(:per_page).returns(1) |
| 787 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 787 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 788 | 788 | |
| 789 | 789 | image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 790 | 790 | image2 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) |
| ... | ... | @@ -796,7 +796,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 796 | 796 | |
| 797 | 797 | should 'display default image in the slideshow if thumbnails were not processed' do |
| 798 | 798 | @controller.stubs(:per_page).returns(1) |
| 799 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 799 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 800 | 800 | |
| 801 | 801 | image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 802 | 802 | |
| ... | ... | @@ -807,7 +807,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 807 | 807 | |
| 808 | 808 | should 'display thumbnail image in the slideshow if thumbnails were processed' do |
| 809 | 809 | @controller.stubs(:per_page).returns(1) |
| 810 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 810 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 811 | 811 | |
| 812 | 812 | image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 813 | 813 | |
| ... | ... | @@ -819,7 +819,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 819 | 819 | |
| 820 | 820 | should 'display default image in gallery if thumbnails were not processed' do |
| 821 | 821 | @controller.stubs(:per_page).returns(1) |
| 822 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 822 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 823 | 823 | |
| 824 | 824 | image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 825 | 825 | |
| ... | ... | @@ -830,7 +830,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 830 | 830 | |
| 831 | 831 | should 'display thumbnail image in gallery if thumbnails were processed' do |
| 832 | 832 | @controller.stubs(:per_page).returns(1) |
| 833 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 833 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 834 | 834 | |
| 835 | 835 | image1 = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg')) |
| 836 | 836 | |
| ... | ... | @@ -875,7 +875,7 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 875 | 875 | |
| 876 | 876 | should 'show only first 40 chars of abstract in image gallery' do |
| 877 | 877 | login_as(profile.identifier) |
| 878 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 878 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 879 | 879 | file = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) |
| 880 | 880 | |
| 881 | 881 | file.abstract = 'a long abstract bigger then 40 chars for testing' |
| ... | ... | @@ -958,4 +958,141 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 958 | 958 | assert_tag :tag => 'div', :attributes => { :class => /main-block/ }, :descendant => { :tag => 'a', :attributes => { :href => "/myprofile/testinguser/cms/edit/#{blog.id}" }, :content => 'Configure blog' } |
| 959 | 959 | end |
| 960 | 960 | |
| 961 | + # Forum | |
| 962 | + | |
| 963 | + should 'list unpublished forum posts to owner with a different class' do | |
| 964 | + login_as('testinguser') | |
| 965 | + forum = Forum.create!(:name => 'A forum test', :profile => profile) | |
| 966 | + forum.posts << TextileArticle.create!(:name => 'Post', :profile => profile, :parent => forum, :published => false) | |
| 967 | + | |
| 968 | + get :view_page, :profile => profile.identifier, :page => [forum.path] | |
| 969 | + assert_tag :tag => 'tr', :attributes => {:class => /not-published/} | |
| 970 | + end | |
| 971 | + | |
| 972 | + should 'not list unpublished forum posts to a not logged person' do | |
| 973 | + forum = Forum.create!(:name => 'A forum test', :profile => profile) | |
| 974 | + forum.posts << TextileArticle.create!(:name => 'Post', :profile => profile, :parent => forum, :published => false) | |
| 975 | + | |
| 976 | + get :view_page, :profile => profile.identifier, :page => [forum.path] | |
| 977 | + assert_no_tag :tag => 'a', :content => "Post" | |
| 978 | + end | |
| 979 | + | |
| 980 | + should 'display pagination links of forum' do | |
| 981 | + forum = Forum.create!(:name => 'A forum test', :profile => profile, :posts_per_page => 5) | |
| 982 | + for n in 1..10 | |
| 983 | + forum.posts << TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => forum) | |
| 984 | + end | |
| 985 | + assert_equal 10, forum.posts.size | |
| 986 | + | |
| 987 | + get :view_page, :profile => profile.identifier, :page => [forum.path] | |
| 988 | + assert_tag :tag => 'a', :attributes => { :href => "/#{profile.identifier}/#{forum.path}?npage=2", :rel => 'next' } | |
| 989 | + end | |
| 990 | + | |
| 991 | + should 'display first page of forum posts' do | |
| 992 | + forum = Forum.create!(:name => 'My forum', :profile => profile, :posts_per_page => 5) | |
| 993 | + for n in 1..10 | |
| 994 | + forum.children << art = TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => forum) | |
| 995 | + art.updated_at = (10 - n).days.ago | |
| 996 | + art.send :update_without_callbacks | |
| 997 | + end | |
| 998 | + assert_equal 10, forum.posts.size | |
| 999 | + | |
| 1000 | + get :view_page, :profile => profile.identifier, :page => [forum.path] | |
| 1001 | + for n in 1..5 | |
| 1002 | + assert_no_tag :tag => 'a', :content => "Post #{n}", :parent => { :tag => 'td', :parent => { :tag => 'tr', :attributes => { :class => /forum-post/ } } } | |
| 1003 | + end | |
| 1004 | + for n in 6..10 | |
| 1005 | + assert_tag :tag => 'a', :content => "Post #{n}", :parent => { :tag => 'td', :parent => { :tag => 'tr', :attributes => { :class => /forum-post/ } } } | |
| 1006 | + end | |
| 1007 | + end | |
| 1008 | + | |
| 1009 | + should 'display others pages of forum posts' do | |
| 1010 | + forum = Forum.create!(:name => 'My forum', :profile => profile, :posts_per_page => 5) | |
| 1011 | + for n in 1..10 | |
| 1012 | + forum.children << art = TextileArticle.create!(:name => "Post #{n}", :profile => profile, :parent => forum) | |
| 1013 | + art.updated_at = (10 - n).days.ago | |
| 1014 | + art.send :update_without_callbacks | |
| 1015 | + end | |
| 1016 | + assert_equal 10, forum.posts.size | |
| 1017 | + | |
| 1018 | + get :view_page, :profile => profile.identifier, :page => [forum.path], :npage => 2 | |
| 1019 | + for n in 1..5 | |
| 1020 | + assert_tag :tag => 'a', :content => "Post #{n}", :parent => { :tag => 'td', :parent => { :tag => 'tr', :attributes => { :class => /forum-post/ } } } | |
| 1021 | + end | |
| 1022 | + for n in 6..10 | |
| 1023 | + assert_no_tag :tag => 'a', :content => "Post #{n}", :parent => { :tag => 'td', :parent => { :tag => 'tr', :attributes => { :class => /forum-post/ } } } | |
| 1024 | + end | |
| 1025 | + end | |
| 1026 | + | |
| 1027 | + should 'set year and month filter from URL params for forum' do | |
| 1028 | + forum = Forum.create!(:name => "forum", :profile => profile) | |
| 1029 | + profile.articles << forum | |
| 1030 | + | |
| 1031 | + past_post = TextileArticle.create!(:name => "past post", :profile => profile, :parent => forum, :created_at => forum.created_at - 1.year) | |
| 1032 | + actual_post = TextileArticle.create!(:name => "actual post", :profile => profile, :parent => forum) | |
| 1033 | + forum.children << past_post | |
| 1034 | + forum.children << actual_post | |
| 1035 | + | |
| 1036 | + year, month = profile.forum.created_at.year.to_s, '%02d' % profile.forum.created_at.month | |
| 1037 | + | |
| 1038 | + get :view_page, :profile => profile.identifier, :page => [profile.forum.path], :year => year, :month => month | |
| 1039 | + | |
| 1040 | + assert_no_tag :tag => 'a', :content => past_post.title | |
| 1041 | + assert_tag :tag => 'a', :content => actual_post.title | |
| 1042 | + end | |
| 1043 | + | |
| 1044 | + should "display 'New discussion topic' when create children of forum" do | |
| 1045 | + login_as(profile.identifier) | |
| 1046 | + a = Forum.create!(:name => 'article folder', :profile => profile) | |
| 1047 | + Article.stubs(:short_description).returns('bli') | |
| 1048 | + get :view_page, :profile => profile.identifier, :page => [a.path] | |
| 1049 | + assert_tag :tag => 'a', :content => 'New discussion topic' | |
| 1050 | + end | |
| 1051 | + | |
| 1052 | + should "display same label for new article button of forum parent" do | |
| 1053 | + login_as(profile.identifier) | |
| 1054 | + a = Forum.create!(:name => 'article folder', :profile => profile) | |
| 1055 | + Article.stubs(:short_description).returns('bli') | |
| 1056 | + t = TextileArticle.create!(:name => 'first post', :parent => a, :profile => profile) | |
| 1057 | + get :view_page, :profile => profile.identifier, :page => [t.path] | |
| 1058 | + assert_tag :tag => 'a', :content => 'New discussion topic' | |
| 1059 | + end | |
| 1060 | + | |
| 1061 | + should 'add meta tag to rss feed on view forum' do | |
| 1062 | + login_as(profile.identifier) | |
| 1063 | + profile.articles << Forum.new(:name => 'Forum', :profile => profile) | |
| 1064 | + get :view_page, :profile => profile.identifier, :page => ['forum'] | |
| 1065 | + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'Forum', :href => "http://#{environment.default_hostname}/testinguser/forum/feed" } | |
| 1066 | + end | |
| 1067 | + | |
| 1068 | + should 'add meta tag to rss feed on view post forum' do | |
| 1069 | + login_as(profile.identifier) | |
| 1070 | + profile.articles << Forum.new(:name => 'Forum', :profile => profile) | |
| 1071 | + profile.forum.posts << TextileArticle.new(:name => 'first post', :parent => profile.forum, :profile => profile) | |
| 1072 | + get :view_page, :profile => profile.identifier, :page => ['forum', 'first-post'] | |
| 1073 | + assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'Forum', :href => "http://#{environment.default_hostname}/testinguser/forum/feed" } | |
| 1074 | + end | |
| 1075 | + | |
| 1076 | + should "not display 'Upload files' when viewing forum" do | |
| 1077 | + login_as(profile.identifier) | |
| 1078 | + b = Forum.create!(:name => 'article folder', :profile => profile) | |
| 1079 | + get :view_page, :profile => profile.identifier, :page => b.explode_path | |
| 1080 | + assert_no_tag :tag => 'a', :content => 'Upload files', :attributes => {:href => /parent_id=#{b.id}/} | |
| 1081 | + end | |
| 1082 | + | |
| 1083 | + should "not display 'Upload files' when viewing post from a forum" do | |
| 1084 | + login_as(profile.identifier) | |
| 1085 | + b = Forum.create!(:name => 'article folder', :profile => profile) | |
| 1086 | + forum_post = TextileArticle.create!(:name => 'children-article', :profile => profile, :parent => b) | |
| 1087 | + get :view_page, :profile => profile.identifier, :page => forum_post.explode_path | |
| 1088 | + assert_no_tag :tag => 'a', :content => 'Upload files', :attributes => {:href => /parent_id=#{b.id}/} | |
| 1089 | + end | |
| 1090 | + | |
| 1091 | + should 'display link to edit forum for allowed' do | |
| 1092 | + forum = fast_create(Forum, :profile_id => profile.id, :path => 'forum') | |
| 1093 | + login_as(profile.identifier) | |
| 1094 | + get :view_page, :profile => profile.identifier, :page => forum.explode_path | |
| 1095 | + assert_tag :tag => 'div', :attributes => { :class => /main-block/ }, :descendant => { :tag => 'a', :attributes => { :href => "/myprofile/testinguser/cms/edit/#{forum.id}" }, :content => 'Configure forum' } | |
| 1096 | + end | |
| 1097 | + | |
| 961 | 1098 | end | ... | ... |
test/functional/profile_controller_test.rb
| ... | ... | @@ -459,7 +459,7 @@ class ProfileControllerTest < Test::Unit::TestCase |
| 459 | 459 | end |
| 460 | 460 | |
| 461 | 461 | should 'show number of published images in index' do |
| 462 | - folder = Folder.create!(:name => 'gallery', :profile => profile, :view_as => 'image_gallery') | |
| 462 | + folder = Gallery.create!(:name => 'gallery', :profile => profile) | |
| 463 | 463 | published_file = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) |
| 464 | 464 | unpublished_file = UploadedFile.create!(:profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :published => false) |
| 465 | 465 | ... | ... |
test/unit/article_block_test.rb
| ... | ... | @@ -118,9 +118,7 @@ class ArticleBlockTest < Test::Unit::TestCase |
| 118 | 118 | should 'not display gallery pages navigation in content' do |
| 119 | 119 | profile = create_user('testuser').person |
| 120 | 120 | block = ArticleBlock.new |
| 121 | - gallery = fast_create(Folder, :profile_id => profile.id) | |
| 122 | - gallery.view_as = 'image_gallery' | |
| 123 | - gallery.save! | |
| 121 | + gallery = fast_create(Gallery, :profile_id => profile.id) | |
| 124 | 122 | image = UploadedFile.create!(:profile => profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery) |
| 125 | 123 | block.article = image |
| 126 | 124 | block.save! | ... | ... |
test/unit/article_test.rb
| ... | ... | @@ -1211,4 +1211,19 @@ class ArticleTest < Test::Unit::TestCase |
| 1211 | 1211 | assert_equal 31, (DateTime.parse('2010-07-06')).at_end_of_month.day |
| 1212 | 1212 | end |
| 1213 | 1213 | |
| 1214 | + should 'not be a forum by default' do | |
| 1215 | + assert !fast_create(Article).forum? | |
| 1216 | + end | |
| 1217 | + | |
| 1218 | + should 'not have posts by default' do | |
| 1219 | + assert !fast_create(Article).has_posts? | |
| 1220 | + end | |
| 1221 | + | |
| 1222 | + should 'get article galleries' do | |
| 1223 | + p = fast_create(Profile) | |
| 1224 | + a = fast_create(Article, :profile_id => p.id) | |
| 1225 | + g = fast_create(Gallery, :profile_id => p.id) | |
| 1226 | + assert_equal [g], p.articles.galleries | |
| 1227 | + end | |
| 1228 | + | |
| 1214 | 1229 | end | ... | ... |
test/unit/blog_test.rb
test/unit/folder_test.rb
| ... | ... | @@ -28,31 +28,6 @@ class FolderTest < ActiveSupport::TestCase |
| 28 | 28 | assert_equal false, a.can_display_hits? |
| 29 | 29 | end |
| 30 | 30 | |
| 31 | - should 'be viewed as image gallery' do | |
| 32 | - p = create_user('test_user').person | |
| 33 | - f = fast_create(Folder, :profile_id => p.id) | |
| 34 | - f.view_as = 'image_gallery'; f.save! | |
| 35 | - f.reload | |
| 36 | - | |
| 37 | - assert_equal 'image_gallery', f.view_as | |
| 38 | - end | |
| 39 | - | |
| 40 | - should 'not allow view as bogus' do | |
| 41 | - p = create_user('test_user').person | |
| 42 | - f = fast_create(Folder, :profile_id => p.id) | |
| 43 | - f.view_as = 'bogus' | |
| 44 | - assert !f.save | |
| 45 | - end | |
| 46 | - | |
| 47 | - should 'view as folder by default' do | |
| 48 | - p = create_user('test_user').person | |
| 49 | - f = fast_create(Folder, :profile_id => p.id) | |
| 50 | - f.expects(:folder) | |
| 51 | - f.to_html | |
| 52 | - | |
| 53 | - assert_equal 'folder', f.view_as | |
| 54 | - end | |
| 55 | - | |
| 56 | 31 | should 'have images that are only images or other folders' do |
| 57 | 32 | p = create_user('test_user').person |
| 58 | 33 | f = fast_create(Folder, :profile_id => p.id) | ... | ... |
| ... | ... | @@ -0,0 +1,80 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class ForumHelperTest < Test::Unit::TestCase | |
| 4 | + | |
| 5 | + include BlogHelper | |
| 6 | + include ForumHelper | |
| 7 | + include ContentViewerHelper | |
| 8 | + include ActionView::Helpers::AssetTagHelper | |
| 9 | + include ApplicationHelper | |
| 10 | + | |
| 11 | + def setup | |
| 12 | + stubs(:show_date).returns('') | |
| 13 | + @environment = Environment.default | |
| 14 | + @profile = create_user('forum_helper_test').person | |
| 15 | + @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test') | |
| 16 | + end | |
| 17 | + | |
| 18 | + attr :profile | |
| 19 | + attr :forum | |
| 20 | + | |
| 21 | + def _(s); s; end | |
| 22 | + def h(s); s; end | |
| 23 | + | |
| 24 | + should 'return a label for new children' do | |
| 25 | + assert_kind_of String, cms_label_for_new_children | |
| 26 | + end | |
| 27 | + | |
| 28 | + should 'return a label for edit' do | |
| 29 | + assert_kind_of String, cms_label_for_edit | |
| 30 | + end | |
| 31 | + | |
| 32 | + should 'list posts with different classes' do | |
| 33 | + forum.children << older_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => false) | |
| 34 | + forum.children << newer_post = TextileArticle.create!(:name => 'Second post', :profile => profile, :parent => forum, :published => true) | |
| 35 | + older_post.updated_at = Time.now.ago(1.month); older_post.send(:update_without_callbacks) | |
| 36 | + assert_match /forum-post position-1 first odd-post.*forum-post position-2 last not-published even-post/, list_forum_posts(forum.posts) | |
| 37 | + end | |
| 38 | + | |
| 39 | + should 'return post update if it has no comments' do | |
| 40 | + author = create_user('forum test author').person | |
| 41 | + some_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => true) | |
| 42 | + some_post.expects(:author).returns(author) | |
| 43 | + assert some_post.comments.empty? | |
| 44 | + assert_equal "#{some_post.updated_at.to_s} ago by #{author.name}", last_topic_update(some_post) | |
| 45 | + end | |
| 46 | + | |
| 47 | + should 'return last comment date if it has comments' do | |
| 48 | + some_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => true) | |
| 49 | + a1, a2 = create_user('a1').person, create_user('a2').person | |
| 50 | + some_post.comments << Comment.new(:title => 'test', :body => 'test', :author => a1) | |
| 51 | + some_post.comments << Comment.new(:title => 'test', :body => 'test', :author => a2) | |
| 52 | + c = Comment.last | |
| 53 | + assert_equal 2, some_post.comments.count | |
| 54 | + assert_equal "#{c.created_at.to_s} ago by #{a2.name}", last_topic_update(some_post) | |
| 55 | + end | |
| 56 | + | |
| 57 | + protected | |
| 58 | + | |
| 59 | + def will_paginate(arg1, arg2) | |
| 60 | + end | |
| 61 | + | |
| 62 | + def link_to(content, url) | |
| 63 | + content | |
| 64 | + end | |
| 65 | + | |
| 66 | + def tag(tag, args = {}) | |
| 67 | + attrs = args.map{|k,v| "#{k}='#{v}'"}.join(' ') | |
| 68 | + "<#{tag} #{attrs} />" | |
| 69 | + end | |
| 70 | + | |
| 71 | + def content_tag(tag, content, options = {}) | |
| 72 | + tag_attr = options.blank? ? "" : options.collect{ |o| "#{o[0]}=\"#{o[1]}\"" }.join(' ') | |
| 73 | + "<#{tag}#{tag_attr}>#{content}</#{tag}>" | |
| 74 | + end | |
| 75 | + | |
| 76 | + def time_ago_as_sentence(t = Time.now) | |
| 77 | + t.to_s | |
| 78 | + end | |
| 79 | + | |
| 80 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,103 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class ForumTest < ActiveSupport::TestCase | |
| 4 | + | |
| 5 | + should 'be an article' do | |
| 6 | + assert_kind_of Article, Forum.new | |
| 7 | + end | |
| 8 | + | |
| 9 | + should 'provide proper description' do | |
| 10 | + assert_kind_of String, Forum.description | |
| 11 | + end | |
| 12 | + | |
| 13 | + should 'provide own icon name' do | |
| 14 | + assert_not_equal Article.new.icon_name, Forum.new.icon_name | |
| 15 | + end | |
| 16 | + | |
| 17 | + should 'identify as folder' do | |
| 18 | + assert Forum.new.folder?, 'forum must identity itself as folder' | |
| 19 | + end | |
| 20 | + | |
| 21 | + should 'identify as forum' do | |
| 22 | + assert Forum.new.forum?, 'forum must identity itself as forum' | |
| 23 | + end | |
| 24 | + | |
| 25 | + should 'create rss feed automatically' do | |
| 26 | + p = create_user('testuser').person | |
| 27 | + b = create(Forum, :profile_id => p.id, :name => 'forum_feed_test') | |
| 28 | + assert_kind_of RssFeed, b.feed | |
| 29 | + end | |
| 30 | + | |
| 31 | + should 'save feed options' do | |
| 32 | + p = create_user('testuser').person | |
| 33 | + p.articles << Forum.new(:profile => p, :name => 'forum_feed_test') | |
| 34 | + p.forum.feed = { :limit => 7 } | |
| 35 | + assert_equal 7, p.forum.feed.limit | |
| 36 | + end | |
| 37 | + | |
| 38 | + should 'save feed options after create forum' do | |
| 39 | + p = create_user('testuser').person | |
| 40 | + p.articles << Forum.new(:profile => p, :name => 'forum_feed_test', :feed => { :limit => 7 }) | |
| 41 | + assert_equal 7, p.forum.feed.limit | |
| 42 | + end | |
| 43 | + | |
| 44 | + should 'list 5 posts per page by default' do | |
| 45 | + forum = Forum.new | |
| 46 | + assert_equal 5, forum.posts_per_page | |
| 47 | + end | |
| 48 | + | |
| 49 | + should 'update posts per page setting' do | |
| 50 | + p = create_user('testuser').person | |
| 51 | + p.articles << Forum.new(:profile => p, :name => 'Forum test') | |
| 52 | + forum = p.forum | |
| 53 | + forum.posts_per_page = 7 | |
| 54 | + assert forum.save! | |
| 55 | + assert_equal 7, p.forum.posts_per_page | |
| 56 | + end | |
| 57 | + | |
| 58 | + should 'has posts' do | |
| 59 | + p = create_user('testuser').person | |
| 60 | + forum = fast_create(Forum, :profile_id => p.id, :name => 'Forum test') | |
| 61 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => p.id, :parent_id => forum.id) | |
| 62 | + forum.children << post | |
| 63 | + assert_includes forum.posts, post | |
| 64 | + end | |
| 65 | + | |
| 66 | + should 'not includes rss feed in posts' do | |
| 67 | + p = create_user('testuser').person | |
| 68 | + forum = create(Forum, :profile_id => p.id, :name => 'Forum test') | |
| 69 | + assert_includes forum.children, forum.feed | |
| 70 | + assert_not_includes forum.posts, forum.feed | |
| 71 | + end | |
| 72 | + | |
| 73 | + should 'list posts ordered by updated at' do | |
| 74 | + p = create_user('testuser').person | |
| 75 | + forum = fast_create(Forum, :profile_id => p.id, :name => 'Forum test') | |
| 76 | + newer = create(TextileArticle, :name => 'Post 2', :parent => forum, :profile => p) | |
| 77 | + older = create(TextileArticle, :name => 'Post 1', :parent => forum, :profile => p) | |
| 78 | + older.updated_at = Time.now - 1.month | |
| 79 | + older.send :update_without_callbacks | |
| 80 | + assert_equal [newer, older], forum.posts | |
| 81 | + end | |
| 82 | + | |
| 83 | + should 'profile has more then one forum' do | |
| 84 | + p = create_user('testuser').person | |
| 85 | + fast_create(Forum, :name => 'Forum test', :profile_id => p.id) | |
| 86 | + assert_nothing_raised ActiveRecord::RecordInvalid do | |
| 87 | + Forum.create!(:name => 'Another Forum', :profile => p) | |
| 88 | + end | |
| 89 | + end | |
| 90 | + | |
| 91 | + should 'not update slug from name for existing forum' do | |
| 92 | + p = create_user('testuser').person | |
| 93 | + forum = Forum.create!(:name => 'Forum test', :profile => p) | |
| 94 | + assert_equal 'forum-test', forum.slug | |
| 95 | + forum.name = 'Changed name' | |
| 96 | + assert_not_equal 'changed-name', forum.slug | |
| 97 | + end | |
| 98 | + | |
| 99 | + should 'have posts' do | |
| 100 | + assert Forum.new.has_posts? | |
| 101 | + end | |
| 102 | + | |
| 103 | +end | ... | ... |
| ... | ... | @@ -0,0 +1,138 @@ |
| 1 | +require File.dirname(__FILE__) + '/../test_helper' | |
| 2 | + | |
| 3 | +class GalleryTest < ActiveSupport::TestCase | |
| 4 | + | |
| 5 | + should 'be an article' do | |
| 6 | + assert_kind_of Article, Gallery.new | |
| 7 | + end | |
| 8 | + | |
| 9 | + should 'provide proper description' do | |
| 10 | + assert_kind_of String, Gallery.description | |
| 11 | + end | |
| 12 | + | |
| 13 | + should 'provide proper short description' do | |
| 14 | + assert_kind_of String, Gallery.short_description | |
| 15 | + end | |
| 16 | + | |
| 17 | + should 'provide own icon name' do | |
| 18 | + assert_not_equal Article.new.icon_name, Gallery.new.icon_name | |
| 19 | + end | |
| 20 | + | |
| 21 | + should 'identify as folder' do | |
| 22 | + assert Folder.new.folder?, 'gallery must identity itself as folder' | |
| 23 | + end | |
| 24 | + | |
| 25 | + should 'identify as gallery' do | |
| 26 | + assert Gallery.new.gallery?, 'gallery must identity itself as gallery' | |
| 27 | + end | |
| 28 | + | |
| 29 | + should 'can display hits' do | |
| 30 | + profile = create_user('testuser').person | |
| 31 | + a = fast_create(Gallery, :profile_id => profile.id) | |
| 32 | + assert_equal false, a.can_display_hits? | |
| 33 | + end | |
| 34 | + | |
| 35 | + should 'have images that are only images or other galleries' do | |
| 36 | + p = create_user('test_user').person | |
| 37 | + f = fast_create(Gallery, :profile_id => p.id) | |
| 38 | + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :parent => f, :profile => p) | |
| 39 | + image = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => f, :profile => p) | |
| 40 | + gallery = fast_create(Gallery, :profile_id => p.id, :parent_id => f.id) | |
| 41 | + | |
| 42 | + assert_equivalent [gallery, image], f.images | |
| 43 | + end | |
| 44 | + | |
| 45 | + should 'bring galleries first in alpha order in images listing' do | |
| 46 | + p = create_user('test_user').person | |
| 47 | + f = fast_create(Gallery, :profile_id => p.id) | |
| 48 | + gallery1 = fast_create(Gallery, :name => 'b', :profile_id => p.id, :parent_id => f.id) | |
| 49 | + image = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => f, :profile => p) | |
| 50 | + gallery2 = fast_create(Gallery, :name => 'c', :profile_id => p.id, :parent_id => f.id) | |
| 51 | + gallery3 = fast_create(Gallery, :name => 'a', :profile_id => p.id, :parent_id => f.id) | |
| 52 | + | |
| 53 | + assert_equal [gallery3.id, gallery1.id, gallery2.id, image.id], f.images.map(&:id) | |
| 54 | + end | |
| 55 | + | |
| 56 | + should 'images support pagination' do | |
| 57 | + p = create_user('test_user').person | |
| 58 | + f = fast_create(Gallery, :profile_id => p.id) | |
| 59 | + gallery = fast_create(Gallery, :profile_id => p.id, :parent_id => f.id) | |
| 60 | + image = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => f, :profile => p) | |
| 61 | + | |
| 62 | + assert_equal [image], f.images.paginate(:page => 2, :per_page => 1) | |
| 63 | + end | |
| 64 | + | |
| 65 | + should 'return newest text articles as news' do | |
| 66 | + c = fast_create(Community) | |
| 67 | + gallery = fast_create(Gallery, :profile_id => c.id) | |
| 68 | + f = fast_create(Gallery, :name => 'gallery', :profile_id => c.id, :parent_id => gallery.id) | |
| 69 | + u = UploadedFile.create!(:profile => c, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery) | |
| 70 | + older_t = fast_create(TinyMceArticle, :name => 'old news', :profile_id => c.id, :parent_id => gallery.id) | |
| 71 | + t = fast_create(TinyMceArticle, :name => 'news', :profile_id => c.id, :parent_id => gallery.id) | |
| 72 | + t_in_f = fast_create(TinyMceArticle, :name => 'news', :profile_id => c.id, :parent_id => f.id) | |
| 73 | + | |
| 74 | + assert_equal [t], gallery.news(1) | |
| 75 | + end | |
| 76 | + | |
| 77 | + should 'not return highlighted news when not asked' do | |
| 78 | + c = fast_create(Community) | |
| 79 | + gallery = fast_create(Gallery, :profile_id => c.id) | |
| 80 | + highlighted_t = fast_create(TinyMceArticle, :name => 'high news', :profile_id => c.id, :highlighted => true, :parent_id => gallery.id) | |
| 81 | + t = fast_create(TinyMceArticle, :name => 'news', :profile_id => c.id, :parent_id => gallery.id) | |
| 82 | + | |
| 83 | + assert_equal [t].map(&:slug), gallery.news(2).map(&:slug) | |
| 84 | + end | |
| 85 | + | |
| 86 | + should 'return highlighted news when asked' do | |
| 87 | + c = fast_create(Community) | |
| 88 | + gallery = fast_create(Gallery, :profile_id => c.id) | |
| 89 | + highlighted_t = fast_create(TinyMceArticle, :name => 'high news', :profile_id => c.id, :highlighted => true, :parent_id => gallery.id) | |
| 90 | + t = fast_create(TinyMceArticle, :name => 'news', :profile_id => c.id, :parent_id => gallery.id) | |
| 91 | + | |
| 92 | + assert_equal [highlighted_t].map(&:slug), gallery.news(2, true).map(&:slug) | |
| 93 | + end | |
| 94 | + | |
| 95 | + should 'return published images as images' do | |
| 96 | + p = create_user('test_user').person | |
| 97 | + i = UploadedFile.create!(:profile => p, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | |
| 98 | + | |
| 99 | + c = fast_create(Community) | |
| 100 | + gallery = fast_create(Gallery, :profile_id => c.id) | |
| 101 | + pi = PublishedArticle.create!(:profile => c, :reference_article => i, :parent => gallery) | |
| 102 | + | |
| 103 | + assert_includes gallery.images(true), pi | |
| 104 | + end | |
| 105 | + | |
| 106 | + should 'not let pass javascript in the body' do | |
| 107 | + gallery = Gallery.new | |
| 108 | + gallery.body = "<script> alert(Xss!); </script>" | |
| 109 | + gallery.valid? | |
| 110 | + | |
| 111 | + assert_no_match /(<script>)/, gallery.body | |
| 112 | + end | |
| 113 | + | |
| 114 | + should 'filter fields with white_list filter' do | |
| 115 | + gallery = Gallery.new | |
| 116 | + gallery.body = "<h1> Body </h1>" | |
| 117 | + gallery.valid? | |
| 118 | + | |
| 119 | + assert_equal "<h1> Body </h1>", gallery.body | |
| 120 | + end | |
| 121 | + | |
| 122 | + should 'not sanitize html comments' do | |
| 123 | + gallery = Gallery.new | |
| 124 | + gallery.body = '<p><!-- <asdf> << aasdfa >>> --> <h1> Wellformed html code </h1>' | |
| 125 | + gallery.valid? | |
| 126 | + | |
| 127 | + assert_match /<!-- .* --> <h1> Wellformed html code <\/h1>/, gallery.body | |
| 128 | + end | |
| 129 | + | |
| 130 | + should 'escape malformed html tags' do | |
| 131 | + gallery = Gallery.new | |
| 132 | + gallery.body = "<h1<< Description >>/h1>" | |
| 133 | + gallery.valid? | |
| 134 | + | |
| 135 | + assert_no_match /[<>]/, gallery.body | |
| 136 | + end | |
| 137 | + | |
| 138 | +end | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -1767,8 +1767,8 @@ class ProfileTest < Test::Unit::TestCase |
| 1767 | 1767 | |
| 1768 | 1768 | should 'provide list of galleries' do |
| 1769 | 1769 | p = fast_create(Profile) |
| 1770 | - f1 = Folder.create(:profile => p, :name => "folder1", :view_as => 'image_gallery') | |
| 1771 | - f2 = Folder.create(:profile => p, :name => "folder2", :view_as => 'folder') | |
| 1770 | + f1 = Gallery.create(:profile => p, :name => "folder1") | |
| 1771 | + f2 = Folder.create(:profile => p, :name => "folder2") | |
| 1772 | 1772 | |
| 1773 | 1773 | assert_equal [f1], p.image_galleries |
| 1774 | 1774 | end |
| ... | ... | @@ -1788,6 +1788,30 @@ class ProfileTest < Test::Unit::TestCase |
| 1788 | 1788 | assert_nil Scrap.find_by_id(scrap.id) |
| 1789 | 1789 | end |
| 1790 | 1790 | |
| 1791 | + should 'have forum' do | |
| 1792 | + p = fast_create(Profile) | |
| 1793 | + p.articles << Forum.new(:profile => p, :name => 'forum_feed_test') | |
| 1794 | + assert p.has_forum? | |
| 1795 | + end | |
| 1796 | + | |
| 1797 | + should 'not have forum' do | |
| 1798 | + p = fast_create(Profile) | |
| 1799 | + assert !p.has_forum? | |
| 1800 | + end | |
| 1801 | + | |
| 1802 | + should 'get nil when no forum' do | |
| 1803 | + p = fast_create(Profile) | |
| 1804 | + assert_nil p.forum | |
| 1805 | + end | |
| 1806 | + | |
| 1807 | + should 'get first forum when has multiple forums' do | |
| 1808 | + p = fast_create(Profile) | |
| 1809 | + p.forums << Forum.new(:profile => p, :name => 'Forum one') | |
| 1810 | + p.forums << Forum.new(:profile => p, :name => 'Forum two') | |
| 1811 | + p.forums << Forum.new(:profile => p, :name => 'Forum three') | |
| 1812 | + assert_equal 'Forum one', p.forum.name | |
| 1813 | + assert_equal 3, p.forums.count | |
| 1814 | + end | |
| 1791 | 1815 | |
| 1792 | 1816 | private |
| 1793 | 1817 | ... | ... |
test/unit/slideshow_block_test.rb
| ... | ... | @@ -8,9 +8,7 @@ class SlideshowBlockTest < ActiveSupport::TestCase |
| 8 | 8 | attr_reader :profile |
| 9 | 9 | |
| 10 | 10 | should 'refer to a gallery' do |
| 11 | - gallery = fast_create(Folder, :profile_id => profile.id) | |
| 12 | - gallery.view_as = 'image_gallery' | |
| 13 | - gallery.save! | |
| 11 | + gallery = fast_create(Gallery, :profile_id => profile.id) | |
| 14 | 12 | slideshow_block = SlideshowBlock.create!(:gallery_id => gallery.id) |
| 15 | 13 | assert_equal gallery, slideshow_block.gallery |
| 16 | 14 | end | ... | ... |
test/unit/uploaded_file_test.rb
| ... | ... | @@ -243,8 +243,7 @@ class UploadedFileTest < Test::Unit::TestCase |
| 243 | 243 | end |
| 244 | 244 | |
| 245 | 245 | should 'track action when a published image is uploaded in a gallery' do |
| 246 | - p = fast_create(Folder, :profile_id => @profile.id) | |
| 247 | - p.view_as = 'image_gallery'; p.save! | |
| 246 | + p = fast_create(Gallery, :profile_id => @profile.id) | |
| 248 | 247 | f = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => p, :profile => @profile) |
| 249 | 248 | ta = ActionTracker::Record.last(:conditions => { :verb => "upload_image" }) |
| 250 | 249 | assert_kind_of String, ta.get_thumbnail_path[0] |
| ... | ... | @@ -255,8 +254,7 @@ class UploadedFileTest < Test::Unit::TestCase |
| 255 | 254 | |
| 256 | 255 | should 'not track action when is not image' do |
| 257 | 256 | ActionTracker::Record.delete_all |
| 258 | - p = fast_create(Folder, :profile_id => @profile.id) | |
| 259 | - p.view_as = 'image_gallery'; p.save! | |
| 257 | + p = fast_create(Gallery, :profile_id => @profile.id) | |
| 260 | 258 | f = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :parent => p, :profile => @profile) |
| 261 | 259 | assert_nil ActionTracker::Record.last(:conditions => { :verb => "upload_image" }) |
| 262 | 260 | end |
| ... | ... | @@ -268,8 +266,7 @@ class UploadedFileTest < Test::Unit::TestCase |
| 268 | 266 | |
| 269 | 267 | should 'not track action when is not published' do |
| 270 | 268 | ActionTracker::Record.delete_all |
| 271 | - p = fast_create(Folder, :profile_id => @profile.id) | |
| 272 | - p.view_as = 'image_gallery'; p.save! | |
| 269 | + p = fast_create(Gallery, :profile_id => @profile.id) | |
| 273 | 270 | f = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => p, :profile => @profile, :published => false) |
| 274 | 271 | assert_nil ActionTracker::Record.last(:conditions => { :verb => "upload_image" }) |
| 275 | 272 | end | ... | ... |