You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repositories_subversion_controller_test.rb 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2022 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require File.expand_path('../../test_helper', __FILE__)
  19. class RepositoriesSubversionControllerTest < Redmine::RepositoryControllerTest
  20. tests RepositoriesController
  21. fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, :enabled_modules,
  22. :repositories, :issues, :issue_statuses, :changesets, :changes,
  23. :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
  24. PRJ_ID = 3
  25. NUM_REV = 14
  26. def setup
  27. super
  28. Setting.default_language = 'en'
  29. User.current = nil
  30. @project = Project.find(PRJ_ID)
  31. @repository = Repository::Subversion.create(:project => @project,
  32. :url => self.class.subversion_repository_url)
  33. assert @repository
  34. end
  35. if repository_configured?('subversion')
  36. def test_new
  37. @request.session[:user_id] = 1
  38. @project.repository.destroy
  39. get(
  40. :new,
  41. :params => {
  42. :project_id => 'subproject1',
  43. :repository_scm => 'Subversion'
  44. }
  45. )
  46. assert_response :success
  47. assert_select 'select[name=?]', 'repository_scm' do
  48. assert_select 'option[value=?][selected=selected]', 'Subversion'
  49. end
  50. end
  51. def test_show
  52. assert_equal 0, @repository.changesets.count
  53. @repository.fetch_changesets
  54. @project.reload
  55. assert_equal NUM_REV, @repository.changesets.count
  56. get(
  57. :show,
  58. :params => {
  59. :id => PRJ_ID
  60. }
  61. )
  62. assert_response :success
  63. assert_select 'table.entries tbody' do
  64. assert_select 'tr', 1
  65. assert_select 'tr.dir td.filename a', :text => 'subversion_test'
  66. assert_select 'tr.dir td.filename a[href=?]', "/projects/subproject1/repository/#{@repository.id}/show/subversion_test"
  67. end
  68. assert_select 'table.changesets tbody' do
  69. assert_select 'tr', 10
  70. assert_select 'tr td.id a', :text => '12'
  71. end
  72. assert_select 'input[name=rev]'
  73. assert_select 'a', :text => 'Statistics'
  74. assert_select 'a', :text => 'Atom'
  75. assert_select 'a[href=?]', "/projects/subproject1/repository/#{@repository.id}", :text => 'root'
  76. end
  77. def test_show_non_default
  78. Repository::Subversion.create(:project => @project,
  79. :url => self.class.subversion_repository_url,
  80. :is_default => false, :identifier => 'svn')
  81. get(
  82. :show,
  83. :params => {
  84. :id => PRJ_ID,
  85. :repository_id => 'svn'
  86. }
  87. )
  88. assert_response :success
  89. assert_select 'tr.dir a[href="/projects/subproject1/repository/svn/show/subversion_test"]'
  90. # Repository menu should link to the main repo
  91. assert_select '#main-menu a[href="/projects/subproject1/repository"]'
  92. end
  93. def test_browse_directory
  94. assert_equal 0, @repository.changesets.count
  95. @repository.fetch_changesets
  96. @project.reload
  97. assert_equal NUM_REV, @repository.changesets.count
  98. get(
  99. :show,
  100. :params => {
  101. :id => PRJ_ID,
  102. :repository_id => @repository.id,
  103. :path => repository_path_hash(['subversion_test'])[:param]
  104. }
  105. )
  106. assert_response :success
  107. assert_select 'table.entries tbody' do
  108. assert_select 'tr', 6
  109. assert_select 'tr.dir td.filename a', :text => '[folder_with_brackets]'
  110. assert_select 'tr.dir td.filename a', :text => 'folder'
  111. assert_select 'tr.file td.filename a', :text => '+.md'
  112. assert_select 'tr.file td.filename a', :text => '.project'
  113. assert_select 'tr.file td.filename a', :text => 'helloworld.c'
  114. assert_select 'tr.file td.filename a', :text => 'textfile.txt'
  115. end
  116. assert_select 'a.text-x-c', :text => 'helloworld.c'
  117. end
  118. def test_browse_at_given_revision
  119. assert_equal 0, @repository.changesets.count
  120. @repository.fetch_changesets
  121. @project.reload
  122. assert_equal NUM_REV, @repository.changesets.count
  123. get(
  124. :show,
  125. :params => {
  126. :id => PRJ_ID,
  127. :repository_id => @repository.id,
  128. :path => repository_path_hash(['subversion_test'])[:param],
  129. :rev => 4
  130. }
  131. )
  132. assert_response :success
  133. assert_select 'table.entries tbody' do
  134. assert_select 'tr', 5
  135. assert_select 'tr.dir td.filename a', :text => 'folder'
  136. assert_select 'tr.file td.filename a', :text => '.project'
  137. assert_select 'tr.file td.filename a', :text => 'helloworld.c'
  138. assert_select 'tr.file td.filename a', :text => 'helloworld.rb'
  139. assert_select 'tr.file td.filename a', :text => 'textfile.txt'
  140. end
  141. end
  142. def test_file_changes
  143. assert_equal 0, @repository.changesets.count
  144. @repository.fetch_changesets
  145. @project.reload
  146. assert_equal NUM_REV, @repository.changesets.count
  147. get(
  148. :changes,
  149. :params => {
  150. :id => PRJ_ID,
  151. :repository_id => @repository.id,
  152. :path => repository_path_hash(['subversion_test', 'folder', 'helloworld.rb'])[:param]
  153. }
  154. )
  155. assert_response :success
  156. assert_select 'table.changesets tbody' do
  157. assert_select 'tr', 3
  158. assert_select 'tr td.id a', :text => '6'
  159. assert_select 'tr td.id a', :text => '3'
  160. assert_select 'tr td.id a', :text => '2'
  161. end
  162. # svn properties displayed with svn >= 1.5 only
  163. if Redmine::Scm::Adapters::SubversionAdapter.client_version_above?([1, 5, 0])
  164. assert_select 'ul li' do
  165. assert_select 'b', :text => 'svn:eol-style'
  166. assert_select 'span', :text => 'native'
  167. end
  168. end
  169. end
  170. def test_directory_changes
  171. assert_equal 0, @repository.changesets.count
  172. @repository.fetch_changesets
  173. @project.reload
  174. assert_equal NUM_REV, @repository.changesets.count
  175. get(
  176. :changes,
  177. :params => {
  178. :id => PRJ_ID,
  179. :repository_id => @repository.id,
  180. :path => repository_path_hash(['subversion_test', 'folder'])[:param]
  181. }
  182. )
  183. assert_response :success
  184. assert_select 'table.changesets tbody' do
  185. assert_select 'tr', 8
  186. assert_select 'tr td.id a', :text => '13'
  187. assert_select 'tr td.id a', :text => '12'
  188. assert_select 'tr td.id a', :text => '10'
  189. assert_select 'tr td.id a', :text => '9'
  190. assert_select 'tr td.id a', :text => '7'
  191. assert_select 'tr td.id a', :text => '6'
  192. assert_select 'tr td.id a', :text => '5'
  193. assert_select 'tr td.id a', :text => '2'
  194. end
  195. end
  196. def test_entry
  197. assert_equal 0, @repository.changesets.count
  198. @repository.fetch_changesets
  199. @project.reload
  200. assert_equal NUM_REV, @repository.changesets.count
  201. get(
  202. :entry,
  203. :params => {
  204. :id => PRJ_ID,
  205. :repository_id => @repository.id,
  206. :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
  207. }
  208. )
  209. assert_response :success
  210. assert_select 'h2 a', :text => 'subversion_test'
  211. assert_select 'h2 a', :text => 'helloworld.c'
  212. end
  213. def test_entry_should_show_other_if_too_big
  214. assert_equal 0, @repository.changesets.count
  215. @repository.fetch_changesets
  216. @project.reload
  217. assert_equal NUM_REV, @repository.changesets.count
  218. # no files in the test repo is larger than 1KB...
  219. with_settings :file_max_size_displayed => 0 do
  220. get(
  221. :entry,
  222. :params => {
  223. :id => PRJ_ID,
  224. :repository_id => @repository.id,
  225. :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
  226. }
  227. )
  228. assert_response :success
  229. assert_equal 'text/html', @response.media_type
  230. assert_select 'p.nodata'
  231. end
  232. end
  233. def test_entry_should_display_images
  234. get(
  235. :entry,
  236. :params => {
  237. :id => PRJ_ID,
  238. :repository_id => @repository.id,
  239. :path => repository_path_hash(['subversion_test', 'folder', 'subfolder', 'rubylogo.gif'])[:param]
  240. }
  241. )
  242. assert_response :success
  243. assert_select 'img[src=?]', "/projects/subproject1/repository/#{@repository.id}/raw/subversion_test/folder/subfolder/rubylogo.gif"
  244. end
  245. def test_entry_should_preview_audio
  246. get(
  247. :entry,
  248. :params => {
  249. :id => PRJ_ID,
  250. :repository_id => @repository.id,
  251. :path => repository_path_hash(['subversion_test', 'folder', 'subfolder', 'chords.mp3'])[:param]
  252. }
  253. )
  254. assert_response :success
  255. assert_select 'audio[src=?]', "/projects/subproject1/repository/#{@repository.id}/raw/subversion_test/folder/subfolder/chords.mp3"
  256. end
  257. def text_entry_should_preview_markdown
  258. get(
  259. :entry,
  260. :params => {
  261. :id => PRJ_ID,
  262. :repository_id => @repository.id,
  263. :path => repository_path_hash(['subversion_test', 'folder', 'subfolder', 'testfile.md'])[:param]
  264. }
  265. )
  266. assert_response :success
  267. assert_select 'div.wiki', :html => "<h1>Header 1</h1>\n\n<h2>Header 2</h2>\n\n<h3>Header 3</h3>"
  268. end
  269. def text_entry_should_preview_textile
  270. get(
  271. :entry,
  272. :params => {
  273. :id => PRJ_ID,
  274. :repository_id => @repository.id,
  275. :path => repository_path_hash(['subversion_test', 'folder', 'subfolder', 'testfile.textile'])[:param]
  276. }
  277. )
  278. assert_response :success
  279. assert_select 'div.wiki', :html => "<h1>Header 1</h1>\n\n\n\t<h2>Header 2</h2>\n\n\n\t<h3>Header 3</h3>"
  280. end
  281. def test_entry_at_given_revision
  282. assert_equal 0, @repository.changesets.count
  283. @repository.fetch_changesets
  284. @project.reload
  285. assert_equal NUM_REV, @repository.changesets.count
  286. get(
  287. :entry,
  288. :params => {
  289. :id => PRJ_ID,
  290. :repository_id => @repository.id,
  291. :path => repository_path_hash(['subversion_test', 'helloworld.rb'])[:param],
  292. :rev => 2
  293. }
  294. )
  295. assert_response :success
  296. # this line was removed in r3 and file was moved in r6
  297. assert_select 'td.line-code', :text => /Here's the code/
  298. end
  299. def test_entry_not_found
  300. assert_equal 0, @repository.changesets.count
  301. @repository.fetch_changesets
  302. @project.reload
  303. assert_equal NUM_REV, @repository.changesets.count
  304. get(
  305. :entry,
  306. :params => {
  307. :id => PRJ_ID,
  308. :repository_id => @repository.id,
  309. :path => repository_path_hash(['subversion_test', 'zzz.c'])[:param]
  310. }
  311. )
  312. assert_select 'p#errorExplanation', :text => /The entry or revision was not found in the repository/
  313. end
  314. def test_entry_download
  315. assert_equal 0, @repository.changesets.count
  316. @repository.fetch_changesets
  317. @project.reload
  318. assert_equal NUM_REV, @repository.changesets.count
  319. get(
  320. :raw,
  321. :params => {
  322. :id => PRJ_ID,
  323. :repository_id => @repository.id,
  324. :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
  325. }
  326. )
  327. assert_response :success
  328. assert_equal "attachment; filename=\"helloworld.c\"; filename*=UTF-8''helloworld.c", @response.headers['Content-Disposition']
  329. end
  330. def test_directory_entry
  331. assert_equal 0, @repository.changesets.count
  332. @repository.fetch_changesets
  333. @project.reload
  334. assert_equal NUM_REV, @repository.changesets.count
  335. get(
  336. :entry,
  337. :params => {
  338. :id => PRJ_ID,
  339. :repository_id => @repository.id,
  340. :path => repository_path_hash(['subversion_test', 'folder'])[:param]
  341. }
  342. )
  343. assert_response :success
  344. assert_select 'h2 a', :text => 'subversion_test'
  345. assert_select 'h2 a', :text => 'folder'
  346. end
  347. # TODO: this test needs fixtures.
  348. def test_revision
  349. get(
  350. :revision,
  351. :params => {
  352. :id => 1,
  353. :repository_id => 10,
  354. :rev => 2
  355. }
  356. )
  357. assert_response :success
  358. assert_select 'ul' do
  359. assert_select 'li' do
  360. # link to the entry at rev 2
  361. assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/2/entry/test/some/path/in/the/repo', :text => 'repo'
  362. # link to partial diff
  363. assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/2/diff/test/some/path/in/the/repo'
  364. end
  365. end
  366. end
  367. def test_invalid_revision
  368. assert_equal 0, @repository.changesets.count
  369. @repository.fetch_changesets
  370. @project.reload
  371. assert_equal NUM_REV, @repository.changesets.count
  372. get(
  373. :revision,
  374. :params => {
  375. :id => PRJ_ID,
  376. :repository_id => @repository.id,
  377. :rev => 'something_weird'
  378. }
  379. )
  380. assert_response 404
  381. assert_select_error /was not found/
  382. end
  383. def test_invalid_revision_diff
  384. get(
  385. :diff,
  386. :params => {
  387. :id => PRJ_ID,
  388. :repository_id => @repository.id,
  389. :rev => '1',
  390. :rev_to => 'something_weird'
  391. }
  392. )
  393. assert_response 404
  394. assert_select_error /was not found/
  395. end
  396. def test_empty_revision
  397. assert_equal 0, @repository.changesets.count
  398. @repository.fetch_changesets
  399. @project.reload
  400. assert_equal NUM_REV, @repository.changesets.count
  401. ['', ' ', nil].each do |r|
  402. get(
  403. :revision,
  404. :params => {
  405. :id => PRJ_ID,
  406. :repository_id => @repository.id,
  407. :rev => r
  408. }
  409. )
  410. assert_response 404
  411. assert_select_error /was not found/
  412. end
  413. end
  414. # TODO: this test needs fixtures.
  415. def test_revision_with_repository_pointing_to_a_subdirectory
  416. r = Project.find(1).repository
  417. # Changes repository url to a subdirectory
  418. r.update_attribute :url, (r.url + '/test/some')
  419. get(
  420. :revision,
  421. :params => {
  422. :id => 1,
  423. :repository_id => 10,
  424. :rev => 2
  425. }
  426. )
  427. assert_response :success
  428. assert_select 'ul' do
  429. assert_select 'li' do
  430. # link to the entry at rev 2
  431. assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/2/entry/path/in/the/repo', :text => 'repo'
  432. # link to partial diff
  433. assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/2/diff/path/in/the/repo'
  434. end
  435. end
  436. end
  437. def test_revision_diff
  438. assert_equal 0, @repository.changesets.count
  439. @repository.fetch_changesets
  440. @project.reload
  441. assert_equal NUM_REV, @repository.changesets.count
  442. ['inline', 'sbs'].each do |dt|
  443. get(
  444. :diff,
  445. :params => {
  446. :id => PRJ_ID,
  447. :repository_id => @repository.id,
  448. :rev => 3,
  449. :type => dt
  450. }
  451. )
  452. assert_response :success
  453. assert_select 'h2', :text => /Revision 3/
  454. assert_select 'th.filename', :text => 'subversion_test/textfile.txt'
  455. end
  456. end
  457. def test_revision_diff_raw_format
  458. assert_equal 0, @repository.changesets.count
  459. @repository.fetch_changesets
  460. @project.reload
  461. assert_equal NUM_REV, @repository.changesets.count
  462. get(
  463. :diff,
  464. :params => {
  465. :id => PRJ_ID,
  466. :repository_id => @repository.id,
  467. :rev => 5,
  468. :format => 'diff'
  469. }
  470. )
  471. assert_response :success
  472. assert_equal 'text/x-patch', @response.media_type
  473. assert_equal 'Index: subversion_test/folder/greeter.rb', @response.body.split(/\r?\n/).first
  474. end
  475. def test_directory_diff
  476. assert_equal 0, @repository.changesets.count
  477. @repository.fetch_changesets
  478. @project.reload
  479. assert_equal NUM_REV, @repository.changesets.count
  480. ['inline', 'sbs'].each do |dt|
  481. get(
  482. :diff,
  483. :params => {
  484. :id => PRJ_ID,
  485. :repository_id => @repository.id,
  486. :rev => 6,
  487. :rev_to => 2,
  488. :path => repository_path_hash(['subversion_test', 'folder'])[:param],
  489. :type => dt
  490. }
  491. )
  492. assert_response :success
  493. assert_select 'h2', :text => /2:6/
  494. # 2 files modified
  495. assert_select 'table.filecontent', 2
  496. assert_select 'table.filecontent thead th.filename', :text => 'greeter.rb'
  497. assert_select 'table.filecontent thead th.filename', :text => 'helloworld.rb'
  498. end
  499. end
  500. def test_annotate
  501. assert_equal 0, @repository.changesets.count
  502. @repository.fetch_changesets
  503. @project.reload
  504. assert_equal NUM_REV, @repository.changesets.count
  505. get(
  506. :annotate,
  507. :params => {
  508. :id => PRJ_ID,
  509. :repository_id => @repository.id,
  510. :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
  511. }
  512. )
  513. assert_response :success
  514. assert_select 'tr' do
  515. assert_select 'th.line-num a[data-txt=?]', '1'
  516. assert_select 'td.revision', :text => '4'
  517. assert_select 'td.author', :text => 'jp'
  518. assert_select 'td', :text => /stdio.h/
  519. end
  520. # Same revision
  521. assert_select 'tr' do
  522. assert_select 'th.line-num a[data-txt=?]', '2'
  523. assert_select 'td.revision', :text => ''
  524. assert_select 'td.author', :text => ''
  525. end
  526. end
  527. def test_annotate_at_given_revision
  528. assert_equal 0, @repository.changesets.count
  529. @repository.fetch_changesets
  530. @project.reload
  531. assert_equal NUM_REV, @repository.changesets.count
  532. get(
  533. :annotate,
  534. :params => {
  535. :id => PRJ_ID,
  536. :repository_id => @repository.id,
  537. :rev => 8,
  538. :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
  539. }
  540. )
  541. assert_response :success
  542. assert_select 'h2', :text => /@ 8/
  543. end
  544. def test_destroy_valid_repository
  545. @request.session[:user_id] = 1 # admin
  546. assert_equal 0, @repository.changesets.count
  547. @repository.fetch_changesets
  548. assert_equal NUM_REV, @repository.changesets.count
  549. assert_difference 'Repository.count', -1 do
  550. delete(:destroy, :params => {:id => @repository.id})
  551. end
  552. assert_response 302
  553. @project.reload
  554. assert_nil @project.repository
  555. end
  556. def test_destroy_invalid_repository
  557. @request.session[:user_id] = 1 # admin
  558. @project.repository.destroy
  559. @repository =
  560. Repository::Subversion.
  561. create!(
  562. :project => @project,
  563. :url => "file:///invalid"
  564. )
  565. @repository.fetch_changesets
  566. assert_equal 0, @repository.changesets.count
  567. assert_difference 'Repository.count', -1 do
  568. delete(:destroy, :params => {:id => @repository.id})
  569. end
  570. assert_response 302
  571. @project.reload
  572. assert_nil @project.repository
  573. end
  574. else
  575. puts "Subversion test repository NOT FOUND. Skipping functional tests !!!"
  576. def test_fake; assert true end
  577. end
  578. end