]> source.dussan.org Git - redmine.git/commitdiff
Wiki page hierarchy (#528). Parent page can be assigned on Rename screen.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 26 Jul 2008 11:46:24 +0000 (11:46 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 26 Jul 2008 11:46:24 +0000 (11:46 +0000)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1698 e93f8b46-1217-0410-a6f0-8f06a7374b81

38 files changed:
app/controllers/wiki_controller.rb
app/helpers/application_helper.rb
app/helpers/wiki_helper.rb
app/models/wiki_page.rb
app/views/wiki/rename.rhtml
app/views/wiki/show.rhtml
app/views/wiki/special_page_index.rhtml
db/migrate/095_add_wiki_pages_parent_id.rb [new file with mode: 0644]
lang/bg.yml
lang/cs.yml
lang/da.yml
lang/de.yml
lang/en.yml
lang/es.yml
lang/fi.yml
lang/fr.yml
lang/he.yml
lang/hu.yml
lang/it.yml
lang/ja.yml
lang/ko.yml
lang/lt.yml
lang/nl.yml
lang/no.yml
lang/pl.yml
lang/pt-br.yml
lang/pt.yml
lang/ro.yml
lang/ru.yml
lang/sr.yml
lang/sv.yml
lang/th.yml
lang/uk.yml
lang/zh-tw.yml
lang/zh.yml
test/fixtures/wiki_pages.yml
test/functional/wiki_controller_test.rb
test/unit/wiki_page_test.rb

index 8655cfed7fc9484564498b511e958b2ffa386c0f..2430205cfd0646f8eaf62383ea5b04e4d2d5c0c2 100644 (file)
@@ -147,6 +147,7 @@ class WikiController < ApplicationController
                                       :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
                                       :order => 'title'
       @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
+      @pages_by_parent_id = @pages.group_by(&:parent_id)
     # export wiki to a single html file
     when 'export'
       @pages = @wiki.pages.find :all, :order => 'title'
index 7bcec461e496635b7f67fecaeb6068fdceb9ee5a..f5ce7ecda28871443e00203ae27cf5763e868754 100644 (file)
@@ -177,7 +177,8 @@ module ApplicationHelper
   end
   
   def breadcrumb(*args)
-    content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb')
+    elements = args.flatten
+    elements.any? ? content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb') : nil
   end
   
   def html_title(*args)
index 980035bd483ab78014ec60c890999c1bf3b67a9b..d27ce3ea33814c8f7a175f6648e34c965020c990 100644 (file)
 
 module WikiHelper
 
+  def render_page_hierarchy(pages, node=nil)
+    content = ''
+    if pages[node]
+      content << "<ul class=\"pages-hierarchy\">\n"
+      pages[node].each do |page|
+        content << "<li>"
+        content << link_to(h(page.pretty_title), {:action => 'index', :page => page.title},
+                           :title => l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)))
+        content << "\n" + render_page_hierarchy(pages, page.id) if pages[page.id]
+        content << "</li>\n"
+      end
+      content << "</ul>\n"
+    end
+    content
+  end
+  
   def html_diff(wdiff)
     words = wdiff.words.collect{|word| h(word)}
     words_add = 0
index 65fc1f68cd94e40fafcc0d744330fe98798a4e7b..2416fab74dcd87e51db9bc206f1ec5850352ba32 100644 (file)
@@ -22,7 +22,8 @@ class WikiPage < ActiveRecord::Base
   belongs_to :wiki
   has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
   has_many :attachments, :as => :container, :dependent => :destroy
-
+  acts_as_tree :order => 'title'
+  
   acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"},
                 :description => :text,
                 :datetime => :created_on,
@@ -110,6 +111,24 @@ class WikiPage < ActiveRecord::Base
   def editable_by?(usr)
     !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
   end
+  
+  def parent_title
+    @parent_title || (self.parent && self.parent.pretty_title)
+  end
+  
+  def parent_title=(t)
+    @parent_title = t
+    parent_page = t.blank? ? nil : self.wiki.find_page(t)
+    self.parent = parent_page
+  end
+  
+  protected
+  
+  def validate
+    errors.add(:parent_title, :activerecord_error_invalid) if !@parent_title.blank? && parent.nil?
+    errors.add(:parent_title, :activerecord_error_circular_dependency) if parent && (parent == self || parent.ancestors.include?(self))
+    errors.add(:parent_title, :activerecord_error_not_same_project) if parent && (parent.wiki_id != wiki_id)
+  end
 end
 
 class WikiDiff
