Commit 6d7a082470e0580f338188c325f1fcded5dcd5c3

Authored by Rodrigo Souto
2 parents 32df4672 35d7a6af

Merge remote-tracking branch 'dani/AI2822-fixes' into AI2822-fixes

Conflicts:
	public/stylesheets/application.css
app/controllers/my_profile/cms_controller.rb
... ... @@ -68,6 +68,9 @@ class CmsController < MyProfileController
68 68 def edit
69 69 @success_back_to = params[:success_back_to]
70 70 @article = profile.articles.find(params[:id])
  71 + version = params[:version]
  72 + @article.revert_to(version) if version
  73 +
71 74 @parent_id = params[:parent_id]
72 75 @type = params[:type] || @article.class.to_s
73 76 translations if @article.translatable?
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -7,6 +7,7 @@ class ContentViewerController < ApplicationController
7 7  
8 8 def view_page
9 9 path = params[:page].join('/')
  10 + @version = params[:version].to_i
10 11  
11 12 if path.blank?
12 13 @page = profile.home_page
... ... @@ -25,22 +26,15 @@ class ContentViewerController < ApplicationController
25 26 end
26 27 end
27 28  
28   - if !@page.nil? && !@page.display_to?(user)
29   - if !profile.public?
30   - private_profile_partial_parameters
31   - render :template => 'profile/_private_profile.rhtml', :status => 403
32   - else #if !profile.visible?
33   - message = _('You are not allowed to view this content.')
34   - message += ' ' + _('You can contact the owner of this profile to request access then.')
35   - render_access_denied(message)
36   - end
37   - return
38   - end
  29 + return unless allow_access_to_page(path)
39 30  
40   - # page not found, give error
41   - if @page.nil?
42   - render_not_found(@path)
43   - return
  31 + if @version > 0
  32 + return render_access_denied unless @page.display_versions?
  33 + @versioned_article = @page.versions.find_by_version(@version)
  34 + if @versioned_article && @page.versions.latest.version != @versioned_article.version
  35 + render :template => 'content_viewer/versioned_article.rhtml'
  36 + return
  37 + end
44 38 end
45 39  
46 40 if request.xhr? && params[:toolbar]
... ... @@ -128,6 +122,15 @@ class ContentViewerController < ApplicationController
128 122 end
129 123 end
130 124  
  125 + def article_versions
  126 + path = params[:page].join('/')
  127 + @page = profile.articles.find_by_path(path)
  128 + return unless allow_access_to_page(path)
  129 +
  130 + render_access_denied unless @page.display_versions?
  131 + @versions = @page.versions.paginate(:per_page => per_page, :page => params[:npage])
  132 + end
  133 +
131 134 protected
132 135  
133 136 def per_page
... ... @@ -158,4 +161,22 @@ class ContentViewerController < ApplicationController
158 161 end
159 162 helper_method :pass_without_comment_captcha?
160 163  
  164 + def allow_access_to_page(path)
  165 + allowed = true
  166 + if @page.nil? # page not found, give error
  167 + render_not_found(path)
  168 + allowed = false
  169 + elsif !@page.display_to?(user)
  170 + if !profile.public?
  171 + private_profile_partial_parameters
  172 + render :template => 'profile/_private_profile.rhtml', :status => 403
  173 + allowed = false
  174 + else #if !profile.visible?
  175 + render_access_denied
  176 + allowed = false
  177 + end
  178 + end
  179 + allowed
  180 + end
  181 +
161 182 end
... ...
app/helpers/application_helper.rb
... ... @@ -1404,4 +1404,8 @@ module ApplicationHelper
1404 1404 content.nil? ? '' : content.id.to_s
1405 1405 end
1406 1406  
  1407 + def display_article_versions(article, version = nil)
  1408 + content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))})
  1409 + end
  1410 +
