From 2da2072eb0931333f22edc4b8783260b34ac23f8 Mon Sep 17 00:00:00 2001 From: Daniela Soares Feitosa Date: Tue, 25 Oct 2011 03:13:13 -0200 Subject: [PATCH] Added Contents on navigation bar --- app/controllers/public/browse_controller.rb | 17 +++++++++++++++++ app/helpers/application_helper.rb | 11 +++++++++++ app/models/article.rb | 31 +++++++++++++++++++++++++++++++ app/views/browse/_article.rhtml | 11 +++++++++++ app/views/browse/_display_results.rhtml | 2 +- app/views/browse/_person.rhtml | 6 +++--- app/views/browse/_profile.rhtml | 2 +- app/views/browse/contents.rhtml | 9 +++++++++ features/browse.feature | 23 +++++++++++++++++++++++ public/designs/themes/base/navigation.rhtml | 3 +++ public/stylesheets/application.css | 13 ++++++++++--- test/functional/browse_controller_test.rb | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/article_test.rb | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 291 insertions(+), 8 deletions(-) create mode 100644 app/views/browse/_article.rhtml create mode 100644 app/views/browse/contents.rhtml diff --git a/app/controllers/public/browse_controller.rb b/app/controllers/public/browse_controller.rb index 17f85a5..f37c68f 100644 --- a/app/controllers/public/browse_controller.rb +++ b/app/controllers/public/browse_controller.rb @@ -6,6 +6,8 @@ class BrowseController < PublicController more_recent more_active more_popular + more_comments + more_views ) def per_page @@ -36,6 +38,18 @@ class BrowseController < PublicController @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) end + def contents + @filter = filter + @title = self.filter_description(params[:action] + '_' + @filter ) + + @results = @environment.articles.published.text_articles.send(@filter) + + if !params[:query].blank? + @results = @results.find_by_contents(params[:query]) + end + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) + end + protected def filter @@ -54,6 +68,9 @@ class BrowseController < PublicController 'communities_more_recent' => _('More recent communities'), 'communities_more_active' => _('More active communities'), 'communities_more_popular' => _('More popular communities'), + 'contents_more_recent' => _('More recent contents'), + 'contents_more_views' => _('Most viewed contents'), + 'contents_more_comments' => _('Most commented contents'), }[str] || str end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 62685ec..3dbf313 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1134,6 +1134,17 @@ module ApplicationHelper link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') end + def browse_contents_menu + links = [ + {s_('contents|More Comments') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_comments'})}}, + {s_('contents|More Views') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_views'})}}, + {s_('contents|More Recent') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_recent'})}} + ] + + link_to(content_tag(:span, _('Contents'), :class => 'icon-blog'), {:controller => "browse", :action => 'contents'}, :id => 'submenu-contents') + + link_to(content_tag(:span, _('Contents Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger') + end + def pagination_links(collection, options={}) options = {:prev_label => '« ' + _('Previous'), :next_label => _('Next') + ' »'}.merge(options) will_paginate(collection, options) diff --git a/app/models/article.rb b/app/models/article.rb index b8f136a..f5956a2 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -355,11 +355,20 @@ class Article < ActiveRecord::Base ['Folder', 'Blog', 'Forum', 'Gallery'] end + def self.text_article_types + ['TextArticle', 'TextileArticle', 'TinyMceArticle'] + end + named_scope :published, :conditions => { :published => true } named_scope :folders, :conditions => { :type => folder_types} named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types] named_scope :galleries, :conditions => { :type => 'Gallery' } named_scope :images, :conditions => { :is_image => true } + named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] + + named_scope :more_comments, :order => "comments_count DESC" + named_scope :more_views, :order => "hits DESC" + named_scope :more_recent, :order => "created_at DESC" def self.display_filter(user, profile) return {:conditions => ['published = ?', true]} if !user @@ -528,6 +537,28 @@ class Article < ActiveRecord::Base end end + def more_comments_label + amount = self.comments_count + { + 0 => _('no comments'), + 1 => _('one comment') + }[amount] || _("%s comments") % amount + + end + + def more_views_label + amount = self.hits + { + 0 => _('no views'), + 1 => _('one view') + }[amount] || _("%s views") % amount + + end + + def more_recent_label + _('Created at: ') + end + private def sanitize_tag_list diff --git a/app/views/browse/_article.rhtml b/app/views/browse/_article.rhtml new file mode 100644 index 0000000..e36e667 --- /dev/null +++ b/app/views/browse/_article.rhtml @@ -0,0 +1,11 @@ +
  • + <%= link_to(result.title, result.view_url) %> +
    + + <%= _('by %s') % link_to(result.author.name, result.author.url) %> + + + <%= (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %> + +
    +
  • diff --git a/app/views/browse/_display_results.rhtml b/app/views/browse/_display_results.rhtml index 8185bb6..cee76a0 100644 --- a/app/views/browse/_display_results.rhtml +++ b/app/views/browse/_display_results.rhtml @@ -8,7 +8,7 @@ <% end %>
    diff --git a/app/views/browse/_person.rhtml b/app/views/browse/_person.rhtml index 80ad4ae..54001f6 100644 --- a/app/views/browse/_person.rhtml +++ b/app/views/browse/_person.rhtml @@ -1,3 +1,3 @@ -<%= profile_image_link profile, :portrait, 'li', - "#{profile.city}" + - (@filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label')) %> +<%= profile_image_link result, :portrait, 'li', + "#{result.city}" + + (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %> diff --git a/app/views/browse/_profile.rhtml b/app/views/browse/_profile.rhtml index 10da93c..755ccb2 100644 --- a/app/views/browse/_profile.rhtml +++ b/app/views/browse/_profile.rhtml @@ -1 +1 @@ -<%= profile_image_link profile, :portrait, 'li', @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %> +<%= profile_image_link result, :portrait, 'li', @filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label') %> diff --git a/app/views/browse/contents.rhtml b/app/views/browse/contents.rhtml new file mode 100644 index 0000000..8cc3a88 --- /dev/null +++ b/app/views/browse/contents.rhtml @@ -0,0 +1,9 @@ +<%= search_page_title( @title, { :query => @query} ) %> + +<%= render :partial => 'search_form', :locals => {:action => 'contents'} %> + +<%= render :partial => 'display_results' %> + +<%= pagination_links @results %> + +
    diff --git a/features/browse.feature b/features/browse.feature index 10bb97c..2ed717f 100644 --- a/features/browse.feature +++ b/features/browse.feature @@ -84,3 +84,26 @@ Feature: browse And I should not see "Pedro Silva" And I should not see "Paulo Neto" And I should not see "Community Silva" + + @selenium + Scenario: Show contents browse menu + Given I should not see "More Comments" + And I should not see "More Views" + And I should not see "More Recent" + When I click "#submenu-contents-trigger" + Then I should see "More Comments" + And I should see "More Views" + And I should see "More Recent" + + Scenario: Browse contents by query + Given the following articles + | owner | name | body | + | joaosilva | Bees can fly | this is an article | + | joaosilva | Bees and ants are insects | this is another article | + | joaosilva | Ants are small | this is another article | + When I go to /browse/contents + And I fill in "bees" for "query" + And I press "Search" + Then I should see "Bees can fly" + And I should see "Bees and ants are insects" + And I should not see "Ants are small" diff --git a/public/designs/themes/base/navigation.rhtml b/public/designs/themes/base/navigation.rhtml index 1dd46c6..b1e2fe2 100644 --- a/public/designs/themes/base/navigation.rhtml +++ b/public/designs/themes/base/navigation.rhtml @@ -3,5 +3,8 @@
  • <%= browse_communities_menu %> +
  • +
  • + <%= browse_contents_menu %>
  • <%= _('Events') %>
  • diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index a1957e3..3df35ee 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -4503,23 +4503,30 @@ h1#agenda-title { } .controller-search #content .search-results-type-article li, -.controller-search #content .search-results-type-event li { +.controller-search #content .search-results-type-event li, +.controller-browse #content li.browse-results-type-content { padding: 0px 0px 4px 20px; background-repeat: no-repeat; border-color: transparent; } .controller-search #content .search-results-type-article li:hover, -.controller-search #content .search-results-type-event li:hover { +.controller-search #content .search-results-type-event li:hover, +.controller-browse #content li.browse-results-type-content:hover { background-color: transparent; } .controller-search .search-results-type-article .item_meta, -.controller-search .search-results-type-event .item_meta { +.controller-search .search-results-type-event .item_meta, +.controller-browse .browse-results-type-content .item_meta { font-size: 10px; color: #888; } +.controller-browse .browse-results-type-content .item_meta span { + width: auto; +} + .search-results-type-article.search-results-innerbox { overflow: auto; } diff --git a/test/functional/browse_controller_test.rb b/test/functional/browse_controller_test.rb index c66e802..56f11ff 100644 --- a/test/functional/browse_controller_test.rb +++ b/test/functional/browse_controller_test.rb @@ -19,7 +19,10 @@ class BrowseControllerTest < Test::Unit::TestCase user.stubs(:email).returns('some@test.com') user.stubs(:save!).returns(true) Person.any_instance.stubs(:user).returns(user) + @profile = create_user('testinguser').person + Article.destroy_all end + attr_reader :profile should 'search for people' do Person.delete_all @@ -274,4 +277,98 @@ class BrowseControllerTest < Test::Unit::TestCase assert_not_includes assigns(:results), p1 end + should 'search for contents' do + small = create(TinyMceArticle, :name => 'Testing article', :body => 'A small article for testing', :profile => profile) + create(TinyMceArticle, :name => 'Testing article 2', :body => 'A big article for testing', :profile => profile) + + get :contents, :query => 'small' + assert_equal [small], assigns(:results) + end + + should 'list all contents ordered by more recent by default' do + c1 = create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile => profile, :created_at => DateTime.now - 2) + c2 = create(TinyMceArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile => profile, :created_at => DateTime.now - 1) + c3 = create(TinyMceArticle, :name => 'Testing article 3', :body => 'Article body 3', :profile => profile) + + get :contents + assert_equal [c3,c2,c1], assigns(:results) + end + + should 'paginate search of contents in groups of 27' do + 1.upto(30).map do |n| + create(TinyMceArticle, :name => "Testing article #{n}", :body => "Article body #{n}", :profile => profile) + end + + get :contents + assert_equal 27 , assigns(:results).count + assert_tag :a, '', :attributes => {:class => 'next_page'} + end + + should 'paginate ferret search of contents in groups of 27' do + 1.upto(30).map do |n| + create(TinyMceArticle, :name => "Testing article #{n}", :body => "Article body #{n}", :profile => profile) + end + + get :contents, :query => 'Testing' + assert_equal 27 , assigns(:results).count + assert_tag :a, '', :attributes => {:class => 'next_page'} + end + + should 'list all contents filter by more comments' do + article1 = fast_create(TinyMceArticle, :body => '

    Article to test browse contents', :profile_id => profile.id, :comments_count => 5) + article2 = fast_create(TinyMceArticle, :body => '

    Another article to test browse contents

    ', :profile_id => profile.id, :comments_count => 10) + article3 = fast_create(TinyMceArticle, :body => '

    Another article to test browse contents

    ', :profile_id => profile.id, :comments_count => 1) + + get :contents, :filter => 'more_comments' + assert_equal [article2,article1,article3] , assigns(:results) + end + + should 'list all contents filter by more views' do + article1 = fast_create(TinyMceArticle, :body => '

    Article to test browse contents', :profile_id => profile.id, :hits => 5) + article2 = fast_create(TinyMceArticle, :body => '

    Another article to test browse contents

    ', :profile_id => profile.id, :hits => 10) + article3 = fast_create(TinyMceArticle, :body => '

    Another article to test browse contents

    ', :profile_id => profile.id, :hits => 1) + + get :contents, :filter => 'more_views' + assert_equal [article2,article1,article3], assigns(:results) + end + + should 'have the more_recent filter by default' do + get :contents, :filter => 'more_recent' + assert_equal 'more_recent' , assigns(:filter) + + get :contents, :filter => 'more_comments' + assert_equal 'more_comments' , assigns(:filter) + + get :contents, :filter => 'more_views' + assert_equal 'more_views' , assigns(:filter) + + get :contents, :filter => 'more_anything' + assert_equal 'more_recent' , assigns(:filter) + end + + should 'the contents filter define the title' do + get :contents, :filter => 'more_recent' + assert_equal 'More recent contents' , assigns(:title) + assert_tag :h1, :content => 'More recent contents' + + get :contents, :filter => 'more_views' + assert_equal 'Most viewed contents' , assigns(:title) + assert_tag :h1, :content => 'Most viewed contents' + + get :contents, :filter => 'more_comments' + assert_equal 'Most commented contents' , assigns(:title) + assert_tag :h1, :content => 'Most commented contents' + + get :contents, :filter => 'more_anything' + assert_equal 'More recent contents' , assigns(:title) + assert_tag :h1, :content => 'More recent contents' + end + + should "only include published contents in more_recent filter" do + # assuming that all filters behave the same! + article = fast_create(TinyMceArticle, :body => '

    Article to test browse contents', :profile_id => profile.id, :published => false) + get :contents, :filter => 'more_recent' + assert_not_includes assigns(:results), article + end + end diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index a4cbf20..7ff89dd 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -1562,4 +1562,78 @@ class ArticleTest < Test::Unit::TestCase end end + should 'find more recent contents' do + Article.delete_all + + c1 = fast_create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile_id => profile.id, :created_at => DateTime.now - 4) + c2 = fast_create(TinyMceArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile_id => profile.id, :created_at => DateTime.now - 1) + c3 = fast_create(TinyMceArticle, :name => 'Testing article 3', :body => 'Article body 3', :profile_id => profile.id, :created_at => DateTime.now - 3) + + assert_equal [c2,c3,c1] , Article.more_recent + + c4 = fast_create(TinyMceArticle, :name => 'Testing article 4', :body => 'Article body 4', :profile_id => profile.id, :created_at => DateTime.now - 2) + assert_equal [c2,c4,c3,c1] , Article.more_recent + end + + should 'respond to more comments' do + assert_respond_to Article, :more_comments + end + + should 'respond to more views' do + assert_respond_to Article, :more_views + end + + should "return the more recent label" do + a = Article.new + assert_equal "Created at: ", a.more_recent_label + end + + should "return no comments if profile has 0 comments" do + a = Article.new + assert_equal 0, a.comments_count + assert_equal "no comments", a.more_comments_label + end + + should "return 1 comment on label if the content has 1 comment" do + a = Article.new(:comments_count => 1) + assert_equal 1, a.comments_count + assert_equal "one comment", a.more_comments_label + end + + should "return number of comments on label if the content has more than one comment" do + a = Article.new(:comments_count => 4) + assert_equal 4, a.comments_count + assert_equal "4 comments", a.more_comments_label + end + + should "return no views if profile has 0 views" do + a = Article.new + assert_equal 0, a.hits + assert_equal "no views", a.more_views_label + end + + should "return 1 view on label if the content has 1 view" do + a = Article.new(:hits => 1) + assert_equal 1, a.hits + assert_equal "one view", a.more_views_label + end + + should "return number of views on label if the content has more than one view" do + a = Article.new(:hits => 4) + assert_equal 4, a.hits + assert_equal "4 views", a.more_views_label + end + + should 'return only text articles' do + Article.delete_all + + c1 = fast_create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile_id => profile.id) + c2 = fast_create(TextArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile_id => profile.id) + c3 = fast_create(Event, :name => 'Testing article 3', :body => 'Article body 3', :profile_id => profile.id) + c4 = fast_create(RssFeed, :name => 'Testing article 4', :body => 'Article body 4', :profile_id => profile.id) + c5 = fast_create(TextileArticle, :name => 'Testing article 5', :body => 'Article body 5', :profile_id => profile.id) + + assert_equal [c1,c2,c5], Article.text_articles + end + end -- libgit2 0.21.2