Commit 2da2072eb0931333f22edc4b8783260b34ac23f8

Authored by Daniela Feitosa
1 parent fc7e02f2

Added Contents on navigation bar

Included new named_scopes for browsing contents:
* more_recent
* more_comments
* more_views
A named_scope to filter only text articles
* text_articles
Included new browse_contents_menu on base theme

(ActionItem2069)
app/controllers/public/browse_controller.rb
... ... @@ -6,6 +6,8 @@ class BrowseController < PublicController
6 6 more_recent
7 7 more_active
8 8 more_popular
  9 + more_comments
  10 + more_views
9 11 )
10 12  
11 13 def per_page
... ... @@ -36,6 +38,18 @@ class BrowseController < PublicController
36 38 @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
37 39 end
38 40  
  41 + def contents
  42 + @filter = filter
  43 + @title = self.filter_description(params[:action] + '_' + @filter )
  44 +
  45 + @results = @environment.articles.published.text_articles.send(@filter)
  46 +
  47 + if !params[:query].blank?
  48 + @results = @results.find_by_contents(params[:query])
  49 + end
  50 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
  51 + end
  52 +
39 53 protected
40 54  
41 55 def filter
... ... @@ -54,6 +68,9 @@ class BrowseController < PublicController
54 68 'communities_more_recent' => _('More recent communities'),
55 69 'communities_more_active' => _('More active communities'),
56 70 'communities_more_popular' => _('More popular communities'),
  71 + 'contents_more_recent' => _('More recent contents'),
  72 + 'contents_more_views' => _('Most viewed contents'),
  73 + 'contents_more_comments' => _('Most commented contents'),