1407 1411 end
... ...
app/helpers/article_helper.rb
... ... @@ -28,7 +28,7 @@ module ArticleHelper
28 28 'div',
29 29 check_box(:article, :notify_comments) +
30 30 content_tag('label', _('I want to receive a notification of each comment written by e-mail'), :for => 'article_notify_comments') +
31   - observe_field(:article_accept_comments, :function => "$('article_notify_comments').disabled = ! $('article_accept_comments').checked;$('article_moderate_comments').disabled = ! $('article_accept_comments').checked")
  31 + observe_field(:article_accept_comments, :function => "$('article_notify_comments').disabled = ! $('article_accept_comments').checked;$('article_moderate_comments').disabled = ! $('article_accept_comments').checked")
32 32 ) +
33 33  
34 34 content_tag(
... ... @@ -42,7 +42,15 @@ module ArticleHelper
42 42 'div',
43 43 check_box(:article, :display_hits) +
44 44 content_tag('label', _('I want this article to display the number of hits it received'), :for => 'article_display_hits')
  45 + ) : '') +
  46 +
  47 + (article.can_display_versions? ?
  48 + content_tag(
  49 + 'div',
  50 + check_box(:article, :display_versions) +
  51 + content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
45 52 ) : '')
  53 +
46 54 )
47 55 end
48 56  
... ...
app/models/article.rb
... ... @@ -201,6 +201,7 @@ class Article < ActiveRecord::Base
201 201 acts_as_filesystem
202 202  
203 203 acts_as_versioned
  204 + self.non_versioned_columns << 'setting'
204 205  
205 206 def comment_data
206 207 comments.map {|item| [item.title, item.body].join(' ') }.join(' ')
... ... @@ -604,17 +605,34 @@ class Article &lt; ActiveRecord::Base
604 605 false
605 606 end
606 607  
607   - def author
608   - if versions.empty?
609   - last_changed_by
610   - else
611   - author_id = versions.first.last_changed_by_id
  608 + settings_items :display_versions, :type => :boolean, :default => false
  609 +
  610 + def can_display_versions?
  611 + false
  612 + end
  613 +
  614 + def display_versions?
  615 + can_display_versions? && display_versions
  616 + end
  617 +
  618 + def author(version_number = nil)
  619 + if version_number
  620 + version = versions.find_by_version(version_number)
  621 + author_id = version.last_changed_by_id if version
612 622 Person.exists?(author_id) ? Person.find(author_id) : nil
  623 + else
  624 + if versions.empty?
  625 + last_changed_by
  626 + else
  627 + author_id = versions.first.last_changed_by_id
  628 + Person.exists?(author_id) ? Person.find(author_id) : nil
  629 + end
613 630 end
614 631 end
615 632  
616   - def author_name
617   - author ? author.name : (setting[:author_name] || _('Unknown'))
  633 + def author_name(version_number = nil)
  634 + person = version_number ? author(version_number) : author
  635 + person ? person.name : (setting[:author_name] || _('Unknown'))
618 636 end
619 637  
620 638 def author_url
... ... @@ -625,13 +643,20 @@ class Article &lt; ActiveRecord::Base
625 643 author ? author.id : nil
626 644 end
627 645  
  646 + def version_license(version_number = nil)
  647 + return license if version_number.nil?
  648 + profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id)
  649 + end
  650 +
628 651 alias :active_record_cache_key :cache_key
629 652 def cache_key(params = {}, the_profile = nil, language = 'en')
630 653 active_record_cache_key+'-'+language +
631 654 (allow_post_content?(the_profile) ? "-owner" : '') +
632 655 (params[:npage] ? "-npage-#{params[:npage]}" : '') +
633 656 (params[:year] ? "-year-#{params[:year]}" : '') +
634   - (params[:month] ? "-month-#{params[:month]}" : '')
  657 + (params[:month] ? "-month-#{params[:month]}" : '') +
  658 + (params[:version] ? "-version-#{params[:version]}" : '')
  659 +
635 660 end
636 661  
637 662 def first_paragraph
... ...
app/models/text_article.rb
... ... @@ -17,4 +17,7 @@ class TextArticle &lt; Article
17 17 end
18 18 end
19 19  
  20 + def can_display_versions?
  21 + true
  22 + end
