rollback.t 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. # Copyright (C) 2006–2015 Alex Schroeder <alex@gnu.org>
  2. #
  3. # This program is free software; you can redistribute it and/or modify it under
  4. # the terms of the GNU General Public License as published by the Free Software
  5. # Foundation; either version 3 of the License, or (at your option) any later
  6. # version.
  7. #
  8. # This program is distributed in the hope that it will be useful, but WITHOUT
  9. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License along with
  13. # this program. If not, see <http://www.gnu.org/licenses/>.
  14. require 't/test.pl';
  15. package OddMuse;
  16. use Test::More tests => 69;
  17. use utf8; # tests contain UTF-8 characters and it matters
  18. AppendStringToFile($ConfigFile, "\$KeepDays = 14;\n");
  19. # reproduce a particular bug from emacswiki.org
  20. update_page('SiteMap', 'initial entry');
  21. sleep(1);
  22. update_page('SiteMap', 'last good entry was a minor edit', '', 1);
  23. ok(get_page('action=browse id=SiteMap raw=2')
  24. =~ /(\d+) # Do not delete this line/,
  25. 'raw=2 returns timestamp');
  26. $to = $1;
  27. ok($to, 'timestamp stored');
  28. sleep(1);
  29. update_page('SiteMap', 'vandal overwrites with major edit');
  30. update_page('SiteMap', 'gnome attemps wrong fix with minor edit', '', 1);
  31. test_page(get_page("action=rollback to=$to pwd=foo"),
  32. 'Rolling back changes', 'SiteMap</a> rolled back');
  33. OpenPage('SiteMap');
  34. isnt($Page{minor}, 1, 'Rollback is a major edit');
  35. is($Page{text}, "last good entry was a minor edit\n", 'Rollback successful');
  36. # new set of tests
  37. clear_pages();
  38. AppendStringToFile($ConfigFile, "\$KeepDays = 7;\n");
  39. WriteStringToFile($RcFile, "1FirstPage1\n");
  40. AppendStringToFile($RcFile, "2SecondPage1\n");
  41. # old revisions
  42. update_page('InnocentPage', 'Innocent.', 'good guy zero');
  43. update_page('NicePage', 'Friendly content.', 'good guy one');
  44. update_page('OtherPage', 'Other cute content 1.', 'another good guy');
  45. update_page('OtherPage', 'Other cute content 2.', 'another good guy');
  46. update_page('OtherPage', 'Other cute content 3.', 'another good guy');
  47. # good revisions -- need a different timestamp than the old revisions!
  48. sleep(1);
  49. update_page('InnocentPage', 'Lamb.', 'good guy zero');
  50. update_page('OtherPage', 'Other cute content 12.', 'another good guy');
  51. update_page('MinorPage', 'Dumdidu', 'tester');
  52. # last good revision -- needs a different timestamp than the good revisions!
  53. sleep(1);
  54. update_page('NicePage', 'Nice content.', 'good guy two');
  55. # bad revisions -- need a different timestamp than the last good revision!
  56. sleep(1);
  57. update_page('NicePage', 'Evil content.', 'vandal one');
  58. update_page('OtherPage', 'Other evil content.', 'another vandal');
  59. update_page('NicePage', 'Bad content.', 'vandal two');
  60. update_page('EvilPage', 'Spam!', 'vandal three');
  61. update_page('AnotherEvilPage', 'More Minor Spam!', 'vandal four', 1);
  62. update_page('AnotherEvilPage', 'Still More Minor Spam!', 'vandal five', 1);
  63. update_page('MinorPage', 'Ramtatam', 'testerror', 1);
  64. test_page(get_page('NicePage'), 'Bad content');
  65. test_page(get_page('InnocentPage'), 'Lamb');
  66. # make sure all those spammers are in the past
  67. sleep(1);
  68. # find the rollback link for the last good revision
  69. $to = xpath_test(get_page('action=rc all=1 pwd=foo'),
  70. '//strong[text()="good guy two"]/preceding-sibling::input[@type="submit"]/attribute::name');
  71. $to =~ /rollback-([0-9]+)/;
  72. $to = $1;
  73. test_page(get_page("action=rollback to=$to"), 'username is required');
  74. test_page(get_page("action=rollback to=$to username=me"), 'restricted to administrators');
  75. test_page(get_page("action=rollback to=$to pwd=foo"),
  76. 'Rolling back changes',
  77. 'EvilPage</a> rolled back',
  78. 'AnotherEvilPage</a> rolled back',
  79. 'MinorPage</a> rolled back',
  80. 'NicePage</a> rolled back',
  81. 'OtherPage</a> rolled back');
  82. test_page(get_page('NicePage'), 'Nice content');
  83. test_page(get_page('OtherPage'), 'Other cute content 12');
  84. test_page(get_page('EvilPage'), 'DeletedPage');
  85. test_page(get_page('AnotherEvilPage'), 'DeletedPage');
  86. test_page(get_page('InnocentPage'), 'Lamb');
  87. # make sure $Now of Recent Changes is larger than $LastUpdate
  88. sleep(1);
  89. # this includes rollback info and rollback links
  90. my $rc = get_page('action=rc all=1 showedit=1 pwd=foo from=1');
  91. # check all revisions of NicePage in recent changes
  92. xpath_test($rc,
  93. '//li/span[@class="time"]/following-sibling::span[@class="new"][text()="new"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage;revision=1"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="good guy one"]',
  94. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=NicePage;revision=2"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage;revision=2"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="good guy two"]',
  95. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=NicePage;revision=3"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage;revision=3"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="vandal one"]',
  96. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=NicePage;revision=4"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage;revision=4"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="vandal two"]',
  97. # The first link to NicePage has no revision (because
  98. # it is the latest version) and no rollback link (because
  99. # the timestamp is equal to $LastUpdate)
  100. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=NicePage"][text()="diff"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[contains(text(),"Rollback to")]',
  101. # The second link to NicePage has a revision (because
  102. # it is from an older version) and a rollback link (because
  103. # the timestamp is smaller than $LastUpdate)
  104. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=NicePage;revision=4"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=NicePage;revision=4"][text()="NicePage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="vandal two"]',
  105. # check that the minor spam is reverted with a minor rollback
  106. '//li/span[@class="time"]/following-sibling::span[@class="new"][text()="new"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=MinorPage;revision=1"][text()="MinorPage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="tester"]',
  107. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=MinorPage;revision=2"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=MinorPage;revision=2"][text()="MinorPage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="testerror"]/following-sibling::em[text()="(minor)"]',
  108. # The first link has no revision (because it is the
  109. # latest version) and no rollback link (because the
  110. # timestamp is equal to $LastUpdate)
  111. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=MinorPage"][text()="diff"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=MinorPage"][text()="MinorPage"]/following-sibling::span[@class="dash"]/following-sibling::strong[contains(text(),"Rollback to")]/following-sibling::em[text()="(minor)"]',
  112. # The second link has a revision (because it is from an
  113. # older version) and a rollback link (because the timestamp
  114. # is smaller than $LastUpdate)
  115. '//li/span[@class="time"]/following-sibling::a[@class="diff"][@href="http://localhost/wiki.pl?action=browse;diff=2;id=MinorPage;revision=2"][text()="diff"]/following-sibling::input[@type="submit"][@value="rollback"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=MinorPage;revision=2"][text()="MinorPage"]/following-sibling::span[@class="dash"]/following-sibling::strong[text()="testerror"]/following-sibling::em[text()="(minor)"]',
  116. # The first page has no rollback link
  117. '//li/span[@class="time"]/following-sibling::span[@class="new"][text()="new"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=FirstPage"][text()="FirstPage"]',
  118. # The second page has a rollback link
  119. '//li/span[@class="time"]/following-sibling::span[@class="new"][text()="new"]/following-sibling::input[@type="submit"][@value="rollback"][@name="rollback-2"]/following-sibling::a[@class="revision"][@href="http://localhost/wiki.pl?action=browse;id=SecondPage"][text()="SecondPage"]',
  120. );
  121. # test that ordinary RC doesn't show the rollback stuff
  122. update_page('Yoga', 'Ommmm', 'peace');
  123. $page = get_page('action=rc raw=1');
  124. test_page($page,
  125. "title: NicePage\ndescription: good guy two\n",
  126. "title: MinorPage\ndescription: tester\n",
  127. "title: OtherPage\ndescription: another good guy\n",
  128. "title: InnocentPage\ndescription: good guy zero\n",
  129. "title: Yoga\ndescription: peace\n",
  130. );
  131. test_page_negative($page,
  132. "rollback",
  133. "Rollback",
  134. "EvilPage",
  135. "AnotherEvilPage",
  136. );
  137. # test url encoding
  138. test_page(update_page('Schröder', 'Alex', 'eins'), 'Alex');
  139. OpenPage('Schröder');
  140. $to = $Page{ts};
  141. sleep(1);
  142. test_page(update_page('HiddenEdit', 'not to be rolled back', 'secret'), 'not to be rolled back');
  143. test_page(update_page('Schröder', 'Berta', 'zwei'), 'Berta');
  144. xpath_test(get_page('action=history id=Schr%c3%b6der username=olaf'),
  145. '//input[@type="submit"][@value="rollback"][@name="rollback-' . $to . '"]');
  146. # test single page rollback
  147. test_page(get_page("action=rollback to=$to id=Schr%c3%b6der username=olaf"),
  148. 'Rolling back changes',
  149. 'Schröder</a> rolled back');
  150. test_page(get_page('Schr%c3%b6der'), 'Alex');
  151. # make sure it is hidden from recent changes
  152. $page = get_page('action=rc raw=1');
  153. test_page($page, "title: Schröder\ndescription: eins\n",
  154. "title: HiddenEdit\ndescription: secret\n");
  155. test_page_negative($page, "title: Schröder\ndescription: zwei\n");
  156. # make sure that rollback=1 shows the rollback link
  157. test_page(get_page('action=rc raw=1 rollback=1'),
  158. "title: Schröder\ndescription: Rollback to ",
  159. "title: HiddenEdit\ndescription: secret\n");
  160. # all=1 shows all links including rollbacks
  161. test_page(get_page('action=rc raw=1 rollback=1 all=1'),
  162. "title: Schröder\ndescription: Rollback to ",
  163. "title: Schröder\ndescription: zwei\n",
  164. "title: Schröder\ndescription: eins\n",
  165. "title: HiddenEdit\ndescription: secret\n",
  166. 'link: http://localhost/wiki.pl/Schr%c3%b6der',
  167. 'link: http://localhost/wiki.pl\?action=browse;id=Schr%c3%b6der;revision=2',
  168. 'link: http://localhost/wiki.pl\?action=browse;id=Schr%c3%b6der;revision=1');
  169. # Making sure no extra [[rollback]] entries show up
  170. clear_pages();
  171. $KeepDays = 14;
  172. AppendStringToFile($ConfigFile, "\$KeepDays = 14;\n");
  173. update_page('Test', 'Hallo');
  174. $ts = $Now - $KeepDays * 86400 + 100;
  175. get_page("action=rollback to=$ts username=Alex pwd=foo");
  176. AppendStringToFile($ConfigFile, "\$KeepDays = 7;\n");
  177. test_page_negative(get_page("action=rc raw=1"), '[[rollback]]');
  178. # Avoid Save button for comments
  179. AppendStringToFile($ConfigFile, "\$CommentsPrefix = 'Comments on ';\n");
  180. update_page('Comments_on_Test', 'no spam');
  181. ok(get_page('action=browse id=Test raw=2')
  182. =~ /(\d+) # Do not delete this line/,
  183. 'raw=2 returns timestamp');
  184. $to = $1;
  185. ok($to, 'timestamp stored');
  186. sleep(1);
  187. get_page('title=Comments_on_Test aftertext=http://spam/amoxil/');
  188. test_page(get_page('Comments_on_Test'), 'spam');
  189. # rollback without password
  190. $page = get_page("action=rollback id=Comments_on_Test to=$to username=Alex");
  191. test_page($page, 'Rolling back changes');
  192. test_page_negative($page, 'Add your comment here', 'Save');