index 0c069f43d59e575790c1036698c545af356622e1..260f9af8b748115b8f76e04fd7e158c0efc37171 100644 (file)
@@ -4,8 +4,9 @@
 
 <% labelled_tabular_form_for :wiki_page, @page, :url => { :action => 'rename' } do |f| %>
 <div class="box">
-<p><%= f.text_field :title, :required => true, :size => 255  %></p>
+<p><%= f.text_field :title, :required => true, :size => 100  %></p>
 <p><%= f.check_box :redirect_existing_links %></p>
+<p><%= f.text_field :parent_title, :size => 100  %></p>
 </div>
 <%= submit_tag l(:button_rename) %>
 <% end %>
index 8092525bdc2ae9252de1f5e7843f9f5eefedbab2..255b904f5669ed2e07ae3f2b275574c376b30158 100644 (file)
@@ -10,6 +10,8 @@
 <%= link_to(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
 </div>
 
+<%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:page => parent.title}}) %>
+
 <% if @content.version != @page.content.version %>
     <p>    
     <%= link_to(('&#171; ' + l(:label_previous)), :action => 'index', :page => @page.title, :version => (@content.version - 1)) + " - " if @content.version > 1 %>
index f21cc34236fa8d97a127ac1062a03e94eb6b70d3..72b395ef7975b8da7f24a3ede22a759e6ed014bd 100644 (file)
@@ -4,11 +4,7 @@
 <p class="nodata"><%= l(:label_no_data) %></p>
 <% end %>
 
-<ul><% @pages.each do |page| %>
-    <li><%= link_to page.pretty_title, {:action => 'index', :page => page.title},
-                                       :title => l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) %>
-    </li>
-<% end %></ul>
+<%= render_page_hierarchy(@pages_by_parent_id) %>
 
 <% content_for :sidebar do %>
   <%= render :partial => 'sidebar' %>
diff --git a/db/migrate/095_add_wiki_pages_parent_id.rb b/db/migrate/095_add_wiki_pages_parent_id.rb
new file mode 100644 (file)
index 0000000..36b922e
--- /dev/null
@@ -0,0 +1,9 @@
+class AddWikiPagesParentId < ActiveRecord::Migration
+  def self.up
+    add_column :wiki_pages, :parent_id, :integer, :default => nil
+  end
+
+  def self.down
+    remove_column :wiki_pages, :parent_id
+  end
+end
index c87e3bebc23e27200bfa875cb14c0136f3c4056c..e8191dc20e8bbd05a54c22636268916a804a4d66 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 6669c6cf3c860363a71bb61a33fcccac844900e3..68273191ab3c42819dcd6a34cec3c188b3cee335 100644 (file)
@@ -637,3 +637,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index cf40e17631d4c7c3c741629dd8fe5b6c23af3af5..1b5aba69ced1ca7b1d01c051ebfcceb09840aff8 100644 (file)
@@ -634,3 +634,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index adc3dd4e9875f934890d6225035fd979999770cb..dc2960c9cce55489821f26f07c7e3afb74ae2532 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 7910946747762cd7050d8db60c7fa4e5e1b7136f..3cc788b8c37546190caf2d13a0e2e85db2b588bd 100644 (file)
@@ -182,6 +182,7 @@ field_time_zone: Time zone
 field_searchable: Searchable
 field_default_value: Default value
 field_comments_sorting: Display comments
+field_parent_title: Parent page
 
 setting_app_title: Application title
 setting_app_subtitle: Application subtitle
index 4205402e439934ddb45ad6bbe894107b44faefb5..c753f367f0475ee8f0a2c435f34290e65261380d 100644 (file)
@@ -635,3 +635,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index b69b0755761bc109023c4b14fc51ded39f1c3fef..b48d8a319355316c834f98f9bb272c53d1645dbd 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 5b0f04fb049c7ae89458d2781cb5a1e1dd7bebed..b9d542da61b0f5c0252c11357d6083eb91274722 100644 (file)
@@ -183,6 +183,7 @@ field_time_zone: Fuseau horaire
 field_searchable: Utilisé pour les recherches
 field_default_value: Valeur par défaut
 field_comments_sorting: Afficher les commentaires