20 23 end
... ...
app/views/content_viewer/_article_toolbar.rhtml
... ... @@ -48,6 +48,10 @@
48 48 <%= expirable_button @page, :suggest, content, url, options %>
49 49 <% end %>
50 50  
  51 + <% if @page.display_versions? %>
  52 + <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %>
  53 + <% end %>
  54 +
51 55 <%= report_abuse(profile, :link, @page) %>
52 56  
53 57 </div>
... ...
app/views/content_viewer/article_versions.rhtml 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<%= article_title(@page, :no_link => true) %>
  2 +
  3 +<p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p>
  4 +
  5 +<ul class='article-versions'>
  6 + <% @versions.each do |v| %>
  7 + <li>
  8 + <%= link_to(_("Version #{v.version}"), @page.url.merge(:version => v.version)) %>
  9 + <%= @page.version == v.version ? _('(current)') : '' %>
  10 + <span class='updated-by'><%= _('by %{author}') % {:author => link_to(@page.author_name(v.version), @page.author_url)} %></span>
  11 + <div class='updated-on'><%= show_time(v.updated_at) %></div>
  12 + </li>
  13 + <% end %>
  14 +</ul>
  15 +
  16 +<%= pagination_links @versions, :param_name => 'npage' %>
... ...
app/views/content_viewer/versioned_article.rhtml 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +<div id="article" class="<%= @page.css_class_name %>">
  2 +
  3 + <div id="article-actions">
  4 + <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %>
  5 +
  6 + <% if @page.allow_edit?(user) && !remove_content_button(:edit) %>
  7 + <% content = content_tag('span', _('Revert to this version')) %>
  8 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id, :version => @version }) %>
  9 + <%= expirable_button @page, :edit, content, url, :id => 'article-revert-version-link' %>
  10 + <% end %>
  11 + </div>
  12 +
  13 + <div id="article-header">
  14 + <h1 class='title'><%= @versioned_article.name %></h1>
  15 + <%= _("Version %{version} - %{author} on %{date}") % {:version => @version, :author => @page.author_name(@version), :date => show_time(@versioned_article.updated_at) } %>
  16 + </div>
  17 +
  18 + <% if @page.version_license(@version).present? %>
  19 + <div id='article-sub-header'>
  20 + <% if @page.version_license(@version).present? %>
  21 + <div id="article-license">
  22 + <%= _('Licensed under %s') % (@page.version_license(@version).url.present? ? link_to(@page.version_license(@version).name, @page.version_license(@version).url, :target => '_blank') : @page.version_license(@version).name) %>
  23 + </div>
  24 + <% end %>
  25 + </div>
  26 + <% end %>
  27 +
  28 + <% cache(@page.cache_key(params, user, language)) do %>
  29 + <div class="<%="article-body article-body-" + @page.css_class_name %>">
  30 + <%= @versioned_article.body %>
  31 + <br style="clear:both" />
  32 + </div> <!-- end class="article-body" -->
  33 + <% end %>
  34 +
  35 + <%= display_source_info(@page) %>
  36 +
  37 +</div><!-- end id="article" -->
  38 +<%= add_zoom_to_article_images %>
... ...
config/routes.rb
... ... @@ -126,12 +126,14 @@ ActionController::Routing::Routes.draw do |map|
126 126 # cache stuff - hack
127 127 map.cache 'public/:action/:id', :controller => 'public'
128 128  
  129 + map.connect ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } }
  130 + map.connect '*page/versions', :controller => 'content_viewer', :action => 'article_versions'
129 131  
130 132 # match requests for profiles that don't have a custom domain
131 133 map.homepage ':profile/*page', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } }
132 134  
133   -
134 135 # match requests for content in domains hosted for profiles
135 136 map.connect '*page', :controller => 'content_viewer', :action => 'view_page'
136 137  
  138 +
