diff --git a/app/models/page.rb b/app/models/page.rb index b2bd0ee6..f6257120 100755 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -15,6 +15,7 @@ class Page end def revise(content, created_at, author) + if not @revisions.empty? and content == @revisions.last.content raise Instiki::ValidationError.new( "You have tried to save page '#{name}' without changing its content") @@ -34,7 +35,7 @@ class Page web.refresh_pages_with_references(name) if @revisions.length == 1 end - + def rollback(revision_number, created_at, author_ip = nil) roll_back_revision = @revisions[revision_number].dup revise(roll_back_revision.content, created_at, Author.new(roll_back_revision.author, author_ip)) diff --git a/test/unit/wiki_service_test.rb b/test/unit/wiki_service_test.rb index 1c3f7695..c6a04e07 100755 --- a/test/unit/wiki_service_test.rb +++ b/test/unit/wiki_service_test.rb @@ -37,27 +37,66 @@ class WikiServiceTest < Test::Unit::TestCase 'state of any object, and therefore should not be logged by Madeleine!', Time.now, 'AlexeyVerkhovsky' - assert_doesnt_change_state :authenticate, 'pswd' - assert_doesnt_change_state :read_page, 'instiki', 'TestReadOnlyOperations' - assert_doesnt_change_state :setup? - assert_doesnt_change_state :webs + assert_doesnt_change_state_or_log :authenticate, 'pswd' + assert_doesnt_change_state_or_log :read_page, 'instiki', 'TestReadOnlyOperations' + assert_doesnt_change_state_or_log :setup? + assert_doesnt_change_state_or_log :webs @s.write_page 'instiki', 'FirstPage', "Electric shocks, I love 'em", Time.now, 'DavidHeinemeierHansson' assert_equal "Electric shocks, I love 'em", @s.read_page('instiki', 'FirstPage').content end + def test_aborted_transaction + @s.write_page 'instiki', 'FirstPage', "Electric shocks, I love 'em", + 10.minutes.ago, 'DavidHeinemeierHansson' - def assert_doesnt_change_state(method, *args) + assert_doesnt_change_state('revise_page with unchanged content') { + begin + @s.revise_page 'instiki', 'FirstPage', "Electric shocks, I love 'em", + Time.now, 'DavidHeinemeierHansson' + fail 'Expected Instiki::ValidationError not raised' + rescue Instiki::ValidationError + end + } + end + + + # Checks that a method call or a block doesn;t change the persisted state of the wiki + # Usage: + # assert_doesnt_change_state :read_page, 'instiki', 'TestReadOnlyOperations' + # or + # assert_doesnt_change_state {|wiki| wiki.webs} + + def assert_doesnt_change_state(method, *args, &block) + _assert_doesnt_change_state(including_command_log = false, method, *args, &block) + end + + # Same as assert_doesnt_change_state, but also asserts that no vommand log is generated + def assert_doesnt_change_state_or_log(method, *args, &block) + _assert_doesnt_change_state(including_command_log = true, method, *args, &block) + end + + private + + def _assert_doesnt_change_state(including_log, method, *args) WikiService.snapshot last_snapshot_before = File.read(Dir[RAILS_ROOT + 'storage/test/*.snapshot'].last) - - @s.send(method, *args) - command_logs = Dir[RAILS_ROOT + 'storage/test/*.command_log'] - assert command_logs.empty?, "Calls to #{method} should not be logged" + if block_given? + yield @s + else + @s.send(method, *args) + end + + if including_log + command_logs = Dir[RAILS_ROOT + 'storage/test/*.command_log'] + assert command_logs.empty?, "Calls to #{method} should not be logged" + end + last_snapshot_after = File.read(Dir[RAILS_ROOT + 'storage/test/*.snapshot'].last) - assert last_snapshot_before == last_snapshot_after, - 'Calls to #{method} should not change the state of any persisted object' + assert last_snapshot_before == last_snapshot_after, + 'Calls to #{method} should not change the state of any persisted object' end + end