+field_parent_title: Page parent
 
 setting_app_title: Titre de l'application
 setting_app_subtitle: Sous-titre de l'application
index 030e09dcc5db0435a21995bea2bdc908ab444a2d..63aa2bb6438ca82cdedccd2e905990aa118f4b31 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 630294c9d48e5c950b690807d8cf051eec83895a..9becbb3499495d72225b2c071b241a9974a3c752 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Kulcs generálása
 setting_mail_handler_api_enabled: Web Service engedélyezése a beérkezett levelekhez
 setting_mail_handler_api_key: API kulcs
 text_email_delivery_not_configured: "Az E-mail küldés nincs konfigurálva, és az értesítések ki vannak kapcsolva.\nÁllítsd be az SMTP szervert a config/email.yml fájlban és indítsd újra az alkalmazást, hogy érvénybe lépjen."
+field_parent_title: Parent page
index 471ef49ed5b1375d4bf8d4e25bb5113f7d5e0801..e7a8772cc0e6901060cd27c02fffbb1aac6544fe 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Genera una chiave
 setting_mail_handler_api_enabled: Abilita WS per le e-mail in arrivo
 setting_mail_handler_api_key: chiave API
 text_email_delivery_not_configured: "La consegna via e-mail non è configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/email.yml e riavvia l'applicazione per abilitarle."
+field_parent_title: Parent page
index cba410f6dbc3a7531d33f931f1282249d6c01bf5..f78fcdba47dee572cb099819676accf05e146292 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 2b5b0eb0a4951b17868a214bf44580dccae7f235..77672c60171fa5021417b66582ff0ba0a4c916e4 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 52b6b6fc86d3e5f67a5e3f2aa2403e81590851df..706133bfe0d9a10b5f90fc71dba70f30f468286a 100644 (file)
@@ -635,3 +635,4 @@ setting_mail_handler_api_enabled: Įgalinti WS įeinantiems laiškams
 setting_mail_handler_api_key: API raktas
 
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 09cdc3c08eb365144822a807f450bb653c315b36..3cfb0aa193e09a0aae8f55d1c821ab5197b06872 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index eb1ff59ca0e13998a24fec2550425d54a81fbfba..0836bd48fa2b55191e6c323a3d882c209ea93892 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 9c5a382b0a018ee4a03909e82426be66734ccb5f..278d56a88de4bdd2a9a1e635e2d70eaa5de7b903 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 1582e568febc8beccdbeac2da000a20ac51055df..9276d768e0351f70c042246c3239d23b048a83ca 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails\r
 setting_mail_handler_api_key: API key\r
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."\r
+field_parent_title: Parent page\r
index ece12cd973264cfd96b4d427cef5f8b8a3bf3178..a7647e31f125bc873a127e37eb429277c3a30c9b 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 50bbf29af722f88953013d2fc85450980647b776..c3640d7e10eca4b313b7a5fc7e0573f169263aeb 100644 (file)
@@ -632,3 +632,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index c0cac30a0855c4443ff8f95fdb1d0ab0b84a07e4..e8bda05b72b8593145baa883b9f94168510b769e 100644 (file)
@@ -636,3 +636,4 @@ label_generate_key: Сгенерировать ключ
 setting_mail_handler_api_enabled: Включить веб-сервис для входящих сообщений
 setting_mail_handler_api_key: API ключ
 text_email_delivery_not_configured: "Параметры работы с почтовым сервером не настроены и функция уведомления по email не активна.\nНастроить параметры для вашего SMTP сервера вы можете в файле config/email.yml. Для применения изменений перезапустите приложение."
+field_parent_title: Parent page
index fa1b4d847f4f56bd6affccc764b68fbdee54e679..688fa8ede2c5c4a63b9aa6b36f4146edbbaf2aeb 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 9015099e7f0a604003fe59a67be035bd8c56e4b4..58507a0b706eb9e9668b24f8a351b73f5b78c197 100644 (file)
@@ -633,3 +633,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 27f7b14cffc19ec39e26f9a6ac723d7977f66518..a7f949c96e14c3fe241711e569d2642cad84baa1 100644 (file)
@@ -635,3 +635,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index 0286779bea9ab81b9437c261b45b77c43f29dfa2..766ddaaab4104d10518e56a51c9204a0abb5a9a3 100644 (file)
@@ -634,3 +634,4 @@ label_generate_key: Generate a key
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index bad6fcca5a221893092f1f408face4752ee67edc..82f26ab8683b85250d5e9381f281cc63dc99c5d6 100644 (file)
@@ -633,3 +633,4 @@ default_activity_development: 開發
 enumeration_issue_priorities: 項目優先權
 enumeration_doc_categories: 文件分類
 enumeration_activities: 活動 (時間追蹤)