137 139 end
... ...
features/article_versioning.feature 0 → 100644
... ... @@ -0,0 +1,87 @@
  1 +Feature: article versioning
  2 + As a user
  3 + I want to see article versions
  4 + In order to be able to change between versions of an article
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name |
  9 + | joaosilva | Joao Silva |
  10 + And "joaosilva" has no articles
  11 + And the following articles
  12 + | owner | name | body | display_versions |
  13 + | joaosilva | Sample Article | This is the first version of the article | true |
  14 + And the article "Sample Article" is updated with
  15 + | name | body |
  16 + | Edited Article | This is the second version of the article |
  17 + And I am logged in as "joaosilva"
  18 +
  19 + @selenium
  20 + Scenario: enabling visualization of versions
  21 + Given the following articles
  22 + | owner | name | body |
  23 + | joaosilva | New Article | Article to enable versions |
  24 + Given I am on article "New Article"
  25 + Then I should not see "All versions"
  26 + When I follow "Edit" within "#article-actions"
  27 + And I check "I want this article to display a link to older versions"
  28 + And I press "Save"
  29 + Then I should be on article "New Article"
  30 + And I should see "All versions"
  31 +
  32 + @selenium
  33 + Scenario: list versions of an article
  34 + Given I am on article "Edited Article"
  35 + When I follow "All versions"
  36 + Then I should be on /joaosilva/edited-article/versions
  37 + And I should see "Version 1" within ".article-versions"
  38 + And I should see "Version 2" within ".article-versions"
  39 +
  40 + @selenium
  41 + Scenario: see specific version
  42 + Given I go to article "Edited Article"
  43 + Then I should see "Edited Article" within ".title"
  44 + And I should see "This is the second version of the article" within ".article-body"
  45 + When I follow "All versions"
  46 + And I follow "Version 1"
  47 + Then I should see "Sample Article" within ".title"
  48 + And I should see "This is the first version of the article" within ".article-body"
  49 +
  50 + @selenium
  51 + Scenario: revert to a specific version generates a new version
  52 + Given I go to article "Edited Article"
  53 + When I follow "All versions"
  54 + Then I should not see "Version 3" within ".article-versions"
  55 + And I follow "Version 1"
  56 + And I follow "Revert to this version"
  57 + And I press "Save"
  58 + Then I should see "Sample Article" within ".title"
  59 + When I follow "All versions"
  60 + Then I should see "Version 3" within ".article-versions"
  61 +
  62 + Scenario: try to access versions of unexistent article
  63 + Given I go to /joaosilva/unexistent-article/versions
  64 + Then I should see "There is no such page"
  65 +
  66 + Scenario: deny access to versions when disabled on article
  67 + Given the following articles
  68 + | owner | name | body | display_versions |
  69 + | joaosilva | Versions disabled | Versions can't be displayed | false |
  70 + And I go to /joaosilva/versions-disabled/versions
  71 + Then I should see "Access denied"
  72 +
  73 + Scenario: deny access to specific version when disabled on article and not logged
  74 + Given the article "Edited Article" is updated with
  75 + | display_versions |
  76 + | false |
  77 + And I am not logged in
  78 + And I go to /joaosilva/edited-article?version=1
  79 + Then I should see "Access denied"
  80 +
  81 + Scenario: deny access to specific version when disabled, private and not logged
  82 + Given the article "Edited Article" is updated with
  83 + | display_versions | published |
  84 + | false | false |
  85 + And I am not logged in
  86 + And I go to /joaosilva/edited-article?version=1
  87 + Then I should see "Access denied"
... ...
features/step_definitions/noosfero_steps.rb
... ... @@ -687,6 +687,14 @@ Given /^the article &quot;([^\&quot;]*)&quot; is updated by &quot;([^\&quot;]*)&quot;$/ do |article, person|
687 687 a.save!
688 688 end
689 689  
  690 +Given /^the article "([^\"]*)" is updated with$/ do |article, table|
  691 + a = Article.find_by_name article
  692 +
  693 + row = table.hashes.first
  694 +
  695 + a.update_attributes(row)
  696 +end
  697 +