57 74 }[str] || str
58 75 end
59 76  
... ...
app/helpers/application_helper.rb
... ... @@ -1134,6 +1134,17 @@ module ApplicationHelper
1134 1134 link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger')
1135 1135 end
1136 1136  
  1137 + def browse_contents_menu
  1138 + links = [
  1139 + {s_('contents|More Comments') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_comments'})}},
  1140 + {s_('contents|More Views') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_views'})}},
  1141 + {s_('contents|More Recent') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_recent'})}}
  1142 + ]
  1143 +
  1144 + link_to(content_tag(:span, _('Contents'), :class => 'icon-blog'), {:controller => "browse", :action => 'contents'}, :id => 'submenu-contents') +
  1145 + link_to(content_tag(:span, _('Contents Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger')
  1146 + end
  1147 +
1137 1148 def pagination_links(collection, options={})
1138 1149 options = {:prev_label => '« ' + _('Previous'), :next_label => _('Next') + ' »'}.merge(options)
1139 1150 will_paginate(collection, options)
... ...
app/models/article.rb
... ... @@ -355,11 +355,20 @@ class Article < ActiveRecord::Base
355 355 ['Folder', 'Blog', 'Forum', 'Gallery']
356 356 end
357 357  
  358 + def self.text_article_types
  359 + ['TextArticle', 'TextileArticle', 'TinyMceArticle']
  360 + end
  361 +
358 362 named_scope :published, :conditions => { :published => true }
359 363 named_scope :folders, :conditions => { :type => folder_types}
360 364 named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types]
361 365 named_scope :galleries, :conditions => { :type => 'Gallery' }
362 366 named_scope :images, :conditions => { :is_image => true }
  367 + named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
  368 +
  369 + named_scope :more_comments, :order => "comments_count DESC"
  370 + named_scope :more_views, :order => "hits DESC"
  371 + named_scope :more_recent, :order => "created_at DESC"
363 372  
364 373 def self.display_filter(user, profile)
365 374 return {:conditions => ['published = ?', true]} if !user
... ... @@ -528,6 +537,28 @@ class Article < ActiveRecord::Base
528 537 end
529 538 end
530 539  
  540 + def more_comments_label
  541 + amount = self.comments_count
  542 + {
  543 + 0 => _('no comments'),
  544 + 1 => _('one comment')
  545 + }[amount] || _("%s comments") % amount
  546 +
  547 + end
  548 +
  549 + def more_views_label
  550 + amount = self.hits
  551 + {
  552 + 0 => _('no views'),
  553 + 1 => _('one view')
  554 + }[amount] || _("%s views") % amount
  555 +
  556 + end
  557 +
  558 + def more_recent_label
  559 + _('Created at: ')
  560 + end
  561 +
531 562 private
532 563  
533 564 def sanitize_tag_list
... ...
app/views/browse/_article.rhtml 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<li class="<%= 'browse-results-type-content ' + icon_for_article(result) %>">
  2 + <strong><%= link_to(result.title, result.view_url) %></strong>
  3 + <div class="item_meta">
  4 + <span class="item_by">
  5 + <%= _('by %s') % link_to(result.author.name, result.author.url) %>
  6 + </span>
  7 + <span class="extra-info">
  8 + <%= (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %>
  9 + </span>
  10 + </div>
  11 +</li>
... ...
app/views/browse/_display_results.rhtml
... ... @@ -8,7 +8,7 @@
8 8 <% end %>
9 9 <ul class='common-profile-list-block'>
10 10 <% @results.each do |result| %>
11   - <%= render :partial => partial_for_class(result.class), :locals => {:profile => result} %>
  11 + <%= render :partial => partial_for_class(result.class), :locals => {:result => result} %>
12 12 <% end %>
13 13 </ul>
14 14 <br style='clear: both;'>
... ...
app/views/browse/_person.rhtml
1   -<%= profile_image_link profile, :portrait, 'li',
2   - "<span class='adr'>#{profile.city}</span>" +
3   - (@filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label')) %>
  1 +<%= profile_image_link result, :portrait, 'li',
  2 + "<span class='adr'>#{result.city}</span>" +
  3 + (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %>
... ...
app/views/browse/_profile.rhtml
1   -<%= profile_image_link profile, :portrait, 'li', @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %>
  1 +<%= profile_image_link result, :portrait, 'li', @filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label') %>
... ...
app/views/browse/contents.rhtml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +<%= search_page_title( @title, { :query => @query} ) %>
  2 +
  3 +<%= render :partial => 'search_form', :locals => {:action => 'contents'} %>
  4 +
  5 +<%= render :partial => 'display_results' %>
  6 +
  7 +<%= pagination_links @results %>
  8 +
  9 +<br style="clear:both" />
... ...
features/browse.feature
... ... @@ -84,3 +84,26 @@ Feature: browse
84 84 And I should not see "Pedro Silva"
85 85 And I should not see "Paulo Neto"
86 86 And I should not see "Community Silva"
  87 +
  88 + @selenium
  89 + Scenario: Show contents browse menu
  90 + Given I should not see "More Comments"
  91 + And I should not see "More Views"
  92 + And I should not see "More Recent"
  93 + When I click "#submenu-contents-trigger"
  94 + Then I should see "More Comments"
  95 + And I should see "More Views"
  96 + And I should see "More Recent"
  97 +
  98 + Scenario: Browse contents by query
  99 + Given the following articles
  100 + | owner | name | body |
  101 + | joaosilva | Bees can fly | this is an article |
  102 + | joaosilva | Bees and ants are insects | this is another article |
  103 + | joaosilva | Ants are small | this is another article |
  104 + When I go to /browse/contents
  105 + And I fill in "bees" for "query"
  106 + And I press "Search"
  107 + Then I should see "Bees can fly"
  108 + And I should see "Bees and ants are insects"
  109 + And I should not see "Ants are small"
... ...
public/designs/themes/base/navigation.rhtml
... ... @@ -3,5 +3,8 @@
3 3 </li>
4 4 <li>
5 5 <%= browse_communities_menu %>
  6 + </li>
  7 +<li>
  8 + <%= browse_contents_menu %>
6 9 </li>
7 10 <li><a href="/assets/events"><span class='icon-menu-events'><%= _('Events') %></span></a></li>
... ...
public/stylesheets/application.css
... ... @@ -4503,23 +4503,30 @@ h1#agenda-title {
4503 4503 }
4504 4504  
4505 4505 .controller-search #content .search-results-type-article li,
4506   -.controller-search #content .search-results-type-event li {
  4506 +.controller-search #content .search-results-type-event li,
  4507 +.controller-browse #content li.browse-results-type-content {
4507 4508 padding: 0px 0px 4px 20px;
4508 4509 background-repeat: no-repeat;
4509 4510 border-color: transparent;
4510 4511 }
4511 4512  
4512 4513 .controller-search #content .search-results-type-article li:hover,
4513   -.controller-search #content .search-results-type-event li:hover {
  4514 +.controller-search #content .search-results-type-event li:hover,
  4515 +.controller-browse #content li.browse-results-type-content:hover {
4514 4516 background-color: transparent;
4515 4517 }
4516 4518  
4517 4519 .controller-search .search-results-type-article .item_meta,
4518   -.controller-search .search-results-type-event .item_meta {
  4520 +.controller-search .search-results-type-event .item_meta,
  4521 +.controller-browse .browse-results-type-content .item_meta {
4519 4522 font-size: 10px;
4520 4523 color: #888;
4521 4524 }
4522 4525  
  4526 +.controller-browse .browse-results-type-content .item_meta span {
  4527 + width: auto;
  4528 +}
  4529 +
4523 4530 .search-results-type-article.search-results-innerbox {
4524 4531 overflow: auto;
4525 4532 }
... ...
test/functional/browse_controller_test.rb
... ... @@ -19,7 +19,10 @@ class BrowseControllerTest &lt; Test::Unit::TestCase
19 19 user.stubs(:email).returns('some@test.com')
20 20 user.stubs(:save!).returns(true)
21 21 Person.any_instance.stubs(:user).returns(user)
  22 + @profile = create_user('testinguser').person
  23 + Article.destroy_all
22 24 end
  25 + attr_reader :profile
23 26  
24 27 should 'search for people' do
25 28 Person.delete_all
... ... @@ -274,4 +277,98 @@ class BrowseControllerTest &lt; Test::Unit::TestCase
274 277 assert_not_includes assigns(:results), p1
275 278 end
276 279  
  280 + should 'search for contents' do
  281 + small = create(TinyMceArticle, :name => 'Testing article', :body => 'A small article for testing', :profile => profile)
  282 + create(TinyMceArticle, :name => 'Testing article 2', :body => 'A big article for testing', :profile => profile)
  283 +
  284 + get :contents, :query => 'small'
  285 + assert_equal [small], assigns(:results)
  286 + end
  287 +
  288 + should 'list all contents ordered by more recent by default' do
  289 + c1 = create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile => profile, :created_at => DateTime.now - 2)
  290 + c2 = create(TinyMceArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile => profile, :created_at => DateTime.now - 1)
  291 + c3 = create(TinyMceArticle, :name => 'Testing article 3', :body => 'Article body 3', :profile => profile)
  292 +
  293 + get :contents
  294 + assert_equal [c3,c2,c1], assigns(:results)
  295 + end
  296 +
  297 + should 'paginate search of contents in groups of 27' do
  298 + 1.upto(30).map do |n|
  299 + create(TinyMceArticle, :name => "Testing article #{n}", :body => "Article body #{n}", :profile => profile)
  300 + end
  301 +
  302 + get :contents
  303 + assert_equal 27 , assigns(:results).count
  304 + assert_tag :a, '', :attributes => {:class => 'next_page'}
  305 + end
  306 +
  307 + should 'paginate ferret search of contents in groups of 27' do
  308 + 1.upto(30).map do |n|
  309 + create(TinyMceArticle, :name => "Testing article #{n}", :body => "Article body #{n}", :profile => profile)
  310 + end
  311 +
  312 + get :contents, :query => 'Testing'
  313 + assert_equal 27 , assigns(:results).count
  314 + assert_tag :a, '', :attributes => {:class => 'next_page'}
  315 + end
  316 +
  317 + should 'list all contents filter by more comments' do
  318 + article1 = fast_create(TinyMceArticle, :body => '<p>Article to test browse contents', :profile_id => profile.id, :comments_count => 5)
  319 + article2 = fast_create(TinyMceArticle, :body => '<p>Another article to test browse contents</p>', :profile_id => profile.id, :comments_count => 10)
  320 + article3 = fast_create(TinyMceArticle, :body => '<p>Another article to test browse contents</p>', :profile_id => profile.id, :comments_count => 1)
  321 +
  322 + get :contents, :filter => 'more_comments'
  323 + assert_equal [article2,article1,article3] , assigns(:results)
  324 + end
  325 +
  326 + should 'list all contents filter by more views' do
  327 + article1 = fast_create(TinyMceArticle, :body => '<p>Article to test browse contents', :profile_id => profile.id, :hits => 5)
  328 + article2 = fast_create(TinyMceArticle, :body => '<p>Another article to test browse contents</p>', :profile_id => profile.id, :hits => 10)
  329 + article3 = fast_create(TinyMceArticle, :body => '<p>Another article to test browse contents</p>', :profile_id => profile.id, :hits => 1)
  330 +
  331 + get :contents, :filter => 'more_views'
  332 + assert_equal [article2,article1,article3], assigns(:results)
  333 + end
  334 +
  335 + should 'have the more_recent filter by default' do
  336 + get :contents, :filter => 'more_recent'
  337 + assert_equal 'more_recent' , assigns(:filter)
  338 +
  339 + get :contents, :filter => 'more_comments'
  340 + assert_equal 'more_comments' , assigns(:filter)
  341 +
  342 + get :contents, :filter => 'more_views'
  343 + assert_equal 'more_views' , assigns(:filter)
  344 +
  345 + get :contents, :filter => 'more_anything'
  346 + assert_equal 'more_recent' , assigns(:filter)
  347 + end
  348 +
  349 + should 'the contents filter define the title' do
  350 + get :contents, :filter => 'more_recent'
  351 + assert_equal 'More recent contents' , assigns(:title)
  352 + assert_tag :h1, :content => 'More recent contents'
  353 +
  354 + get :contents, :filter => 'more_views'
  355 + assert_equal 'Most viewed contents' , assigns(:title)
  356 + assert_tag :h1, :content => 'Most viewed contents'
  357 +
  358 + get :contents, :filter => 'more_comments'
  359 + assert_equal 'Most commented contents' , assigns(:title)
  360 + assert_tag :h1, :content => 'Most commented contents'
  361 +
  362 + get :contents, :filter => 'more_anything'
  363 + assert_equal 'More recent contents' , assigns(:title)
  364 + assert_tag :h1, :content => 'More recent contents'
  365 + end
  366 +
  367 + should "only include published contents in more_recent filter" do
  368 + # assuming that all filters behave the same!
  369 + article = fast_create(TinyMceArticle, :body => '<p>Article to test browse contents', :profile_id => profile.id, :published => false)
  370 + get :contents, :filter => 'more_recent'
  371 + assert_not_includes assigns(:results), article
  372 + end
  373 +
277 374 end
... ...
test/unit/article_test.rb
... ... @@ -1562,4 +1562,78 @@ class ArticleTest &lt; Test::Unit::TestCase
1562 1562 end
1563 1563 end
1564 1564  
  1565 + should 'find more recent contents' do
  1566 + Article.delete_all
  1567 +
  1568 + c1 = fast_create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile_id => profile.id, :created_at => DateTime.now - 4)
  1569 + c2 = fast_create(TinyMceArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile_id => profile.id, :created_at => DateTime.now - 1)
  1570 + c3 = fast_create(TinyMceArticle, :name => 'Testing article 3', :body => 'Article body 3', :profile_id => profile.id, :created_at => DateTime.now - 3)
  1571 +
  1572 + assert_equal [c2,c3,c1] , Article.more_recent
  1573 +
  1574 + c4 = fast_create(TinyMceArticle, :name => 'Testing article 4', :body => 'Article body 4', :profile_id => profile.id, :created_at => DateTime.now - 2)
  1575 + assert_equal [c2,c4,c3,c1] , Article.more_recent
  1576 + end
  1577 +
  1578 + should 'respond to more comments' do
  1579 + assert_respond_to Article, :more_comments
  1580 + end
  1581 +
  1582 + should 'respond to more views' do
  1583 + assert_respond_to Article, :more_views
  1584 + end
  1585 +
  1586 + should "return the more recent label" do
  1587 + a = Article.new
  1588 + assert_equal "Created at: ", a.more_recent_label
  1589 + end
  1590 +
  1591 + should "return no comments if profile has 0 comments" do
  1592 + a = Article.new
  1593 + assert_equal 0, a.comments_count
  1594 + assert_equal "no comments", a.more_comments_label
  1595 + end
  1596 +
  1597 + should "return 1 comment on label if the content has 1 comment" do
  1598 + a = Article.new(:comments_count => 1)
  1599 + assert_equal 1, a.comments_count
  1600 + assert_equal "one comment", a.more_comments_label
  1601 + end
  1602 +
  1603 + should "return number of comments on label if the content has more than one comment" do
  1604 + a = Article.new(:comments_count => 4)
  1605 + assert_equal 4, a.comments_count
  1606 + assert_equal "4 comments", a.more_comments_label
  1607 + end
  1608 +
  1609 + should "return no views if profile has 0 views" do
  1610 + a = Article.new
  1611 + assert_equal 0, a.hits
  1612 + assert_equal "no views", a.more_views_label
  1613 + end
  1614 +
  1615 + should "return 1 view on label if the content has 1 view" do
  1616 + a = Article.new(:hits => 1)
  1617 + assert_equal 1, a.hits
  1618 + assert_equal "one view", a.more_views_label
  1619 + end
  1620 +
  1621 + should "return number of views on label if the content has more than one view" do
  1622 + a = Article.new(:hits => 4)
  1623 + assert_equal 4, a.hits
  1624 + assert_equal "4 views", a.more_views_label
  1625 + end
  1626 +
  1627 + should 'return only text articles' do
  1628 + Article.delete_all
  1629 +
  1630 + c1 = fast_create(TinyMceArticle, :name => 'Testing article 1', :body => 'Article body 1', :profile_id => profile.id)
  1631 + c2 = fast_create(TextArticle, :name => 'Testing article 2', :body => 'Article body 2', :profile_id => profile.id)
  1632 + c3 = fast_create(Event, :name => 'Testing article 3', :body => 'Article body 3', :profile_id => profile.id)
  1633 + c4 = fast_create(RssFeed, :name => 'Testing article 4', :body => 'Article body 4', :profile_id => profile.id)
  1634 + c5 = fast_create(TextileArticle, :name => 'Testing article 5', :body => 'Article body 5', :profile_id => profile.id)
  1635 +
  1636 + assert_equal [c1,c2,c5], Article.text_articles
  1637 + end
  1638 +
1565 1639 end
... ...