+field_parent_title: Parent page
index 1cde9f502e1831533743dd41de356b3d9686c241..b4ae89ba7ea62f3b3c43227ba5b883c8871316bc 100644 (file)
@@ -633,3 +633,4 @@ enumeration_issue_priorities: 问题优先级
 enumeration_doc_categories: 文档类别
 enumeration_activities: 活动(时间跟踪)
 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
+field_parent_title: Parent page
index ef72424305f17efb0326b50406ad4a9bb2056f34..e285441ff90c0b6ed3c6a51f71b8b7de89eae85f 100644 (file)
@@ -4,23 +4,27 @@ wiki_pages_001:
   title: CookBook_documentation\r
   id: 1\r
   wiki_id: 1\r
-  protected: true  \r
+  protected: true\r
+  parent_id: \r
 wiki_pages_002: \r
   created_on: 2007-03-08 00:18:07 +01:00\r
   title: Another_page\r
   id: 2\r
   wiki_id: 1\r
   protected: false\r
+  parent_id: \r
 wiki_pages_003: \r
   created_on: 2007-03-08 00:18:07 +01:00\r
   title: Start_page\r
   id: 3\r
   wiki_id: 2\r
   protected: false\r
+  parent_id: \r
 wiki_pages_004: \r
   created_on: 2007-03-08 00:18:07 +01:00\r
   title: Page_with_an_inline_image\r
   id: 4\r
   wiki_id: 1\r
   protected: false\r
+  parent_id: 1\r
   
\ No newline at end of file
index f1ae7a9c25bd6c5083700502f5e931e2c05226c5..06d8cacf204012733e34247c8083da62817ca38e 100644 (file)
@@ -163,8 +163,16 @@ class WikiControllerTest < Test::Unit::TestCase
     pages = assigns(:pages)
     assert_not_nil pages
     assert_equal Project.find(1).wiki.pages.size, pages.size
-    assert_tag :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' },
-                            :content => /CookBook documentation/
+    
+    assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
+                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' },
+                                              :content => 'CookBook documentation' },
+                                :child => { :tag => 'ul',
+                                            :child => { :tag => 'li',
+                                                        :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Page_with_an_inline_image' },
+                                                                                 :content => 'Page with an inline image' } } } },
+                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Another_page' },
+                                                                       :content => 'Another page' } }
   end
   
   def test_not_found
index bb8111176b0e2c7d7091a121559628d0fa684532..e5ebeeea6893ed7bf2fd53461f29020be65f7a8b 100644 (file)
@@ -48,6 +48,50 @@ class WikiPageTest < Test::Unit::TestCase
     assert page.new_record?
   end
   
+  def test_parent_title
+    page = WikiPage.find_by_title('Another_page')
+    assert_nil page.parent_title
+    
+    page = WikiPage.find_by_title('Page_with_an_inline_image')
+    assert_equal 'CookBook documentation', page.parent_title
+  end
+  
+  def test_assign_parent
+    page = WikiPage.find_by_title('Another_page')
+    page.parent_title = 'CookBook documentation'
+    assert page.save
+    page.reload
+    assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
+  end
+  
+  def test_unassign_parent
+    page = WikiPage.find_by_title('Page_with_an_inline_image')
+    page.parent_title = ''
+    assert page.save
+    page.reload
+    assert_nil page.parent
+  end
+  
+  def test_parent_validation
+    page = WikiPage.find_by_title('CookBook_documentation')
+    
+    # A page that doesn't exist
+    page.parent_title = 'Unknown title'
+    assert !page.save
+    assert_equal :activerecord_error_invalid, page.errors.on(:parent_title)
+    # A child page
+    page.parent_title = 'Page_with_an_inline_image'
+    assert !page.save
+    assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
+    # The page itself
+    page.parent_title = 'CookBook_documentation'
+    assert !page.save
+    assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
+
+    page.parent_title = 'Another_page'
+    assert page.save
+  end
+  
   def test_destroy
     page = WikiPage.find(1)
     page.destroy