690 698 Given /^the cache is turned (on|off)$/ do |state|
691 699 ActionController::Base.perform_caching = (state == 'on')
692 700 end
... ...
public/designs/icons/tango/style.css
... ... @@ -105,6 +105,7 @@
105 105 .icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) }
106 106 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
107 107 .icon-reset-admin-role { background-image: url(/images/icons-app/person-icon.png) }
  108 +.icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
108 109  
109 110 /******************LARGE ICONS********************/
110 111 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
... ...
public/stylesheets/application.css
... ... @@ -6466,3 +6466,15 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6466 6466 width: 100px;
6467 6467 text-align: center;
6468 6468 }
  6469 +
  6470 +#product-list .highlighted img.star {
  6471 + position: absolute;
  6472 + top: 2px;
  6473 + right: 2px;
  6474 + z-index: 1;
  6475 +}
  6476 +
  6477 +ul.article-versions li {
  6478 + font-size: 13px;
  6479 + padding: 3px 0px;
  6480 +}
... ...
test/functional/cms_controller_test.rb
... ... @@ -1719,6 +1719,23 @@ class CmsControllerTest &lt; ActionController::TestCase
1719 1719 assert_redirected_to '/'
1720 1720 end
1721 1721  
  1722 + should 'edit article with content from older version' do
  1723 + article = profile.articles.create(:name => 'first version')
  1724 + article.name = 'second version'; article.save
  1725 +
  1726 + get :edit, :profile => profile.identifier, :id => article.id, :version => 1
  1727 + assert_equal 'second version', Article.find(article.id).name
  1728 + assert_equal 'first version', assigns(:article).name
  1729 + end
  1730 +
  1731 + should 'save article with content from older version' do
  1732 + article = profile.articles.create(:name => 'first version')
  1733 + article.name = 'second version'; article.save
  1734 +
  1735 + post :edit, :profile => profile.identifier, :id => article.id, :version => 1
  1736 + assert_equal 'first version', Article.find(article.id).name
  1737 + end
  1738 +
1722 1739 protected
1723 1740  
1724 1741 # FIXME this is to avoid adding an extra dependency for a proper JSON parser.
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -369,6 +369,35 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
369 369 assert_redirected_to :host => p.default_hostname, :controller => 'content_viewer', :action => 'view_page', :profile => p.identifier, :page => a2.explode_path
370 370 end
371 371  
  372 + should "display current article's versions" do
  373 + page = TextArticle.create!(:name => 'myarticle', :body => 'test article', :display_versions => true, :profile => profile)
  374 + page.body = 'test article edited'; page.save
  375 +
  376 + get :article_versions, :profile => profile.identifier, :page => [ 'myarticle' ]
  377 + assert_tag :tag => 'ul', :attributes => { :class => 'article-versions' }, :descendant => {
  378 + :tag => 'a',
  379 + :attributes => { :href => "http://#{profile.environment.default_hostname}/#{profile.identifier}/#{page.path}?version=1" }
  380 + }
  381 + end
  382 +
  383 + should "fetch correct article version" do
  384 + page = TextArticle.create!(:name => 'myarticle', :body => 'original article', :display_versions => true, :profile => profile)
  385 + page.body = 'edited article'; page.save
  386 +
  387 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ], :version => 1
  388 +
  389 + assert_tag :tag => 'div', :attributes => { :class => /article-body/ }, :content => /original article/
  390 + end
  391 +
  392 + should "display current article if version does not exist" do
  393 + page = TextArticle.create!(:name => 'myarticle', :body => 'original article', :display_versions => true, :profile => profile)
  394 + page.body = 'edited article'; page.save
  395 +
  396 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ], :version => 'bli'
  397 +
  398 + assert_tag :tag => 'div', :attributes => { :class => /article-body/ }, :content => /edited article/
  399 + end
  400 +
372 401 should 'not return an article of a different user' do
373 402 p1 = create_user('test_user').person
374 403 a = p1.articles.create!(:name => 'old-name')
... ...
test/integration/routing_test.rb
... ... @@ -256,4 +256,19 @@ class RoutingTest &lt; ActionController::IntegrationTest
256 256 assert_recognizes({:controller => 'not_found', :action => 'nothing', :stuff => ['aksdhf']}, '/user_themes/aksdhf')
257 257 end
258 258  
  259 + should 'have route to versions of an article' do
  260 +
  261 + assert_routing('/ze/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => 'ze', :page => ['work', "free-software"])
  262 + end
  263 +
  264 + should 'have route to versions of an article if profile has domain' do
  265 + user = create_user('testuser').person
  266 + domain = Domain.create!(:name => 'example.com', :owner => user)
  267 +
  268 + ActionController::TestRequest.any_instance.expects(:host).returns('www.example.com')
  269 +
  270 + assert_routing('/work/free-software/versions', :controller => 'content_viewer', :action => 'article_versions', :page => [ 'work', 'free-software'] )
  271 + end
  272 +
  273 +
259 274 end
... ...
test/unit/article_test.rb
... ... @@ -740,6 +740,11 @@ class ArticleTest &lt; ActiveSupport::TestCase
740 740 assert_match(/-year-2009-month-04/, a.cache_key(:year => '2009', :month => '04'))
741 741 end
742 742  
  743 + should 'use revision number to compose cache key' do
  744 + a = fast_create(Article, :name => 'Versioned article', :profile_id => profile.id)
  745 + assert_match(/-version-2/,a.cache_key(:version => 2))
  746 + end
  747 +
743 748 should 'not be highlighted by default' do
744 749 a = Article.new
745 750 assert !a.highlighted
... ... @@ -1688,6 +1693,16 @@ class ArticleTest &lt; ActiveSupport::TestCase
1688 1693 assert_equal license, article.license
1689 1694 end
1690 1695  
  1696 + should 'return license from a specific version' do
  1697 + cc = License.create!(:name => 'CC (by)', :environment => Environment.default)
  1698 + gpl = License.create!(:name => 'GPLv3', :environment => Environment.default)
  1699 + article = Article.create!(:name => 'first version', :profile => profile, :license => cc)
  1700 + article.license = gpl
  1701 + article.save
  1702 + assert_equal cc, article.version_license(1)
  1703 + assert_equal gpl, article.version_license(2)
  1704 + end
  1705 +
1691 1706 should 'update path if parent is changed' do
1692 1707 f1 = Folder.create!(:name => 'Folder 1', :profile => profile)
1693 1708 f2 = Folder.create!(:name => 'Folder 2', :profile => profile)
... ... @@ -1746,6 +1761,28 @@ class ArticleTest &lt; ActiveSupport::TestCase
1746 1761 assert_nil article.author_id
1747 1762 end
1748 1763  
  1764 + should "return the author of a specific version" do
  1765 + author1 = fast_create(Person)
  1766 + author2 = fast_create(Person)
  1767 + article = Article.create!(:name => 'first version', :profile => profile, :last_changed_by => author1)
  1768 + article.name = 'second version'
  1769 + article.last_changed_by = author2
  1770 + article.save
  1771 + assert_equal author1, article.author(1)
  1772 + assert_equal author2, article.author(2)
  1773 + end
  1774 +
  1775 + should "return the author_name of a specific version" do
  1776 + author1 = fast_create(Person)
  1777 + author2 = fast_create(Person)
  1778 + article = Article.create!(:name => 'first version', :profile => profile, :last_changed_by => author1)
  1779 + article.name = 'second version'
  1780 + article.last_changed_by = author2
  1781 + article.save
  1782 + assert_equal author1.name, article.author_name(1)
  1783 + assert_equal author2.name, article.author_name(2)
  1784 + end
  1785 +
1749 1786 should 'identify if belongs to forum' do
1750 1787 p = create_user('user_forum_test').person
1751 1788 forum = fast_create(Forum, :name => 'Forum test', :profile_id => p.id)
... ...