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.

issues_controller_test.rb 163KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466
  1. # Redmine - project management software
  2. # Copyright (C) 2006-2015 Jean-Philippe Lang
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. require File.expand_path('../../test_helper', __FILE__)
  18. class IssuesControllerTest < ActionController::TestCase
  19. fixtures :projects,
  20. :users, :email_addresses,
  21. :roles,
  22. :members,
  23. :member_roles,
  24. :issues,
  25. :issue_statuses,
  26. :issue_relations,
  27. :versions,
  28. :trackers,
  29. :projects_trackers,
  30. :issue_categories,
  31. :enabled_modules,
  32. :enumerations,
  33. :attachments,
  34. :workflows,
  35. :custom_fields,
  36. :custom_values,
  37. :custom_fields_projects,
  38. :custom_fields_trackers,
  39. :time_entries,
  40. :journals,
  41. :journal_details,
  42. :queries,
  43. :repositories,
  44. :changesets
  45. include Redmine::I18n
  46. def setup
  47. User.current = nil
  48. end
  49. def test_index
  50. with_settings :default_language => "en" do
  51. get :index
  52. assert_response :success
  53. assert_template 'index'
  54. assert_not_nil assigns(:issues)
  55. assert_nil assigns(:project)
  56. # links to visible issues
  57. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  58. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  59. # private projects hidden
  60. assert_select 'a[href="/issues/6"]', 0
  61. assert_select 'a[href="/issues/4"]', 0
  62. # project column
  63. assert_select 'th', :text => /Project/
  64. end
  65. end
  66. def test_index_should_not_list_issues_when_module_disabled
  67. EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
  68. get :index
  69. assert_response :success
  70. assert_template 'index'
  71. assert_not_nil assigns(:issues)
  72. assert_nil assigns(:project)
  73. assert_select 'a[href="/issues/1"]', 0
  74. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  75. end
  76. def test_index_should_list_visible_issues_only
  77. get :index, :per_page => 100
  78. assert_response :success
  79. assert_not_nil assigns(:issues)
  80. assert_nil assigns(:issues).detect {|issue| !issue.visible?}
  81. end
  82. def test_index_with_project
  83. Setting.display_subprojects_issues = 0
  84. get :index, :project_id => 1
  85. assert_response :success
  86. assert_template 'index'
  87. assert_not_nil assigns(:issues)
  88. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  89. assert_select 'a[href="/issues/5"]', 0
  90. end
  91. def test_index_with_project_and_subprojects
  92. Setting.display_subprojects_issues = 1
  93. get :index, :project_id => 1
  94. assert_response :success
  95. assert_template 'index'
  96. assert_not_nil assigns(:issues)
  97. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  98. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  99. assert_select 'a[href="/issues/6"]', 0
  100. end
  101. def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
  102. @request.session[:user_id] = 2
  103. Setting.display_subprojects_issues = 1
  104. get :index, :project_id => 1
  105. assert_response :success
  106. assert_template 'index'
  107. assert_not_nil assigns(:issues)
  108. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  109. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  110. assert_select 'a[href="/issues/6"]', :text => /Issue of a private subproject/
  111. end
  112. def test_index_with_project_and_default_filter
  113. get :index, :project_id => 1, :set_filter => 1
  114. assert_response :success
  115. assert_template 'index'
  116. assert_not_nil assigns(:issues)
  117. query = assigns(:query)
  118. assert_not_nil query
  119. # default filter
  120. assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
  121. end
  122. def test_index_with_project_and_filter
  123. get :index, :project_id => 1, :set_filter => 1,
  124. :f => ['tracker_id'],
  125. :op => {'tracker_id' => '='},
  126. :v => {'tracker_id' => ['1']}
  127. assert_response :success
  128. assert_template 'index'
  129. assert_not_nil assigns(:issues)
  130. query = assigns(:query)
  131. assert_not_nil query
  132. assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
  133. end
  134. def test_index_with_short_filters
  135. to_test = {
  136. 'status_id' => {
  137. 'o' => { :op => 'o', :values => [''] },
  138. 'c' => { :op => 'c', :values => [''] },
  139. '7' => { :op => '=', :values => ['7'] },
  140. '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
  141. '=7' => { :op => '=', :values => ['7'] },
  142. '!3' => { :op => '!', :values => ['3'] },
  143. '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
  144. 'subject' => {
  145. 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
  146. 'o' => { :op => '=', :values => ['o'] },
  147. '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
  148. '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
  149. 'tracker_id' => {
  150. '3' => { :op => '=', :values => ['3'] },
  151. '=3' => { :op => '=', :values => ['3'] }},
  152. 'start_date' => {
  153. '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
  154. '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
  155. '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
  156. '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
  157. '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
  158. '<t+2' => { :op => '<t+', :values => ['2'] },
  159. '>t+2' => { :op => '>t+', :values => ['2'] },
  160. 't+2' => { :op => 't+', :values => ['2'] },
  161. 't' => { :op => 't', :values => [''] },
  162. 'w' => { :op => 'w', :values => [''] },
  163. '>t-2' => { :op => '>t-', :values => ['2'] },
  164. '<t-2' => { :op => '<t-', :values => ['2'] },
  165. 't-2' => { :op => 't-', :values => ['2'] }},
  166. 'created_on' => {
  167. '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
  168. '<t-2' => { :op => '<t-', :values => ['2'] },
  169. '>t-2' => { :op => '>t-', :values => ['2'] },
  170. 't-2' => { :op => 't-', :values => ['2'] }},
  171. 'cf_1' => {
  172. 'c' => { :op => '=', :values => ['c'] },
  173. '!c' => { :op => '!', :values => ['c'] },
  174. '!*' => { :op => '!*', :values => [''] },
  175. '*' => { :op => '*', :values => [''] }},
  176. 'estimated_hours' => {
  177. '=13.4' => { :op => '=', :values => ['13.4'] },
  178. '>=45' => { :op => '>=', :values => ['45'] },
  179. '<=125' => { :op => '<=', :values => ['125'] },
  180. '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
  181. '!*' => { :op => '!*', :values => [''] },
  182. '*' => { :op => '*', :values => [''] }}
  183. }
  184. default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
  185. to_test.each do |field, expression_and_expected|
  186. expression_and_expected.each do |filter_expression, expected|
  187. get :index, :set_filter => 1, field => filter_expression
  188. assert_response :success
  189. assert_template 'index'
  190. assert_not_nil assigns(:issues)
  191. query = assigns(:query)
  192. assert_not_nil query
  193. assert query.has_filter?(field)
  194. assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
  195. end
  196. end
  197. end
  198. def test_index_with_project_and_empty_filters
  199. get :index, :project_id => 1, :set_filter => 1, :fields => ['']
  200. assert_response :success
  201. assert_template 'index'
  202. assert_not_nil assigns(:issues)
  203. query = assigns(:query)
  204. assert_not_nil query
  205. # no filter
  206. assert_equal({}, query.filters)
  207. end
  208. def test_index_with_project_custom_field_filter
  209. field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
  210. CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
  211. CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
  212. filter_name = "project.cf_#{field.id}"
  213. @request.session[:user_id] = 1
  214. get :index, :set_filter => 1,
  215. :f => [filter_name],
  216. :op => {filter_name => '='},
  217. :v => {filter_name => ['Foo']}
  218. assert_response :success
  219. assert_template 'index'
  220. assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
  221. end
  222. def test_index_with_query
  223. get :index, :project_id => 1, :query_id => 5
  224. assert_response :success
  225. assert_template 'index'
  226. assert_not_nil assigns(:issues)
  227. assert_nil assigns(:issue_count_by_group)
  228. end
  229. def test_index_with_query_grouped_by_tracker
  230. get :index, :project_id => 1, :query_id => 6
  231. assert_response :success
  232. assert_template 'index'
  233. assert_not_nil assigns(:issues)
  234. assert_not_nil assigns(:issue_count_by_group)
  235. end
  236. def test_index_with_query_grouped_and_sorted_by_category
  237. get :index, :project_id => 1, :set_filter => 1, :group_by => "category", :sort => "category"
  238. assert_response :success
  239. assert_template 'index'
  240. assert_not_nil assigns(:issues)
  241. assert_not_nil assigns(:issue_count_by_group)
  242. end
  243. def test_index_with_query_grouped_by_list_custom_field
  244. get :index, :project_id => 1, :query_id => 9
  245. assert_response :success
  246. assert_template 'index'
  247. assert_not_nil assigns(:issues)
  248. assert_not_nil assigns(:issue_count_by_group)
  249. end
  250. def test_index_with_query_grouped_by_user_custom_field
  251. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  252. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  253. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  254. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  255. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  256. get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
  257. assert_response :success
  258. assert_select 'tr.group', 3
  259. assert_select 'tr.group' do
  260. assert_select 'a', :text => 'John Smith'
  261. assert_select 'span.count', :text => '1'
  262. end
  263. assert_select 'tr.group' do
  264. assert_select 'a', :text => 'Dave Lopper'
  265. assert_select 'span.count', :text => '2'
  266. end
  267. end
  268. def test_index_grouped_by_boolean_custom_field_should_distinguish_blank_and_false_values
  269. cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool')
  270. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '1')
  271. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
  272. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '')
  273. with_settings :default_language => 'en' do
  274. get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
  275. assert_response :success
  276. end
  277. assert_select 'tr.group', 3
  278. assert_select 'tr.group', :text => /Yes/
  279. assert_select 'tr.group', :text => /No/
  280. assert_select 'tr.group', :text => /blank/
  281. end
  282. def test_index_grouped_by_boolean_custom_field_with_false_group_in_first_position_should_show_the_group
  283. cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool', :is_filter => true)
  284. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '0')
  285. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
  286. with_settings :default_language => 'en' do
  287. get :index, :project_id => 1, :set_filter => 1, "cf_#{cf.id}" => "*", :group_by => "cf_#{cf.id}"
  288. assert_response :success
  289. assert_equal [1, 2], assigns(:issues).map(&:id).sort
  290. end
  291. assert_select 'tr.group', 1
  292. assert_select 'tr.group', :text => /No/
  293. end
  294. def test_index_with_query_grouped_by_tracker_in_normal_order
  295. 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
  296. get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
  297. assert_response :success
  298. trackers = assigns(:issues).map(&:tracker).uniq
  299. assert_equal [1, 2, 3], trackers.map(&:id)
  300. end
  301. def test_index_with_query_grouped_by_tracker_in_reverse_order
  302. 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
  303. get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
  304. assert_response :success
  305. trackers = assigns(:issues).map(&:tracker).uniq
  306. assert_equal [3, 2, 1], trackers.map(&:id)
  307. end
  308. def test_index_with_query_id_and_project_id_should_set_session_query
  309. get :index, :project_id => 1, :query_id => 4
  310. assert_response :success
  311. assert_kind_of Hash, session[:query]
  312. assert_equal 4, session[:query][:id]
  313. assert_equal 1, session[:query][:project_id]
  314. end
  315. def test_index_with_invalid_query_id_should_respond_404
  316. get :index, :project_id => 1, :query_id => 999
  317. assert_response 404
  318. end
  319. def test_index_with_cross_project_query_in_session_should_show_project_issues
  320. q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
  321. @request.session[:query] = {:id => q.id, :project_id => 1}
  322. with_settings :display_subprojects_issues => '0' do
  323. get :index, :project_id => 1
  324. end
  325. assert_response :success
  326. assert_not_nil assigns(:query)
  327. assert_equal q.id, assigns(:query).id
  328. assert_equal 1, assigns(:query).project_id
  329. assert_equal [1], assigns(:issues).map(&:project_id).uniq
  330. end
  331. def test_private_query_should_not_be_available_to_other_users
  332. q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
  333. @request.session[:user_id] = 3
  334. get :index, :query_id => q.id
  335. assert_response 403
  336. end
  337. def test_private_query_should_be_available_to_its_user
  338. q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
  339. @request.session[:user_id] = 2
  340. get :index, :query_id => q.id
  341. assert_response :success
  342. end
  343. def test_public_query_should_be_available_to_other_users
  344. q = IssueQuery.create!(:name => "public", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
  345. @request.session[:user_id] = 3
  346. get :index, :query_id => q.id
  347. assert_response :success
  348. end
  349. def test_index_should_omit_page_param_in_export_links
  350. get :index, :page => 2
  351. assert_response :success
  352. assert_select 'a.atom[href="/issues.atom"]'
  353. assert_select 'a.csv[href="/issues.csv"]'
  354. assert_select 'a.pdf[href="/issues.pdf"]'
  355. assert_select 'form#csv-export-form[action="/issues.csv"]'
  356. end
  357. def test_index_should_not_warn_when_not_exceeding_export_limit
  358. with_settings :issues_export_limit => 200 do
  359. get :index
  360. assert_select '#csv-export-options p.icon-warning', 0
  361. end
  362. end
  363. def test_index_should_warn_when_exceeding_export_limit
  364. with_settings :issues_export_limit => 2 do
  365. get :index
  366. assert_select '#csv-export-options p.icon-warning', :text => %r{limit: 2}
  367. end
  368. end
  369. def test_index_csv
  370. get :index, :format => 'csv'
  371. assert_response :success
  372. assert_not_nil assigns(:issues)
  373. assert_equal 'text/csv; header=present', @response.content_type
  374. assert @response.body.starts_with?("#,")
  375. lines = @response.body.chomp.split("\n")
  376. assert_equal assigns(:query).columns.size, lines[0].split(',').size
  377. end
  378. def test_index_csv_with_project
  379. get :index, :project_id => 1, :format => 'csv'
  380. assert_response :success
  381. assert_not_nil assigns(:issues)
  382. assert_equal 'text/csv; header=present', @response.content_type
  383. end
  384. def test_index_csv_with_description
  385. Issue.generate!(:description => 'test_index_csv_with_description')
  386. with_settings :default_language => 'en' do
  387. get :index, :format => 'csv', :csv => {:description => '1'}
  388. assert_response :success
  389. assert_not_nil assigns(:issues)
  390. end
  391. assert_equal 'text/csv; header=present', response.content_type
  392. headers = response.body.chomp.split("\n").first.split(',')
  393. assert_include 'Description', headers
  394. assert_include 'test_index_csv_with_description', response.body
  395. end
  396. def test_index_csv_with_spent_time_column
  397. issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
  398. TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
  399. get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
  400. assert_response :success
  401. assert_equal 'text/csv; header=present', @response.content_type
  402. lines = @response.body.chomp.split("\n")
  403. assert_include "#{issue.id},#{issue.subject},7.33", lines
  404. end
  405. def test_index_csv_with_all_columns
  406. get :index, :format => 'csv', :csv => {:columns => 'all'}
  407. assert_response :success
  408. assert_not_nil assigns(:issues)
  409. assert_equal 'text/csv; header=present', @response.content_type
  410. assert_match /\A#,/, response.body
  411. lines = response.body.chomp.split("\n")
  412. assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
  413. end
  414. def test_index_csv_with_multi_column_field
  415. CustomField.find(1).update_attribute :multiple, true
  416. issue = Issue.find(1)
  417. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  418. issue.save!
  419. get :index, :format => 'csv', :csv => {:columns => 'all'}
  420. assert_response :success
  421. lines = @response.body.chomp.split("\n")
  422. assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
  423. end
  424. def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
  425. field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
  426. issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
  427. with_settings :default_language => 'fr' do
  428. get :index, :format => 'csv', :csv => {:columns => 'all'}
  429. assert_response :success
  430. issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
  431. assert_include '185,60', issue_line
  432. end
  433. with_settings :default_language => 'en' do
  434. get :index, :format => 'csv', :csv => {:columns => 'all'}
  435. assert_response :success
  436. issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
  437. assert_include '185.60', issue_line
  438. end
  439. end
  440. def test_index_csv_should_fill_parent_column_with_parent_id
  441. Issue.delete_all
  442. parent = Issue.generate!
  443. child = Issue.generate!(:parent_issue_id => parent.id)
  444. with_settings :default_language => 'en' do
  445. get :index, :format => 'csv', :c => %w(parent)
  446. end
  447. lines = response.body.split("\n")
  448. assert_include "#{child.id},#{parent.id}", lines
  449. end
  450. def test_index_csv_big_5
  451. with_settings :default_language => "zh-TW" do
  452. str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8')
  453. str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5')
  454. issue = Issue.generate!(:subject => str_utf8)
  455. get :index, :project_id => 1,
  456. :f => ['subject'],
  457. :op => '=', :values => [str_utf8],
  458. :format => 'csv'
  459. assert_equal 'text/csv; header=present', @response.content_type
  460. lines = @response.body.chomp.split("\n")
  461. header = lines[0]
  462. status = "\xaa\xac\xbaA".force_encoding('Big5')
  463. assert_include status, header
  464. issue_line = lines.find {|l| l =~ /^#{issue.id},/}
  465. assert_include str_big5, issue_line
  466. end
  467. end
  468. def test_index_csv_cannot_convert_should_be_replaced_big_5
  469. with_settings :default_language => "zh-TW" do
  470. str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8')
  471. issue = Issue.generate!(:subject => str_utf8)
  472. get :index, :project_id => 1,
  473. :f => ['subject'],
  474. :op => '=', :values => [str_utf8],
  475. :c => ['status', 'subject'],
  476. :format => 'csv',
  477. :set_filter => 1
  478. assert_equal 'text/csv; header=present', @response.content_type
  479. lines = @response.body.chomp.split("\n")
  480. header = lines[0]
  481. issue_line = lines.find {|l| l =~ /^#{issue.id},/}
  482. s1 = "\xaa\xac\xbaA".force_encoding('Big5') # status
  483. assert header.include?(s1)
  484. s2 = issue_line.split(",")[2]
  485. s3 = "\xa5H?".force_encoding('Big5') # subject
  486. assert_equal s3, s2
  487. end
  488. end
  489. def test_index_csv_tw
  490. with_settings :default_language => "zh-TW" do
  491. str1 = "test_index_csv_tw"
  492. issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
  493. get :index, :project_id => 1,
  494. :f => ['subject'],
  495. :op => '=', :values => [str1],
  496. :c => ['estimated_hours', 'subject'],
  497. :format => 'csv',
  498. :set_filter => 1
  499. assert_equal 'text/csv; header=present', @response.content_type
  500. lines = @response.body.chomp.split("\n")
  501. assert_include "#{issue.id},1234.50,#{str1}", lines
  502. end
  503. end
  504. def test_index_csv_fr
  505. with_settings :default_language => "fr" do
  506. str1 = "test_index_csv_fr"
  507. issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
  508. get :index, :project_id => 1,
  509. :f => ['subject'],
  510. :op => '=', :values => [str1],
  511. :c => ['estimated_hours', 'subject'],
  512. :format => 'csv',
  513. :set_filter => 1
  514. assert_equal 'text/csv; header=present', @response.content_type
  515. lines = @response.body.chomp.split("\n")
  516. assert_include "#{issue.id};1234,50;#{str1}", lines
  517. end
  518. end
  519. def test_index_pdf
  520. ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
  521. with_settings :default_language => lang do
  522. get :index
  523. assert_response :success
  524. assert_template 'index'
  525. get :index, :format => 'pdf'
  526. assert_response :success
  527. assert_not_nil assigns(:issues)
  528. assert_equal 'application/pdf', @response.content_type
  529. get :index, :project_id => 1, :format => 'pdf'
  530. assert_response :success
  531. assert_not_nil assigns(:issues)
  532. assert_equal 'application/pdf', @response.content_type
  533. get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
  534. assert_response :success
  535. assert_not_nil assigns(:issues)
  536. assert_equal 'application/pdf', @response.content_type
  537. end
  538. end
  539. end
  540. def test_index_pdf_with_query_grouped_by_list_custom_field
  541. get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
  542. assert_response :success
  543. assert_not_nil assigns(:issues)
  544. assert_not_nil assigns(:issue_count_by_group)
  545. assert_equal 'application/pdf', @response.content_type
  546. end
  547. def test_index_atom
  548. get :index, :project_id => 'ecookbook', :format => 'atom'
  549. assert_response :success
  550. assert_template 'common/feed'
  551. assert_equal 'application/atom+xml', response.content_type
  552. assert_select 'feed' do
  553. assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
  554. assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
  555. assert_select 'entry link[href=?]', 'http://test.host/issues/1'
  556. end
  557. end
  558. def test_index_sort
  559. get :index, :sort => 'tracker,id:desc'
  560. assert_response :success
  561. sort_params = @request.session['issues_index_sort']
  562. assert sort_params.is_a?(String)
  563. assert_equal 'tracker,id:desc', sort_params
  564. issues = assigns(:issues)
  565. assert_not_nil issues
  566. assert !issues.empty?
  567. assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
  568. assert_select 'table.issues.sort-by-tracker.sort-asc'
  569. end
  570. def test_index_sort_by_field_not_included_in_columns
  571. Setting.issue_list_default_columns = %w(subject author)
  572. get :index, :sort => 'tracker'
  573. end
  574. def test_index_sort_by_assigned_to
  575. get :index, :sort => 'assigned_to'
  576. assert_response :success
  577. assignees = assigns(:issues).collect(&:assigned_to).compact
  578. assert_equal assignees.sort, assignees
  579. assert_select 'table.issues.sort-by-assigned-to.sort-asc'
  580. end
  581. def test_index_sort_by_assigned_to_desc
  582. get :index, :sort => 'assigned_to:desc'
  583. assert_response :success
  584. assignees = assigns(:issues).collect(&:assigned_to).compact
  585. assert_equal assignees.sort.reverse, assignees
  586. assert_select 'table.issues.sort-by-assigned-to.sort-desc'
  587. end
  588. def test_index_group_by_assigned_to
  589. get :index, :group_by => 'assigned_to', :sort => 'priority'
  590. assert_response :success
  591. end
  592. def test_index_sort_by_author
  593. get :index, :sort => 'author'
  594. assert_response :success
  595. authors = assigns(:issues).collect(&:author)
  596. assert_equal authors.sort, authors
  597. end
  598. def test_index_sort_by_author_desc
  599. get :index, :sort => 'author:desc'
  600. assert_response :success
  601. authors = assigns(:issues).collect(&:author)
  602. assert_equal authors.sort.reverse, authors
  603. end
  604. def test_index_group_by_author
  605. get :index, :group_by => 'author', :sort => 'priority'
  606. assert_response :success
  607. end
  608. def test_index_sort_by_spent_hours
  609. get :index, :sort => 'spent_hours:desc'
  610. assert_response :success
  611. hours = assigns(:issues).collect(&:spent_hours)
  612. assert_equal hours.sort.reverse, hours
  613. end
  614. def test_index_sort_by_total_spent_hours
  615. get :index, :sort => 'total_spent_hours:desc'
  616. assert_response :success
  617. hours = assigns(:issues).collect(&:total_spent_hours)
  618. assert_equal hours.sort.reverse, hours
  619. end
  620. def test_index_sort_by_total_estimated_hours
  621. get :index, :sort => 'total_estimated_hours:desc'
  622. assert_response :success
  623. hours = assigns(:issues).collect(&:total_estimated_hours)
  624. assert_equal hours.sort.reverse, hours
  625. end
  626. def test_index_sort_by_user_custom_field
  627. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  628. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  629. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  630. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  631. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  632. get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
  633. assert_response :success
  634. assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
  635. end
  636. def test_index_with_columns
  637. columns = ['tracker', 'subject', 'assigned_to']
  638. get :index, :set_filter => 1, :c => columns
  639. assert_response :success
  640. # query should use specified columns
  641. query = assigns(:query)
  642. assert_kind_of IssueQuery, query
  643. assert_equal columns, query.column_names.map(&:to_s)
  644. # columns should be stored in session
  645. assert_kind_of Hash, session[:query]
  646. assert_kind_of Array, session[:query][:column_names]
  647. assert_equal columns, session[:query][:column_names].map(&:to_s)
  648. # ensure only these columns are kept in the selected columns list
  649. assert_select 'select#selected_columns option' do
  650. assert_select 'option', 3
  651. assert_select 'option[value=tracker]'
  652. assert_select 'option[value=project]', 0
  653. end
  654. end
  655. def test_index_without_project_should_implicitly_add_project_column_to_default_columns
  656. Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
  657. get :index, :set_filter => 1
  658. # query should use specified columns
  659. query = assigns(:query)
  660. assert_kind_of IssueQuery, query
  661. assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
  662. end
  663. def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
  664. Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
  665. columns = ['id', 'tracker', 'subject', 'assigned_to']
  666. get :index, :set_filter => 1, :c => columns
  667. # query should use specified columns
  668. query = assigns(:query)
  669. assert_kind_of IssueQuery, query
  670. assert_equal columns.map(&:to_sym), query.columns.map(&:name)
  671. end
  672. def test_index_with_default_columns_should_respect_default_columns_order
  673. columns = ['assigned_to', 'subject', 'status', 'tracker']
  674. with_settings :issue_list_default_columns => columns do
  675. get :index, :project_id => 1, :set_filter => 1
  676. query = assigns(:query)
  677. assert_equal (['id'] + columns).map(&:to_sym), query.columns.map(&:name)
  678. end
  679. end
  680. def test_index_with_custom_field_column
  681. columns = %w(tracker subject cf_2)
  682. get :index, :set_filter => 1, :c => columns
  683. assert_response :success
  684. # query should use specified columns
  685. query = assigns(:query)
  686. assert_kind_of IssueQuery, query
  687. assert_equal columns, query.column_names.map(&:to_s)
  688. assert_select 'table.issues td.cf_2.string'
  689. end
  690. def test_index_with_multi_custom_field_column
  691. field = CustomField.find(1)
  692. field.update_attribute :multiple, true
  693. issue = Issue.find(1)
  694. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  695. issue.save!
  696. get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
  697. assert_response :success
  698. assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
  699. end
  700. def test_index_with_multi_user_custom_field_column
  701. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  702. :tracker_ids => [1], :is_for_all => true)
  703. issue = Issue.find(1)
  704. issue.custom_field_values = {field.id => ['2', '3']}
  705. issue.save!
  706. get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
  707. assert_response :success
  708. assert_select "table.issues td.cf_#{field.id}" do
  709. assert_select 'a', 2
  710. assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
  711. assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
  712. end
  713. end
  714. def test_index_with_date_column
  715. with_settings :date_format => '%d/%m/%Y' do
  716. Issue.find(1).update_attribute :start_date, '1987-08-24'
  717. get :index, :set_filter => 1, :c => %w(start_date)
  718. assert_select "table.issues td.start_date", :text => '24/08/1987'
  719. end
  720. end
  721. def test_index_with_done_ratio_column
  722. Issue.find(1).update_attribute :done_ratio, 40
  723. get :index, :set_filter => 1, :c => %w(done_ratio)
  724. assert_select 'table.issues td.done_ratio' do
  725. assert_select 'table.progress' do
  726. assert_select 'td.closed[style=?]', 'width: 40%;'
  727. end
  728. end
  729. end
  730. def test_index_with_spent_hours_column
  731. Issue.expects(:load_visible_spent_hours).once
  732. get :index, :set_filter => 1, :c => %w(subject spent_hours)
  733. assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
  734. end
  735. def test_index_with_total_spent_hours_column
  736. Issue.expects(:load_visible_total_spent_hours).once
  737. get :index, :set_filter => 1, :c => %w(subject total_spent_hours)
  738. assert_select 'table.issues tr#issue-3 td.total_spent_hours', :text => '1.00'
  739. end
  740. def test_index_with_total_estimated_hours_column
  741. get :index, :set_filter => 1, :c => %w(subject total_estimated_hours)
  742. assert_select 'table.issues td.total_estimated_hours'
  743. end
  744. def test_index_should_not_show_spent_hours_column_without_permission
  745. Role.anonymous.remove_permission! :view_time_entries
  746. get :index, :set_filter => 1, :c => %w(subject spent_hours)
  747. assert_select 'td.spent_hours', 0
  748. end
  749. def test_index_with_fixed_version_column
  750. get :index, :set_filter => 1, :c => %w(fixed_version)
  751. assert_select 'table.issues td.fixed_version' do
  752. assert_select 'a[href=?]', '/versions/2', :text => 'eCookbook - 1.0'
  753. end
  754. end
  755. def test_index_with_relations_column
  756. IssueRelation.delete_all
  757. IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
  758. IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
  759. IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
  760. IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
  761. get :index, :set_filter => 1, :c => %w(subject relations)
  762. assert_response :success
  763. assert_select "tr#issue-1 td.relations" do
  764. assert_select "span", 3
  765. assert_select "span", :text => "Related to #7"
  766. assert_select "span", :text => "Related to #8"
  767. assert_select "span", :text => "Blocks #11"
  768. end
  769. assert_select "tr#issue-2 td.relations" do
  770. assert_select "span", 1
  771. assert_select "span", :text => "Blocked by #12"
  772. end
  773. assert_select "tr#issue-3 td.relations" do
  774. assert_select "span", 0
  775. end
  776. get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
  777. assert_response :success
  778. assert_equal 'text/csv; header=present', response.content_type
  779. lines = response.body.chomp.split("\n")
  780. assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
  781. assert_include '2,Blocked by #12', lines
  782. assert_include '3,""', lines
  783. get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
  784. assert_response :success
  785. assert_equal 'application/pdf', response.content_type
  786. end
  787. def test_index_with_description_column
  788. get :index, :set_filter => 1, :c => %w(subject description)
  789. assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
  790. assert_select 'td.description[colspan="3"]', :text => 'Unable to print recipes'
  791. get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
  792. assert_response :success
  793. assert_equal 'application/pdf', response.content_type
  794. end
  795. def test_index_with_parent_column
  796. Issue.delete_all
  797. parent = Issue.generate!
  798. child = Issue.generate!(:parent_issue_id => parent.id)
  799. get :index, :c => %w(parent)
  800. assert_select 'td.parent', :text => "#{parent.tracker} ##{parent.id}"
  801. assert_select 'td.parent a[title=?]', parent.subject
  802. end
  803. def test_index_with_estimated_hours_total
  804. Issue.delete_all
  805. Issue.generate!(:estimated_hours => 5.5)
  806. Issue.generate!(:estimated_hours => 1.1)
  807. get :index, :t => %w(estimated_hours)
  808. assert_response :success
  809. assert_select '.query-totals'
  810. assert_select '.total-for-estimated-hours span.value', :text => '6.60'
  811. assert_select 'input[type=checkbox][name=?][value=estimated_hours][checked=checked]', 't[]'
  812. end
  813. def test_index_with_grouped_query_and_estimated_hours_total
  814. Issue.delete_all
  815. Issue.generate!(:estimated_hours => 5.5, :category_id => 1)
  816. Issue.generate!(:estimated_hours => 2.3, :category_id => 1)
  817. Issue.generate!(:estimated_hours => 1.1, :category_id => 2)
  818. Issue.generate!(:estimated_hours => 4.6)
  819. get :index, :t => %w(estimated_hours), :group_by => 'category'
  820. assert_response :success
  821. assert_select '.query-totals'
  822. assert_select '.query-totals .total-for-estimated-hours span.value', :text => '13.50'
  823. assert_select 'tr.group', :text => /Printing/ do
  824. assert_select '.total-for-estimated-hours span.value', :text => '7.80'
  825. end
  826. assert_select 'tr.group', :text => /Recipes/ do
  827. assert_select '.total-for-estimated-hours span.value', :text => '1.10'
  828. end
  829. assert_select 'tr.group', :text => /blank/ do
  830. assert_select '.total-for-estimated-hours span.value', :text => '4.60'
  831. end
  832. end
  833. def test_index_with_int_custom_field_total
  834. field = IssueCustomField.generate!(:field_format => 'int', :is_for_all => true)
  835. CustomValue.create!(:customized => Issue.find(1), :custom_field => field, :value => '2')
  836. CustomValue.create!(:customized => Issue.find(2), :custom_field => field, :value => '7')
  837. get :index, :t => ["cf_#{field.id}"]
  838. assert_response :success
  839. assert_select '.query-totals'
  840. assert_select ".total-for-cf-#{field.id} span.value", :text => '9'
  841. end
  842. def test_index_totals_should_default_to_settings
  843. with_settings :issue_list_default_totals => ['estimated_hours'] do
  844. get :index
  845. assert_response :success
  846. assert_select '.total-for-estimated-hours span.value'
  847. assert_select '.query-totals>span', 1
  848. end
  849. end
  850. def test_index_send_html_if_query_is_invalid
  851. get :index, :f => ['start_date'], :op => {:start_date => '='}
  852. assert_equal 'text/html', @response.content_type
  853. assert_template 'index'
  854. end
  855. def test_index_send_nothing_if_query_is_invalid
  856. get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
  857. assert_equal 'text/csv', @response.content_type
  858. assert @response.body.blank?
  859. end
  860. def test_show_by_anonymous
  861. get :show, :id => 1
  862. assert_response :success
  863. assert_template 'show'
  864. assert_equal Issue.find(1), assigns(:issue)
  865. assert_select 'div.issue div.description', :text => /Unable to print recipes/
  866. # anonymous role is allowed to add a note
  867. assert_select 'form#issue-form' do
  868. assert_select 'fieldset' do
  869. assert_select 'legend', :text => 'Notes'
  870. assert_select 'textarea[name=?]', 'issue[notes]'
  871. end
  872. end
  873. assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
  874. end
  875. def test_show_by_manager
  876. @request.session[:user_id] = 2
  877. get :show, :id => 1
  878. assert_response :success
  879. assert_select 'a', :text => /Quote/
  880. assert_select 'form#issue-form' do
  881. assert_select 'fieldset' do
  882. assert_select 'legend', :text => 'Change properties'
  883. assert_select 'input[name=?]', 'issue[subject]'
  884. end
  885. assert_select 'fieldset' do
  886. assert_select 'legend', :text => 'Log time'
  887. assert_select 'input[name=?]', 'time_entry[hours]'
  888. end
  889. assert_select 'fieldset' do
  890. assert_select 'legend', :text => 'Notes'
  891. assert_select 'textarea[name=?]', 'issue[notes]'
  892. end
  893. end
  894. end
  895. def test_show_should_display_update_form
  896. @request.session[:user_id] = 2
  897. get :show, :id => 1
  898. assert_response :success
  899. assert_select 'form#issue-form' do
  900. assert_select 'input[name=?]', 'issue[is_private]'
  901. assert_select 'select[name=?]', 'issue[project_id]'
  902. assert_select 'select[name=?]', 'issue[tracker_id]'
  903. assert_select 'input[name=?]', 'issue[subject]'
  904. assert_select 'textarea[name=?]', 'issue[description]'
  905. assert_select 'select[name=?]', 'issue[status_id]'
  906. assert_select 'select[name=?]', 'issue[priority_id]'
  907. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  908. assert_select 'select[name=?]', 'issue[category_id]'
  909. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  910. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  911. assert_select 'input[name=?]', 'issue[start_date]'
  912. assert_select 'input[name=?]', 'issue[due_date]'
  913. assert_select 'select[name=?]', 'issue[done_ratio]'
  914. assert_select 'input[name=?]', 'issue[custom_field_values][2]'
  915. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  916. assert_select 'textarea[name=?]', 'issue[notes]'
  917. end
  918. end
  919. def test_show_should_display_update_form_with_minimal_permissions
  920. Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
  921. WorkflowTransition.delete_all :role_id => 1
  922. @request.session[:user_id] = 2
  923. get :show, :id => 1
  924. assert_response :success
  925. assert_select 'form#issue-form' do
  926. assert_select 'input[name=?]', 'issue[is_private]', 0
  927. assert_select 'select[name=?]', 'issue[project_id]', 0
  928. assert_select 'select[name=?]', 'issue[tracker_id]', 0
  929. assert_select 'input[name=?]', 'issue[subject]', 0
  930. assert_select 'textarea[name=?]', 'issue[description]', 0
  931. assert_select 'select[name=?]', 'issue[status_id]', 0
  932. assert_select 'select[name=?]', 'issue[priority_id]', 0
  933. assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
  934. assert_select 'select[name=?]', 'issue[category_id]', 0
  935. assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
  936. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  937. assert_select 'input[name=?]', 'issue[start_date]', 0
  938. assert_select 'input[name=?]', 'issue[due_date]', 0
  939. assert_select 'select[name=?]', 'issue[done_ratio]', 0
  940. assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
  941. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  942. assert_select 'textarea[name=?]', 'issue[notes]'
  943. end
  944. end
  945. def test_show_should_not_display_update_form_without_permissions
  946. Role.find(1).update_attribute :permissions, [:view_issues]
  947. @request.session[:user_id] = 2
  948. get :show, :id => 1
  949. assert_response :success
  950. assert_select 'form#issue-form', 0
  951. end
  952. def test_update_form_should_not_display_inactive_enumerations
  953. assert !IssuePriority.find(15).active?
  954. @request.session[:user_id] = 2
  955. get :show, :id => 1
  956. assert_response :success
  957. assert_select 'form#issue-form' do
  958. assert_select 'select[name=?]', 'issue[priority_id]' do
  959. assert_select 'option[value="4"]'
  960. assert_select 'option[value="15"]', 0
  961. end
  962. end
  963. end
  964. def test_update_form_should_allow_attachment_upload
  965. @request.session[:user_id] = 2
  966. get :show, :id => 1
  967. assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
  968. assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
  969. end
  970. end
  971. def test_show_should_deny_anonymous_access_without_permission
  972. Role.anonymous.remove_permission!(:view_issues)
  973. get :show, :id => 1
  974. assert_response :redirect
  975. end
  976. def test_show_should_deny_anonymous_access_to_private_issue
  977. Issue.where(:id => 1).update_all(["is_private = ?", true])
  978. get :show, :id => 1
  979. assert_response :redirect
  980. end
  981. def test_show_should_deny_non_member_access_without_permission
  982. Role.non_member.remove_permission!(:view_issues)
  983. @request.session[:user_id] = 9
  984. get :show, :id => 1
  985. assert_response 403
  986. end
  987. def test_show_should_deny_non_member_access_to_private_issue
  988. Issue.where(:id => 1).update_all(["is_private = ?", true])
  989. @request.session[:user_id] = 9
  990. get :show, :id => 1
  991. assert_response 403
  992. end
  993. def test_show_should_deny_member_access_without_permission
  994. Role.find(1).remove_permission!(:view_issues)
  995. @request.session[:user_id] = 2
  996. get :show, :id => 1
  997. assert_response 403
  998. end
  999. def test_show_should_deny_member_access_to_private_issue_without_permission
  1000. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1001. @request.session[:user_id] = 3
  1002. get :show, :id => 1
  1003. assert_response 403
  1004. end
  1005. def test_show_should_allow_author_access_to_private_issue
  1006. Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
  1007. @request.session[:user_id] = 3
  1008. get :show, :id => 1
  1009. assert_response :success
  1010. end
  1011. def test_show_should_allow_assignee_access_to_private_issue
  1012. Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
  1013. @request.session[:user_id] = 3
  1014. get :show, :id => 1
  1015. assert_response :success
  1016. end
  1017. def test_show_should_allow_member_access_to_private_issue_with_permission
  1018. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1019. User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
  1020. @request.session[:user_id] = 3
  1021. get :show, :id => 1
  1022. assert_response :success
  1023. end
  1024. def test_show_should_not_disclose_relations_to_invisible_issues
  1025. Setting.cross_project_issue_relations = '1'
  1026. IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
  1027. # Relation to a private project issue
  1028. IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
  1029. get :show, :id => 1
  1030. assert_response :success
  1031. assert_select 'div#relations' do
  1032. assert_select 'a', :text => /#2$/
  1033. assert_select 'a', :text => /#4$/, :count => 0
  1034. end
  1035. end
  1036. def test_show_should_list_subtasks
  1037. Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
  1038. get :show, :id => 1
  1039. assert_response :success
  1040. assert_select 'div#issue_tree' do
  1041. assert_select 'td.subject', :text => /Child Issue/
  1042. end
  1043. end
  1044. def test_show_should_list_parents
  1045. issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
  1046. get :show, :id => issue.id
  1047. assert_response :success
  1048. assert_select 'div.subject' do
  1049. assert_select 'h3', 'Child Issue'
  1050. assert_select 'a[href="/issues/1"]'
  1051. end
  1052. end
  1053. def test_show_should_not_display_prev_next_links_without_query_in_session
  1054. get :show, :id => 1
  1055. assert_response :success
  1056. assert_nil assigns(:prev_issue_id)
  1057. assert_nil assigns(:next_issue_id)
  1058. assert_select 'div.next-prev-links', 0
  1059. end
  1060. def test_show_should_display_prev_next_links_with_query_in_session
  1061. @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
  1062. @request.session['issues_index_sort'] = 'id'
  1063. with_settings :display_subprojects_issues => '0' do
  1064. get :show, :id => 3
  1065. end
  1066. assert_response :success
  1067. # Previous and next issues for all projects
  1068. assert_equal 2, assigns(:prev_issue_id)
  1069. assert_equal 5, assigns(:next_issue_id)
  1070. count = Issue.open.visible.count
  1071. assert_select 'div.next-prev-links' do
  1072. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1073. assert_select 'a[href="/issues/5"]', :text => /Next/
  1074. assert_select 'span.position', :text => "3 of #{count}"
  1075. end
  1076. end
  1077. def test_show_should_display_prev_next_links_with_saved_query_in_session
  1078. query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
  1079. :filters => {'status_id' => {:values => ['5'], :operator => '='}},
  1080. :sort_criteria => [['id', 'asc']])
  1081. @request.session[:query] = {:id => query.id, :project_id => nil}
  1082. get :show, :id => 11
  1083. assert_response :success
  1084. assert_equal query, assigns(:query)
  1085. # Previous and next issues for all projects
  1086. assert_equal 8, assigns(:prev_issue_id)
  1087. assert_equal 12, assigns(:next_issue_id)
  1088. assert_select 'div.next-prev-links' do
  1089. assert_select 'a[href="/issues/8"]', :text => /Previous/
  1090. assert_select 'a[href="/issues/12"]', :text => /Next/
  1091. end
  1092. end
  1093. def test_show_should_display_prev_next_links_with_query_and_sort_on_association
  1094. @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
  1095. %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
  1096. @request.session['issues_index_sort'] = assoc_sort
  1097. get :show, :id => 3
  1098. assert_response :success, "Wrong response status for #{assoc_sort} sort"
  1099. assert_select 'div.next-prev-links' do
  1100. assert_select 'a', :text => /(Previous|Next)/
  1101. end
  1102. end
  1103. end
  1104. def test_show_should_display_prev_next_links_with_project_query_in_session
  1105. @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
  1106. @request.session['issues_index_sort'] = 'id'
  1107. with_settings :display_subprojects_issues => '0' do
  1108. get :show, :id => 3
  1109. end
  1110. assert_response :success
  1111. # Previous and next issues inside project
  1112. assert_equal 2, assigns(:prev_issue_id)
  1113. assert_equal 7, assigns(:next_issue_id)
  1114. assert_select 'div.next-prev-links' do
  1115. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1116. assert_select 'a[href="/issues/7"]', :text => /Next/
  1117. end
  1118. end
  1119. def test_show_should_not_display_prev_link_for_first_issue
  1120. @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
  1121. @request.session['issues_index_sort'] = 'id'
  1122. with_settings :display_subprojects_issues => '0' do
  1123. get :show, :id => 1
  1124. end
  1125. assert_response :success
  1126. assert_nil assigns(:prev_issue_id)
  1127. assert_equal 2, assigns(:next_issue_id)
  1128. assert_select 'div.next-prev-links' do
  1129. assert_select 'a', :text => /Previous/, :count => 0
  1130. assert_select 'a[href="/issues/2"]', :text => /Next/
  1131. end
  1132. end
  1133. def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
  1134. @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
  1135. @request.session['issues_index_sort'] = 'id'
  1136. get :show, :id => 1
  1137. assert_response :success
  1138. assert_nil assigns(:prev_issue_id)
  1139. assert_nil assigns(:next_issue_id)
  1140. assert_select 'a', :text => /Previous/, :count => 0
  1141. assert_select 'a', :text => /Next/, :count => 0
  1142. end
  1143. def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
  1144. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  1145. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  1146. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  1147. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  1148. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  1149. query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
  1150. :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
  1151. @request.session[:query] = {:id => query.id, :project_id => nil}
  1152. get :show, :id => 3
  1153. assert_response :success
  1154. assert_equal 2, assigns(:prev_issue_id)
  1155. assert_equal 1, assigns(:next_issue_id)
  1156. assert_select 'div.next-prev-links' do
  1157. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1158. assert_select 'a[href="/issues/1"]', :text => /Next/
  1159. end
  1160. end
  1161. def test_show_should_display_category_field_if_categories_are_defined
  1162. Issue.update_all :category_id => nil
  1163. get :show, :id => 1
  1164. assert_response :success
  1165. assert_select '.attributes .category'
  1166. end
  1167. def test_show_should_not_display_category_field_if_no_categories_are_defined
  1168. Project.find(1).issue_categories.delete_all
  1169. get :show, :id => 1
  1170. assert_response :success
  1171. assert_select 'table.attributes .category', 0
  1172. end
  1173. def test_show_should_display_link_to_the_assignee
  1174. get :show, :id => 2
  1175. assert_response :success
  1176. assert_select '.assigned-to' do
  1177. assert_select 'a[href="/users/3"]'
  1178. end
  1179. end
  1180. def test_show_should_display_visible_changesets_from_other_projects
  1181. project = Project.find(2)
  1182. issue = project.issues.first
  1183. issue.changeset_ids = [102]
  1184. issue.save!
  1185. # changesets from other projects should be displayed even if repository
  1186. # is disabled on issue's project
  1187. project.disable_module! :repository
  1188. @request.session[:user_id] = 2
  1189. get :show, :id => issue.id
  1190. assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
  1191. end
  1192. def test_show_should_display_watchers
  1193. @request.session[:user_id] = 2
  1194. Issue.find(1).add_watcher User.find(2)
  1195. get :show, :id => 1
  1196. assert_select 'div#watchers ul' do
  1197. assert_select 'li' do
  1198. assert_select 'a[href="/users/2"]'
  1199. assert_select 'a img[alt=Delete]'
  1200. end
  1201. end
  1202. end
  1203. def test_show_should_display_watchers_with_gravatars
  1204. @request.session[:user_id] = 2
  1205. Issue.find(1).add_watcher User.find(2)
  1206. with_settings :gravatar_enabled => '1' do
  1207. get :show, :id => 1
  1208. end
  1209. assert_select 'div#watchers ul' do
  1210. assert_select 'li' do
  1211. assert_select 'img.gravatar'
  1212. assert_select 'a[href="/users/2"]'
  1213. assert_select 'a img[alt=Delete]'
  1214. end
  1215. end
  1216. end
  1217. def test_show_with_thumbnails_enabled_should_display_thumbnails
  1218. @request.session[:user_id] = 2
  1219. with_settings :thumbnails_enabled => '1' do
  1220. get :show, :id => 14
  1221. assert_response :success
  1222. end
  1223. assert_select 'div.thumbnails' do
  1224. assert_select 'a[href="/attachments/16/testfile.png"]' do
  1225. assert_select 'img[src="/attachments/thumbnail/16"]'
  1226. end
  1227. end
  1228. end
  1229. def test_show_with_thumbnails_disabled_should_not_display_thumbnails
  1230. @request.session[:user_id] = 2
  1231. with_settings :thumbnails_enabled => '0' do
  1232. get :show, :id => 14
  1233. assert_response :success
  1234. end
  1235. assert_select 'div.thumbnails', 0
  1236. end
  1237. def test_show_with_multi_custom_field
  1238. field = CustomField.find(1)
  1239. field.update_attribute :multiple, true
  1240. issue = Issue.find(1)
  1241. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  1242. issue.save!
  1243. get :show, :id => 1
  1244. assert_response :success
  1245. assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
  1246. end
  1247. def test_show_with_multi_user_custom_field
  1248. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  1249. :tracker_ids => [1], :is_for_all => true)
  1250. issue = Issue.find(1)
  1251. issue.custom_field_values = {field.id => ['2', '3']}
  1252. issue.save!
  1253. get :show, :id => 1
  1254. assert_response :success
  1255. assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
  1256. assert_select 'a', :text => 'Dave Lopper'
  1257. assert_select 'a', :text => 'John Smith'
  1258. end
  1259. end
  1260. def test_show_should_display_private_notes_with_permission_only
  1261. journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
  1262. @request.session[:user_id] = 2
  1263. get :show, :id => 2
  1264. assert_response :success
  1265. assert_include journal, assigns(:journals)
  1266. Role.find(1).remove_permission! :view_private_notes
  1267. get :show, :id => 2
  1268. assert_response :success
  1269. assert_not_include journal, assigns(:journals)
  1270. end
  1271. def test_show_atom
  1272. get :show, :id => 2, :format => 'atom'
  1273. assert_response :success
  1274. assert_template 'journals/index'
  1275. # Inline image
  1276. assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
  1277. end
  1278. def test_show_export_to_pdf
  1279. issue = Issue.find(3)
  1280. assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
  1281. get :show, :id => 3, :format => 'pdf'
  1282. assert_response :success
  1283. assert_equal 'application/pdf', @response.content_type
  1284. assert @response.body.starts_with?('%PDF')
  1285. assert_not_nil assigns(:issue)
  1286. end
  1287. def test_export_to_pdf_with_utf8_u_fffd
  1288. # U+FFFD
  1289. s = "\xef\xbf\xbd"
  1290. s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
  1291. issue = Issue.generate!(:subject => s)
  1292. ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
  1293. with_settings :default_language => lang do
  1294. get :show, :id => issue.id, :format => 'pdf'
  1295. assert_response :success
  1296. assert_equal 'application/pdf', @response.content_type
  1297. assert @response.body.starts_with?('%PDF')
  1298. assert_not_nil assigns(:issue)
  1299. end
  1300. end
  1301. end
  1302. def test_show_export_to_pdf_with_ancestors
  1303. issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  1304. get :show, :id => issue.id, :format => 'pdf'
  1305. assert_response :success
  1306. assert_equal 'application/pdf', @response.content_type
  1307. assert @response.body.starts_with?('%PDF')
  1308. end
  1309. def test_show_export_to_pdf_with_descendants
  1310. c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  1311. c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  1312. c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
  1313. get :show, :id => 1, :format => 'pdf'
  1314. assert_response :success
  1315. assert_equal 'application/pdf', @response.content_type
  1316. assert @response.body.starts_with?('%PDF')
  1317. end
  1318. def test_show_export_to_pdf_with_journals
  1319. get :show, :id => 1, :format => 'pdf'
  1320. assert_response :success
  1321. assert_equal 'application/pdf', @response.content_type
  1322. assert @response.body.starts_with?('%PDF')
  1323. end
  1324. def test_show_export_to_pdf_with_changesets
  1325. [[100], [100, 101], [100, 101, 102]].each do |cs|
  1326. issue1 = Issue.find(3)
  1327. issue1.changesets = Changeset.find(cs)
  1328. issue1.save!
  1329. issue = Issue.find(3)
  1330. assert_equal issue.changesets.count, cs.size
  1331. get :show, :id => 3, :format => 'pdf'
  1332. assert_response :success
  1333. assert_equal 'application/pdf', @response.content_type
  1334. assert @response.body.starts_with?('%PDF')
  1335. end
  1336. end
  1337. def test_show_invalid_should_respond_with_404
  1338. get :show, :id => 999
  1339. assert_response 404
  1340. end
  1341. def test_get_new
  1342. @request.session[:user_id] = 2
  1343. get :new, :project_id => 1, :tracker_id => 1
  1344. assert_response :success
  1345. assert_template 'new'
  1346. assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
  1347. assert_select 'form#issue-form' do
  1348. assert_select 'input[name=?]', 'issue[is_private]'
  1349. assert_select 'select[name=?]', 'issue[project_id]', 0
  1350. assert_select 'select[name=?]', 'issue[tracker_id]'
  1351. assert_select 'input[name=?]', 'issue[subject]'
  1352. assert_select 'textarea[name=?]', 'issue[description]'
  1353. assert_select 'select[name=?]', 'issue[status_id]'
  1354. assert_select 'select[name=?]', 'issue[priority_id]'
  1355. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  1356. assert_select 'select[name=?]', 'issue[category_id]'
  1357. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  1358. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  1359. assert_select 'input[name=?]', 'issue[start_date]'
  1360. assert_select 'input[name=?]', 'issue[due_date]'
  1361. assert_select 'select[name=?]', 'issue[done_ratio]'
  1362. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
  1363. assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
  1364. end
  1365. # Be sure we don't display inactive IssuePriorities
  1366. assert ! IssuePriority.find(15).active?
  1367. assert_select 'select[name=?]', 'issue[priority_id]' do
  1368. assert_select 'option[value="15"]', 0
  1369. end
  1370. end
  1371. def test_get_new_with_minimal_permissions
  1372. Role.find(1).update_attribute :permissions, [:add_issues]
  1373. WorkflowTransition.delete_all :role_id => 1
  1374. @request.session[:user_id] = 2
  1375. get :new, :project_id => 1, :tracker_id => 1
  1376. assert_response :success
  1377. assert_template 'new'
  1378. assert_select 'form#issue-form' do
  1379. assert_select 'input[name=?]', 'issue[is_private]', 0
  1380. assert_select 'select[name=?]', 'issue[project_id]', 0
  1381. assert_select 'select[name=?]', 'issue[tracker_id]'
  1382. assert_select 'input[name=?]', 'issue[subject]'
  1383. assert_select 'textarea[name=?]', 'issue[description]'
  1384. assert_select 'select[name=?]', 'issue[status_id]'
  1385. assert_select 'select[name=?]', 'issue[priority_id]'
  1386. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  1387. assert_select 'select[name=?]', 'issue[category_id]'
  1388. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  1389. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  1390. assert_select 'input[name=?]', 'issue[start_date]'
  1391. assert_select 'input[name=?]', 'issue[due_date]'
  1392. assert_select 'select[name=?]', 'issue[done_ratio]'
  1393. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
  1394. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  1395. end
  1396. end
  1397. def test_new_without_project_id
  1398. @request.session[:user_id] = 2
  1399. get :new
  1400. assert_response :success
  1401. assert_template 'new'
  1402. assert_select 'form#issue-form[action=?]', '/issues'
  1403. assert_select 'form#issue-form' do
  1404. assert_select 'select[name=?]', 'issue[project_id]'
  1405. end
  1406. assert_nil assigns(:project)
  1407. assert_not_nil assigns(:issue)
  1408. end
  1409. def test_new_should_select_default_status
  1410. @request.session[:user_id] = 2
  1411. get :new, :project_id => 1
  1412. assert_response :success
  1413. assert_template 'new'
  1414. assert_select 'select[name=?]', 'issue[status_id]' do
  1415. assert_select 'option[value="1"][selected=selected]'
  1416. end
  1417. assert_select 'input[name=was_default_status][value="1"]'
  1418. end
  1419. def test_new_should_propose_allowed_statuses
  1420. WorkflowTransition.delete_all
  1421. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
  1422. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
  1423. @request.session[:user_id] = 2
  1424. get :new, :project_id => 1
  1425. assert_response :success
  1426. assert_select 'select[name=?]', 'issue[status_id]' do
  1427. assert_select 'option[value="1"]'
  1428. assert_select 'option[value="3"]'
  1429. assert_select 'option', 2
  1430. assert_select 'option[value="1"][selected=selected]'
  1431. end
  1432. end
  1433. def test_new_should_propose_allowed_statuses_without_default_status_allowed
  1434. WorkflowTransition.delete_all
  1435. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
  1436. assert_equal 1, Tracker.find(1).default_status_id
  1437. @request.session[:user_id] = 2
  1438. get :new, :project_id => 1
  1439. assert_response :success
  1440. assert_select 'select[name=?]', 'issue[status_id]' do
  1441. assert_select 'option[value="2"]'
  1442. assert_select 'option', 1
  1443. assert_select 'option[value="2"][selected=selected]'
  1444. end
  1445. end
  1446. def test_new_should_preselect_default_version
  1447. version = Version.generate!(:project_id => 1)
  1448. Project.find(1).update_attribute :default_version_id, version.id
  1449. @request.session[:user_id] = 2
  1450. get :new, :project_id => 1
  1451. assert_response :success
  1452. assert_equal version, assigns(:issue).fixed_version
  1453. assert_select 'select[name=?]', 'issue[fixed_version_id]' do
  1454. assert_select 'option[value=?][selected=selected]', version.id.to_s
  1455. end
  1456. end
  1457. def test_get_new_with_list_custom_field
  1458. @request.session[:user_id] = 2
  1459. get :new, :project_id => 1, :tracker_id => 1
  1460. assert_response :success
  1461. assert_template 'new'
  1462. assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
  1463. assert_select 'option', 4
  1464. assert_select 'option[value=MySQL]', :text => 'MySQL'
  1465. end
  1466. end
  1467. def test_get_new_with_multi_custom_field
  1468. field = IssueCustomField.find(1)
  1469. field.update_attribute :multiple, true
  1470. @request.session[:user_id] = 2
  1471. get :new, :project_id => 1, :tracker_id => 1
  1472. assert_response :success
  1473. assert_template 'new'
  1474. assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
  1475. assert_select 'option', 3
  1476. assert_select 'option[value=MySQL]', :text => 'MySQL'
  1477. end
  1478. assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
  1479. end
  1480. def test_get_new_with_multi_user_custom_field
  1481. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  1482. :tracker_ids => [1], :is_for_all => true)
  1483. @request.session[:user_id] = 2
  1484. get :new, :project_id => 1, :tracker_id => 1
  1485. assert_response :success
  1486. assert_template 'new'
  1487. assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
  1488. assert_select 'option', Project.find(1).users.count
  1489. assert_select 'option[value="2"]', :text => 'John Smith'
  1490. end
  1491. assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
  1492. end
  1493. def test_get_new_with_date_custom_field
  1494. field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
  1495. @request.session[:user_id] = 2
  1496. get :new, :project_id => 1, :tracker_id => 1
  1497. assert_response :success
  1498. assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
  1499. end
  1500. def test_get_new_with_text_custom_field
  1501. field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
  1502. @request.session[:user_id] = 2
  1503. get :new, :project_id => 1, :tracker_id => 1
  1504. assert_response :success
  1505. assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
  1506. end
  1507. def test_get_new_without_default_start_date_is_creation_date
  1508. with_settings :default_issue_start_date_to_creation_date => 0 do
  1509. @request.session[:user_id] = 2
  1510. get :new, :project_id => 1, :tracker_id => 1
  1511. assert_response :success
  1512. assert_template 'new'
  1513. assert_select 'input[name=?]', 'issue[start_date]'
  1514. assert_select 'input[name=?][value]', 'issue[start_date]', 0
  1515. end
  1516. end
  1517. def test_get_new_with_default_start_date_is_creation_date
  1518. with_settings :default_issue_start_date_to_creation_date => 1 do
  1519. @request.session[:user_id] = 2
  1520. get :new, :project_id => 1, :tracker_id => 1
  1521. assert_response :success
  1522. assert_template 'new'
  1523. assert_select 'input[name=?][value=?]', 'issue[start_date]',
  1524. Date.today.to_s
  1525. end
  1526. end
  1527. def test_get_new_form_should_allow_attachment_upload
  1528. @request.session[:user_id] = 2
  1529. get :new, :project_id => 1, :tracker_id => 1
  1530. assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
  1531. assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
  1532. end
  1533. end
  1534. def test_get_new_should_prefill_the_form_from_params
  1535. @request.session[:user_id] = 2
  1536. get :new, :project_id => 1,
  1537. :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
  1538. issue = assigns(:issue)
  1539. assert_equal 3, issue.tracker_id
  1540. assert_equal 'Prefilled', issue.description
  1541. assert_equal 'Custom field value', issue.custom_field_value(2)
  1542. assert_select 'select[name=?]', 'issue[tracker_id]' do
  1543. assert_select 'option[value="3"][selected=selected]'
  1544. end
  1545. assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
  1546. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
  1547. end
  1548. def test_get_new_should_mark_required_fields
  1549. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1550. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1551. WorkflowPermission.delete_all
  1552. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
  1553. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  1554. @request.session[:user_id] = 2
  1555. get :new, :project_id => 1
  1556. assert_response :success
  1557. assert_template 'new'
  1558. assert_select 'label[for=issue_start_date]' do
  1559. assert_select 'span[class=required]', 0
  1560. end
  1561. assert_select 'label[for=issue_due_date]' do
  1562. assert_select 'span[class=required]'
  1563. end
  1564. assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
  1565. assert_select 'span[class=required]', 0
  1566. end
  1567. assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
  1568. assert_select 'span[class=required]'
  1569. end
  1570. end
  1571. def test_get_new_should_not_display_readonly_fields
  1572. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1573. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1574. WorkflowPermission.delete_all
  1575. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
  1576. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
  1577. @request.session[:user_id] = 2
  1578. get :new, :project_id => 1
  1579. assert_response :success
  1580. assert_template 'new'
  1581. assert_select 'input[name=?]', 'issue[start_date]'
  1582. assert_select 'input[name=?]', 'issue[due_date]', 0
  1583. assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
  1584. assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
  1585. end
  1586. def test_new_with_tracker_set_as_readonly_should_accept_status
  1587. WorkflowPermission.delete_all
  1588. [1, 2].each do |status_id|
  1589. WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
  1590. end
  1591. @request.session[:user_id] = 2
  1592. get :new, :project_id => 1, :issue => {:status_id => 2}
  1593. assert_select 'select[name=?]', 'issue[tracker_id]', 0
  1594. assert_equal 2, assigns(:issue).status_id
  1595. end
  1596. def test_get_new_without_tracker_id
  1597. @request.session[:user_id] = 2
  1598. get :new, :project_id => 1
  1599. assert_response :success
  1600. assert_template 'new'
  1601. issue = assigns(:issue)
  1602. assert_not_nil issue
  1603. assert_equal Project.find(1).trackers.first, issue.tracker
  1604. end
  1605. def test_get_new_with_no_default_status_should_display_an_error
  1606. @request.session[:user_id] = 2
  1607. IssueStatus.delete_all
  1608. get :new, :project_id => 1
  1609. assert_response 500
  1610. assert_select_error /No default issue/
  1611. end
  1612. def test_get_new_with_no_tracker_should_display_an_error
  1613. @request.session[:user_id] = 2
  1614. Tracker.delete_all
  1615. get :new, :project_id => 1
  1616. assert_response 500
  1617. assert_select_error /No tracker/
  1618. end
  1619. def test_new_with_invalid_project_id
  1620. @request.session[:user_id] = 1
  1621. get :new, :project_id => 'invalid'
  1622. assert_response 404
  1623. end
  1624. def test_update_form_for_new_issue
  1625. @request.session[:user_id] = 2
  1626. xhr :post, :new, :project_id => 1,
  1627. :issue => {:tracker_id => 2,
  1628. :subject => 'This is the test_new issue',
  1629. :description => 'This is the description',
  1630. :priority_id => 5}
  1631. assert_response :success
  1632. assert_template 'new'
  1633. assert_template :partial => '_form'
  1634. assert_equal 'text/javascript', response.content_type
  1635. issue = assigns(:issue)
  1636. assert_kind_of Issue, issue
  1637. assert_equal 1, issue.project_id
  1638. assert_equal 2, issue.tracker_id
  1639. assert_equal 'This is the test_new issue', issue.subject
  1640. end
  1641. def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
  1642. @request.session[:user_id] = 2
  1643. WorkflowTransition.delete_all
  1644. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
  1645. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
  1646. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
  1647. xhr :post, :new, :project_id => 1,
  1648. :issue => {:tracker_id => 1,
  1649. :status_id => 5,
  1650. :subject => 'This is an issue'}
  1651. assert_equal 5, assigns(:issue).status_id
  1652. assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
  1653. end
  1654. def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
  1655. @request.session[:user_id] = 2
  1656. tracker = Tracker.find(2)
  1657. tracker.update! :default_status_id => 2
  1658. tracker.generate_transitions! 2, 1, :clear => true
  1659. xhr :post, :new, :project_id => 1,
  1660. :issue => {:tracker_id => 2,
  1661. :status_id => 1},
  1662. :was_default_status => 1
  1663. assert_equal 2, assigns(:issue).status_id
  1664. end
  1665. def test_update_form_for_new_issue_should_ignore_version_when_changing_project
  1666. version = Version.generate!(:project_id => 1)
  1667. Project.find(1).update_attribute :default_version_id, version.id
  1668. @request.session[:user_id] = 2
  1669. xhr :post, :new, :issue => {:project_id => 1,
  1670. :fixed_version_id => ''},
  1671. :form_update_triggered_by => 'issue_project_id'
  1672. assert_response :success
  1673. assert_template 'new'
  1674. issue = assigns(:issue)
  1675. assert_equal 1, issue.project_id
  1676. assert_equal version, issue.fixed_version
  1677. end
  1678. def test_post_create
  1679. @request.session[:user_id] = 2
  1680. assert_difference 'Issue.count' do
  1681. assert_no_difference 'Journal.count' do
  1682. post :create, :project_id => 1,
  1683. :issue => {:tracker_id => 3,
  1684. :status_id => 2,
  1685. :subject => 'This is the test_new issue',
  1686. :description => 'This is the description',
  1687. :priority_id => 5,
  1688. :start_date => '2010-11-07',
  1689. :estimated_hours => '',
  1690. :custom_field_values => {'2' => 'Value for field 2'}}
  1691. end
  1692. end
  1693. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  1694. issue = Issue.find_by_subject('This is the test_new issue')
  1695. assert_not_nil issue
  1696. assert_equal 2, issue.author_id
  1697. assert_equal 3, issue.tracker_id
  1698. assert_equal 2, issue.status_id
  1699. assert_equal Date.parse('2010-11-07'), issue.start_date
  1700. assert_nil issue.estimated_hours
  1701. v = issue.custom_values.where(:custom_field_id => 2).first
  1702. assert_not_nil v
  1703. assert_equal 'Value for field 2', v.value
  1704. end
  1705. def test_post_new_with_group_assignment
  1706. group = Group.find(11)
  1707. project = Project.find(1)
  1708. project.members << Member.new(:principal => group, :roles => [Role.givable.first])
  1709. with_settings :issue_group_assignment => '1' do
  1710. @request.session[:user_id] = 2
  1711. assert_difference 'Issue.count' do
  1712. post :create, :project_id => project.id,
  1713. :issue => {:tracker_id => 3,
  1714. :status_id => 1,
  1715. :subject => 'This is the test_new_with_group_assignment issue',
  1716. :assigned_to_id => group.id}
  1717. end
  1718. end
  1719. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  1720. issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
  1721. assert_not_nil issue
  1722. assert_equal group, issue.assigned_to
  1723. end
  1724. def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
  1725. with_settings :default_issue_start_date_to_creation_date => 0 do
  1726. @request.session[:user_id] = 2
  1727. assert_difference 'Issue.count' do
  1728. post :create, :project_id => 1,
  1729. :issue => {:tracker_id => 3,
  1730. :status_id => 2,
  1731. :subject => 'This is the test_new issue',
  1732. :description => 'This is the description',
  1733. :priority_id => 5,
  1734. :estimated_hours => '',
  1735. :custom_field_values => {'2' => 'Value for field 2'}}
  1736. end
  1737. assert_redirected_to :controller => 'issues', :action => 'show',
  1738. :id => Issue.last.id
  1739. issue = Issue.find_by_subject('This is the test_new issue')
  1740. assert_not_nil issue
  1741. assert_nil issue.start_date
  1742. end
  1743. end
  1744. def test_post_create_without_start_date_and_default_start_date_is_creation_date
  1745. with_settings :default_issue_start_date_to_creation_date => 1 do
  1746. @request.session[:user_id] = 2
  1747. assert_difference 'Issue.count' do
  1748. post :create, :project_id => 1,
  1749. :issue => {:tracker_id => 3,
  1750. :status_id => 2,
  1751. :subject => 'This is the test_new issue',
  1752. :description => 'This is the description',
  1753. :priority_id => 5,
  1754. :estimated_hours => '',
  1755. :custom_field_values => {'2' => 'Value for field 2'}}
  1756. end
  1757. assert_redirected_to :controller => 'issues', :action => 'show',
  1758. :id => Issue.last.id
  1759. issue = Issue.find_by_subject('This is the test_new issue')
  1760. assert_not_nil issue
  1761. assert_equal Date.today, issue.start_date
  1762. end
  1763. end
  1764. def test_post_create_and_continue
  1765. @request.session[:user_id] = 2
  1766. assert_difference 'Issue.count' do
  1767. post :create, :project_id => 1,
  1768. :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
  1769. :continue => ''
  1770. end
  1771. issue = Issue.order('id DESC').first
  1772. assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
  1773. assert_not_nil flash[:notice], "flash was not set"
  1774. assert_select_in flash[:notice],
  1775. 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
  1776. end
  1777. def test_post_create_without_custom_fields_param
  1778. @request.session[:user_id] = 2
  1779. assert_difference 'Issue.count' do
  1780. post :create, :project_id => 1,
  1781. :issue => {:tracker_id => 1,
  1782. :subject => 'This is the test_new issue',
  1783. :description => 'This is the description',
  1784. :priority_id => 5}
  1785. end
  1786. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  1787. end
  1788. def test_post_create_with_multi_custom_field
  1789. field = IssueCustomField.find_by_name('Database')
  1790. field.update_attribute(:multiple, true)
  1791. @request.session[:user_id] = 2
  1792. assert_difference 'Issue.count' do
  1793. post :create, :project_id => 1,
  1794. :issue => {:tracker_id => 1,
  1795. :subject => 'This is the test_new issue',
  1796. :description => 'This is the description',
  1797. :priority_id => 5,
  1798. :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
  1799. end
  1800. assert_response 302
  1801. issue = Issue.order('id DESC').first
  1802. assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
  1803. end
  1804. def test_post_create_with_empty_multi_custom_field
  1805. field = IssueCustomField.find_by_name('Database')
  1806. field.update_attribute(:multiple, true)
  1807. @request.session[:user_id] = 2
  1808. assert_difference 'Issue.count' do
  1809. post :create, :project_id => 1,
  1810. :issue => {:tracker_id => 1,
  1811. :subject => 'This is the test_new issue',
  1812. :description => 'This is the description',
  1813. :priority_id => 5,
  1814. :custom_field_values => {'1' => ['']}}
  1815. end
  1816. assert_response 302
  1817. issue = Issue.order('id DESC').first
  1818. assert_equal [''], issue.custom_field_value(1).sort
  1819. end
  1820. def test_post_create_with_multi_user_custom_field
  1821. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  1822. :tracker_ids => [1], :is_for_all => true)
  1823. @request.session[:user_id] = 2
  1824. assert_difference 'Issue.count' do
  1825. post :create, :project_id => 1,
  1826. :issue => {:tracker_id => 1,
  1827. :subject => 'This is the test_new issue',
  1828. :description => 'This is the description',
  1829. :priority_id => 5,
  1830. :custom_field_values => {field.id.to_s => ['', '2', '3']}}
  1831. end
  1832. assert_response 302
  1833. issue = Issue.order('id DESC').first
  1834. assert_equal ['2', '3'], issue.custom_field_value(field).sort
  1835. end
  1836. def test_post_create_with_required_custom_field_and_without_custom_fields_param
  1837. field = IssueCustomField.find_by_name('Database')
  1838. field.update_attribute(:is_required, true)
  1839. @request.session[:user_id] = 2
  1840. assert_no_difference 'Issue.count' do
  1841. post :create, :project_id => 1,
  1842. :issue => {:tracker_id => 1,
  1843. :subject => 'This is the test_new issue',
  1844. :description => 'This is the description',
  1845. :priority_id => 5}
  1846. end
  1847. assert_response :success
  1848. assert_template 'new'
  1849. issue = assigns(:issue)
  1850. assert_not_nil issue
  1851. assert_select_error /Database cannot be blank/
  1852. end
  1853. def test_create_should_validate_required_fields
  1854. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1855. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1856. WorkflowPermission.delete_all
  1857. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
  1858. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  1859. @request.session[:user_id] = 2
  1860. assert_no_difference 'Issue.count' do
  1861. post :create, :project_id => 1, :issue => {
  1862. :tracker_id => 2,
  1863. :status_id => 1,
  1864. :subject => 'Test',
  1865. :start_date => '',
  1866. :due_date => '',
  1867. :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
  1868. }
  1869. assert_response :success
  1870. assert_template 'new'
  1871. end
  1872. assert_select_error /Due date cannot be blank/i
  1873. assert_select_error /Bar cannot be blank/i
  1874. end
  1875. def test_create_should_validate_required_list_fields
  1876. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
  1877. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
  1878. WorkflowPermission.delete_all
  1879. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
  1880. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  1881. @request.session[:user_id] = 2
  1882. assert_no_difference 'Issue.count' do
  1883. post :create, :project_id => 1, :issue => {
  1884. :tracker_id => 2,
  1885. :status_id => 1,
  1886. :subject => 'Test',
  1887. :start_date => '',
  1888. :due_date => '',
  1889. :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
  1890. }
  1891. assert_response :success
  1892. assert_template 'new'
  1893. end
  1894. assert_select_error /Foo cannot be blank/i
  1895. assert_select_error /Bar cannot be blank/i
  1896. end
  1897. def test_create_should_ignore_readonly_fields
  1898. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1899. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  1900. WorkflowPermission.delete_all
  1901. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
  1902. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
  1903. @request.session[:user_id] = 2
  1904. assert_difference 'Issue.count' do
  1905. post :create, :project_id => 1, :issue => {
  1906. :tracker_id => 2,
  1907. :status_id => 1,
  1908. :subject => 'Test',
  1909. :start_date => '2012-07-14',
  1910. :due_date => '2012-07-16',
  1911. :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
  1912. }
  1913. assert_response 302
  1914. end
  1915. issue = Issue.order('id DESC').first
  1916. assert_equal Date.parse('2012-07-14'), issue.start_date
  1917. assert_nil issue.due_date
  1918. assert_equal 'value1', issue.custom_field_value(cf1)
  1919. assert_nil issue.custom_field_value(cf2)
  1920. end
  1921. def test_post_create_with_watchers
  1922. @request.session[:user_id] = 2
  1923. ActionMailer::Base.deliveries.clear
  1924. with_settings :notified_events => %w(issue_added) do
  1925. assert_difference 'Watcher.count', 2 do
  1926. post :create, :project_id => 1,
  1927. :issue => {:tracker_id => 1,
  1928. :subject => 'This is a new issue with watchers',
  1929. :description => 'This is the description',
  1930. :priority_id => 5,
  1931. :watcher_user_ids => ['2', '3']}
  1932. end
  1933. end
  1934. issue = Issue.find_by_subject('This is a new issue with watchers')
  1935. assert_not_nil issue
  1936. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
  1937. # Watchers added
  1938. assert_equal [2, 3], issue.watcher_user_ids.sort
  1939. assert issue.watched_by?(User.find(3))
  1940. # Watchers notified
  1941. mail = ActionMailer::Base.deliveries.last
  1942. assert_not_nil mail
  1943. assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
  1944. end
  1945. def test_post_create_subissue
  1946. @request.session[:user_id] = 2
  1947. assert_difference 'Issue.count' do
  1948. post :create, :project_id => 1,
  1949. :issue => {:tracker_id => 1,
  1950. :subject => 'This is a child issue',
  1951. :parent_issue_id => '2'}
  1952. assert_response 302
  1953. end
  1954. issue = Issue.order('id DESC').first
  1955. assert_equal Issue.find(2), issue.parent
  1956. end
  1957. def test_post_create_subissue_with_sharp_parent_id
  1958. @request.session[:user_id] = 2
  1959. assert_difference 'Issue.count' do
  1960. post :create, :project_id => 1,
  1961. :issue => {:tracker_id => 1,
  1962. :subject => 'This is a child issue',
  1963. :parent_issue_id => '#2'}
  1964. assert_response 302
  1965. end
  1966. issue = Issue.order('id DESC').first
  1967. assert_equal Issue.find(2), issue.parent
  1968. end
  1969. def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
  1970. @request.session[:user_id] = 2
  1971. assert_no_difference 'Issue.count' do
  1972. post :create, :project_id => 1,
  1973. :issue => {:tracker_id => 1,
  1974. :subject => 'This is a child issue',
  1975. :parent_issue_id => '4'}
  1976. assert_response :success
  1977. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
  1978. assert_select_error /Parent task is invalid/i
  1979. end
  1980. end
  1981. def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
  1982. @request.session[:user_id] = 2
  1983. assert_no_difference 'Issue.count' do
  1984. post :create, :project_id => 1,
  1985. :issue => {:tracker_id => 1,
  1986. :subject => 'This is a child issue',
  1987. :parent_issue_id => '01ABC'}
  1988. assert_response :success
  1989. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
  1990. assert_select_error /Parent task is invalid/i
  1991. end
  1992. end
  1993. def test_post_create_private
  1994. @request.session[:user_id] = 2
  1995. assert_difference 'Issue.count' do
  1996. post :create, :project_id => 1,
  1997. :issue => {:tracker_id => 1,
  1998. :subject => 'This is a private issue',
  1999. :is_private => '1'}
  2000. end
  2001. issue = Issue.order('id DESC').first
  2002. assert issue.is_private?
  2003. end
  2004. def test_post_create_private_with_set_own_issues_private_permission
  2005. role = Role.find(1)
  2006. role.remove_permission! :set_issues_private
  2007. role.add_permission! :set_own_issues_private
  2008. @request.session[:user_id] = 2
  2009. assert_difference 'Issue.count' do
  2010. post :create, :project_id => 1,
  2011. :issue => {:tracker_id => 1,
  2012. :subject => 'This is a private issue',
  2013. :is_private => '1'}
  2014. end
  2015. issue = Issue.order('id DESC').first
  2016. assert issue.is_private?
  2017. end
  2018. def test_create_without_project_id
  2019. @request.session[:user_id] = 2
  2020. assert_difference 'Issue.count' do
  2021. post :create,
  2022. :issue => {:project_id => 3,
  2023. :tracker_id => 2,
  2024. :subject => 'Foo'}
  2025. assert_response 302
  2026. end
  2027. issue = Issue.order('id DESC').first
  2028. assert_equal 3, issue.project_id
  2029. assert_equal 2, issue.tracker_id
  2030. end
  2031. def test_create_without_project_id_and_continue_should_redirect_without_project_id
  2032. @request.session[:user_id] = 2
  2033. assert_difference 'Issue.count' do
  2034. post :create,
  2035. :issue => {:project_id => 3,
  2036. :tracker_id => 2,
  2037. :subject => 'Foo'},
  2038. :continue => '1'
  2039. assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
  2040. end
  2041. end
  2042. def test_create_without_project_id_should_be_denied_without_permission
  2043. Role.non_member.remove_permission! :add_issues
  2044. Role.anonymous.remove_permission! :add_issues
  2045. @request.session[:user_id] = 2
  2046. assert_no_difference 'Issue.count' do
  2047. post :create,
  2048. :issue => {:project_id => 3,
  2049. :tracker_id => 2,
  2050. :subject => 'Foo'}
  2051. assert_response 422
  2052. end
  2053. end
  2054. def test_create_without_project_id_with_failure
  2055. @request.session[:user_id] = 2
  2056. post :create,
  2057. :issue => {:project_id => 3,
  2058. :tracker_id => 2,
  2059. :subject => ''}
  2060. assert_response :success
  2061. assert_nil assigns(:project)
  2062. end
  2063. def test_post_create_should_send_a_notification
  2064. ActionMailer::Base.deliveries.clear
  2065. @request.session[:user_id] = 2
  2066. with_settings :notified_events => %w(issue_added) do
  2067. assert_difference 'Issue.count' do
  2068. post :create, :project_id => 1,
  2069. :issue => {:tracker_id => 3,
  2070. :subject => 'This is the test_new issue',
  2071. :description => 'This is the description',
  2072. :priority_id => 5,
  2073. :estimated_hours => '',
  2074. :custom_field_values => {'2' => 'Value for field 2'}}
  2075. end
  2076. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  2077. assert_equal 1, ActionMailer::Base.deliveries.size
  2078. end
  2079. end
  2080. def test_post_create_should_preserve_fields_values_on_validation_failure
  2081. @request.session[:user_id] = 2
  2082. post :create, :project_id => 1,
  2083. :issue => {:tracker_id => 1,
  2084. # empty subject
  2085. :subject => '',
  2086. :description => 'This is a description',
  2087. :priority_id => 6,
  2088. :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
  2089. assert_response :success
  2090. assert_template 'new'
  2091. assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
  2092. assert_select 'select[name=?]', 'issue[priority_id]' do
  2093. assert_select 'option[value="6"][selected=selected]', :text => 'High'
  2094. end
  2095. # Custom fields
  2096. assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
  2097. assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
  2098. end
  2099. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
  2100. end
  2101. def test_post_create_with_failure_should_preserve_watchers
  2102. assert !User.find(8).member_of?(Project.find(1))
  2103. @request.session[:user_id] = 2
  2104. post :create, :project_id => 1,
  2105. :issue => {:tracker_id => 1,
  2106. :watcher_user_ids => ['3', '8']}
  2107. assert_response :success
  2108. assert_template 'new'
  2109. assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
  2110. assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
  2111. assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
  2112. end
  2113. def test_post_create_should_ignore_non_safe_attributes
  2114. @request.session[:user_id] = 2
  2115. assert_nothing_raised do
  2116. post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
  2117. end
  2118. end
  2119. def test_post_create_with_attachment
  2120. set_tmp_attachments_directory
  2121. @request.session[:user_id] = 2
  2122. assert_difference 'Issue.count' do
  2123. assert_difference 'Attachment.count' do
  2124. assert_no_difference 'Journal.count' do
  2125. post :create, :project_id => 1,
  2126. :issue => { :tracker_id => '1', :subject => 'With attachment' },
  2127. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
  2128. end
  2129. end
  2130. end
  2131. issue = Issue.order('id DESC').first
  2132. attachment = Attachment.order('id DESC').first
  2133. assert_equal issue, attachment.container
  2134. assert_equal 2, attachment.author_id
  2135. assert_equal 'testfile.txt', attachment.filename
  2136. assert_equal 'text/plain', attachment.content_type
  2137. assert_equal 'test file', attachment.description
  2138. assert_equal 59, attachment.filesize
  2139. assert File.exists?(attachment.diskfile)
  2140. assert_equal 59, File.size(attachment.diskfile)
  2141. end
  2142. def test_post_create_with_attachment_should_notify_with_attachments
  2143. ActionMailer::Base.deliveries.clear
  2144. set_tmp_attachments_directory
  2145. @request.session[:user_id] = 2
  2146. with_settings :host_name => 'mydomain.foo', :protocol => 'http', :notified_events => %w(issue_added) do
  2147. assert_difference 'Issue.count' do
  2148. post :create, :project_id => 1,
  2149. :issue => { :tracker_id => '1', :subject => 'With attachment' },
  2150. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
  2151. end
  2152. end
  2153. assert_not_nil ActionMailer::Base.deliveries.last
  2154. assert_select_email do
  2155. assert_select 'a[href^=?]', 'http://mydomain.foo/attachments/download', 'testfile.txt'
  2156. end
  2157. end
  2158. def test_post_create_with_failure_should_save_attachments
  2159. set_tmp_attachments_directory
  2160. @request.session[:user_id] = 2
  2161. assert_no_difference 'Issue.count' do
  2162. assert_difference 'Attachment.count' do
  2163. post :create, :project_id => 1,
  2164. :issue => { :tracker_id => '1', :subject => '' },
  2165. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
  2166. assert_response :success
  2167. assert_template 'new'
  2168. end
  2169. end
  2170. attachment = Attachment.order('id DESC').first
  2171. assert_equal 'testfile.txt', attachment.filename
  2172. assert File.exists?(attachment.diskfile)
  2173. assert_nil attachment.container
  2174. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  2175. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  2176. end
  2177. def test_post_create_with_failure_should_keep_saved_attachments
  2178. set_tmp_attachments_directory
  2179. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  2180. @request.session[:user_id] = 2
  2181. assert_no_difference 'Issue.count' do
  2182. assert_no_difference 'Attachment.count' do
  2183. post :create, :project_id => 1,
  2184. :issue => { :tracker_id => '1', :subject => '' },
  2185. :attachments => {'p0' => {'token' => attachment.token}}
  2186. assert_response :success
  2187. assert_template 'new'
  2188. end
  2189. end
  2190. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  2191. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  2192. end
  2193. def test_post_create_should_attach_saved_attachments
  2194. set_tmp_attachments_directory
  2195. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  2196. @request.session[:user_id] = 2
  2197. assert_difference 'Issue.count' do
  2198. assert_no_difference 'Attachment.count' do
  2199. post :create, :project_id => 1,
  2200. :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
  2201. :attachments => {'p0' => {'token' => attachment.token}}
  2202. assert_response 302
  2203. end
  2204. end
  2205. issue = Issue.order('id DESC').first
  2206. assert_equal 1, issue.attachments.count
  2207. attachment.reload
  2208. assert_equal issue, attachment.container
  2209. end
  2210. def setup_without_workflow_privilege
  2211. WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
  2212. Role.anonymous.add_permission! :add_issues, :add_issue_notes
  2213. end
  2214. private :setup_without_workflow_privilege
  2215. test "without workflow privilege #new should propose default status only" do
  2216. setup_without_workflow_privilege
  2217. get :new, :project_id => 1
  2218. assert_response :success
  2219. assert_template 'new'
  2220. issue = assigns(:issue)
  2221. assert_not_nil issue.default_status
  2222. assert_select 'select[name=?]', 'issue[status_id]' do
  2223. assert_select 'option', 1
  2224. assert_select 'option[value=?]', issue.default_status.id.to_s
  2225. end
  2226. end
  2227. test "without workflow privilege #create should accept default status" do
  2228. setup_without_workflow_privilege
  2229. assert_difference 'Issue.count' do
  2230. post :create, :project_id => 1,
  2231. :issue => {:tracker_id => 1,
  2232. :subject => 'This is an issue',
  2233. :status_id => 1}
  2234. end
  2235. issue = Issue.order('id').last
  2236. assert_not_nil issue.default_status
  2237. assert_equal issue.default_status, issue.status
  2238. end
  2239. test "without workflow privilege #create should ignore unauthorized status" do
  2240. setup_without_workflow_privilege
  2241. assert_difference 'Issue.count' do
  2242. post :create, :project_id => 1,
  2243. :issue => {:tracker_id => 1,
  2244. :subject => 'This is an issue',
  2245. :status_id => 3}
  2246. end
  2247. issue = Issue.order('id').last
  2248. assert_not_nil issue.default_status
  2249. assert_equal issue.default_status, issue.status
  2250. end
  2251. test "without workflow privilege #update should ignore status change" do
  2252. setup_without_workflow_privilege
  2253. assert_difference 'Journal.count' do
  2254. put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
  2255. end
  2256. assert_equal 1, Issue.find(1).status_id
  2257. end
  2258. test "without workflow privilege #update ignore attributes changes" do
  2259. setup_without_workflow_privilege
  2260. assert_difference 'Journal.count' do
  2261. put :update, :id => 1,
  2262. :issue => {:subject => 'changed', :assigned_to_id => 2,
  2263. :notes => 'just trying'}
  2264. end
  2265. issue = Issue.find(1)
  2266. assert_equal "Cannot print recipes", issue.subject
  2267. assert_nil issue.assigned_to
  2268. end
  2269. def setup_with_workflow_privilege
  2270. WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
  2271. WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
  2272. :old_status_id => 1, :new_status_id => 3)
  2273. WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
  2274. :old_status_id => 1, :new_status_id => 4)
  2275. Role.anonymous.add_permission! :add_issues, :add_issue_notes
  2276. end
  2277. private :setup_with_workflow_privilege
  2278. def setup_with_workflow_privilege_and_edit_issues_permission
  2279. setup_with_workflow_privilege
  2280. Role.anonymous.add_permission! :add_issues, :edit_issues
  2281. end
  2282. private :setup_with_workflow_privilege_and_edit_issues_permission
  2283. test "with workflow privilege and :edit_issues permission should accept authorized status" do
  2284. setup_with_workflow_privilege_and_edit_issues_permission
  2285. assert_difference 'Journal.count' do
  2286. put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
  2287. end
  2288. assert_equal 3, Issue.find(1).status_id
  2289. end
  2290. test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
  2291. setup_with_workflow_privilege_and_edit_issues_permission
  2292. assert_difference 'Journal.count' do
  2293. put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
  2294. end
  2295. assert_equal 1, Issue.find(1).status_id
  2296. end
  2297. test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
  2298. setup_with_workflow_privilege_and_edit_issues_permission
  2299. assert_difference 'Journal.count' do
  2300. put :update, :id => 1,
  2301. :issue => {:subject => 'changed', :assigned_to_id => 2,
  2302. :notes => 'just trying'}
  2303. end
  2304. issue = Issue.find(1)
  2305. assert_equal "changed", issue.subject
  2306. assert_equal 2, issue.assigned_to_id
  2307. end
  2308. def test_new_as_copy
  2309. @request.session[:user_id] = 2
  2310. get :new, :project_id => 1, :copy_from => 1
  2311. assert_response :success
  2312. assert_template 'new'
  2313. assert_not_nil assigns(:issue)
  2314. orig = Issue.find(1)
  2315. assert_equal 1, assigns(:issue).project_id
  2316. assert_equal orig.subject, assigns(:issue).subject
  2317. assert assigns(:issue).copy?
  2318. assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
  2319. assert_select 'select[name=?]', 'issue[project_id]' do
  2320. assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
  2321. assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
  2322. end
  2323. assert_select 'input[name=copy_from][value="1"]'
  2324. end
  2325. # "New issue" menu item should not link to copy
  2326. assert_select '#main-menu a.new-issue[href="/projects/ecookbook/issues/new"]'
  2327. end
  2328. def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
  2329. user = setup_user_with_copy_but_not_add_permission
  2330. @request.session[:user_id] = user.id
  2331. get :new, :project_id => 1, :copy_from => 1
  2332. assert_response :success
  2333. assert_template 'new'
  2334. assert_select 'select[name=?]', 'issue[project_id]' do
  2335. assert_select 'option[value="1"]', 0
  2336. assert_select 'option[value="2"]', :text => 'OnlineStore'
  2337. end
  2338. end
  2339. def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
  2340. @request.session[:user_id] = 2
  2341. issue = Issue.find(3)
  2342. assert issue.attachments.count > 0
  2343. get :new, :project_id => 1, :copy_from => 3
  2344. assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
  2345. end
  2346. def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
  2347. @request.session[:user_id] = 2
  2348. issue = Issue.find(3)
  2349. issue.attachments.delete_all
  2350. get :new, :project_id => 1, :copy_from => 3
  2351. assert_select 'input[name=copy_attachments]', 0
  2352. end
  2353. def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
  2354. @request.session[:user_id] = 2
  2355. issue = Issue.generate_with_descendants!
  2356. get :new, :project_id => 1, :copy_from => issue.id
  2357. assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
  2358. end
  2359. def test_new_as_copy_with_invalid_issue_should_respond_with_404
  2360. @request.session[:user_id] = 2
  2361. get :new, :project_id => 1, :copy_from => 99999
  2362. assert_response 404
  2363. end
  2364. def test_create_as_copy_on_different_project
  2365. @request.session[:user_id] = 2
  2366. assert_difference 'Issue.count' do
  2367. post :create, :project_id => 1, :copy_from => 1,
  2368. :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
  2369. assert_not_nil assigns(:issue)
  2370. assert assigns(:issue).copy?
  2371. end
  2372. issue = Issue.order('id DESC').first
  2373. assert_redirected_to "/issues/#{issue.id}"
  2374. assert_equal 2, issue.project_id
  2375. assert_equal 3, issue.tracker_id
  2376. assert_equal 'Copy', issue.subject
  2377. end
  2378. def test_create_as_copy_should_allow_status_to_be_set_to_default
  2379. copied = Issue.generate! :status_id => 2
  2380. assert_equal 2, copied.reload.status_id
  2381. @request.session[:user_id] = 2
  2382. assert_difference 'Issue.count' do
  2383. post :create, :project_id => 1, :copy_from => copied.id,
  2384. :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
  2385. :was_default_status => '1'
  2386. end
  2387. issue = Issue.order('id DESC').first
  2388. assert_equal 1, issue.status_id
  2389. end
  2390. def test_create_as_copy_should_copy_attachments
  2391. @request.session[:user_id] = 2
  2392. issue = Issue.find(3)
  2393. count = issue.attachments.count
  2394. assert count > 0
  2395. assert_difference 'Issue.count' do
  2396. assert_difference 'Attachment.count', count do
  2397. post :create, :project_id => 1, :copy_from => 3,
  2398. :issue => {:project_id => '1', :tracker_id => '3',
  2399. :status_id => '1', :subject => 'Copy with attachments'},
  2400. :copy_attachments => '1'
  2401. end
  2402. end
  2403. copy = Issue.order('id DESC').first
  2404. assert_equal count, copy.attachments.count
  2405. assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
  2406. end
  2407. def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
  2408. @request.session[:user_id] = 2
  2409. issue = Issue.find(3)
  2410. count = issue.attachments.count
  2411. assert count > 0
  2412. assert_difference 'Issue.count' do
  2413. assert_no_difference 'Attachment.count' do
  2414. post :create, :project_id => 1, :copy_from => 3,
  2415. :issue => {:project_id => '1', :tracker_id => '3',
  2416. :status_id => '1', :subject => 'Copy with attachments'}
  2417. end
  2418. end
  2419. copy = Issue.order('id DESC').first
  2420. assert_equal 0, copy.attachments.count
  2421. end
  2422. def test_create_as_copy_with_attachments_should_also_add_new_files
  2423. @request.session[:user_id] = 2
  2424. issue = Issue.find(3)
  2425. count = issue.attachments.count
  2426. assert count > 0
  2427. assert_difference 'Issue.count' do
  2428. assert_difference 'Attachment.count', count + 1 do
  2429. post :create, :project_id => 1, :copy_from => 3,
  2430. :issue => {:project_id => '1', :tracker_id => '3',
  2431. :status_id => '1', :subject => 'Copy with attachments'},
  2432. :copy_attachments => '1',
  2433. :attachments => {'1' =>
  2434. {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
  2435. 'description' => 'test file'}}
  2436. end
  2437. end
  2438. copy = Issue.order('id DESC').first
  2439. assert_equal count + 1, copy.attachments.count
  2440. end
  2441. def test_create_as_copy_should_add_relation_with_copied_issue
  2442. @request.session[:user_id] = 2
  2443. assert_difference 'Issue.count' do
  2444. assert_difference 'IssueRelation.count' do
  2445. post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
  2446. :issue => {:project_id => '1', :tracker_id => '3',
  2447. :status_id => '1', :subject => 'Copy'}
  2448. end
  2449. end
  2450. copy = Issue.order('id DESC').first
  2451. assert_equal 1, copy.relations.size
  2452. end
  2453. def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
  2454. @request.session[:user_id] = 2
  2455. assert_difference 'Issue.count' do
  2456. assert_no_difference 'IssueRelation.count' do
  2457. post :create, :project_id => 1, :copy_from => 1,
  2458. :issue => {:subject => 'Copy'}
  2459. end
  2460. end
  2461. end
  2462. def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
  2463. with_settings :link_copied_issue => 'yes' do
  2464. @request.session[:user_id] = 2
  2465. assert_difference 'Issue.count' do
  2466. assert_difference 'IssueRelation.count' do
  2467. post :create, :project_id => 1, :copy_from => 1,
  2468. :issue => {:subject => 'Copy'}
  2469. end
  2470. end
  2471. end
  2472. end
  2473. def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
  2474. with_settings :link_copied_issue => 'no' do
  2475. @request.session[:user_id] = 2
  2476. assert_difference 'Issue.count' do
  2477. assert_no_difference 'IssueRelation.count' do
  2478. post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
  2479. :issue => {:subject => 'Copy'}
  2480. end
  2481. end
  2482. end
  2483. end
  2484. def test_create_as_copy_should_copy_subtasks
  2485. @request.session[:user_id] = 2
  2486. issue = Issue.generate_with_descendants!
  2487. count = issue.descendants.count
  2488. assert_difference 'Issue.count', count + 1 do
  2489. post :create, :project_id => 1, :copy_from => issue.id,
  2490. :issue => {:project_id => '1', :tracker_id => '3',
  2491. :status_id => '1', :subject => 'Copy with subtasks'},
  2492. :copy_subtasks => '1'
  2493. end
  2494. copy = Issue.where(:parent_id => nil).order('id DESC').first
  2495. assert_equal count, copy.descendants.count
  2496. assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
  2497. end
  2498. def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
  2499. @request.session[:user_id] = 2
  2500. issue = Issue.generate_with_descendants!
  2501. assert_difference 'Issue.count', 1 do
  2502. post :create, :project_id => 1, :copy_from => 3,
  2503. :issue => {:project_id => '1', :tracker_id => '3',
  2504. :status_id => '1', :subject => 'Copy with subtasks'}
  2505. end
  2506. copy = Issue.where(:parent_id => nil).order('id DESC').first
  2507. assert_equal 0, copy.descendants.count
  2508. end
  2509. def test_create_as_copy_with_failure
  2510. @request.session[:user_id] = 2
  2511. post :create, :project_id => 1, :copy_from => 1,
  2512. :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
  2513. assert_response :success
  2514. assert_template 'new'
  2515. assert_not_nil assigns(:issue)
  2516. assert assigns(:issue).copy?
  2517. assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
  2518. assert_select 'select[name=?]', 'issue[project_id]' do
  2519. assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
  2520. assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
  2521. end
  2522. assert_select 'input[name=copy_from][value="1"]'
  2523. end
  2524. end
  2525. def test_create_as_copy_on_project_without_permission_should_ignore_target_project
  2526. @request.session[:user_id] = 2
  2527. assert !User.find(2).member_of?(Project.find(4))
  2528. assert_difference 'Issue.count' do
  2529. post :create, :project_id => 1, :copy_from => 1,
  2530. :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
  2531. end
  2532. issue = Issue.order('id DESC').first
  2533. assert_equal 1, issue.project_id
  2534. end
  2535. def test_get_edit
  2536. @request.session[:user_id] = 2
  2537. get :edit, :id => 1
  2538. assert_response :success
  2539. assert_template 'edit'
  2540. assert_not_nil assigns(:issue)
  2541. assert_equal Issue.find(1), assigns(:issue)
  2542. # Be sure we don't display inactive IssuePriorities
  2543. assert ! IssuePriority.find(15).active?
  2544. assert_select 'select[name=?]', 'issue[priority_id]' do
  2545. assert_select 'option[value="15"]', 0
  2546. end
  2547. end
  2548. def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
  2549. @request.session[:user_id] = 2
  2550. Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
  2551. get :edit, :id => 1
  2552. assert_select 'input[name=?]', 'time_entry[hours]'
  2553. end
  2554. def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
  2555. @request.session[:user_id] = 2
  2556. Role.find_by_name('Manager').remove_permission! :log_time
  2557. get :edit, :id => 1
  2558. assert_select 'input[name=?]', 'time_entry[hours]', 0
  2559. end
  2560. def test_get_edit_with_params
  2561. @request.session[:user_id] = 2
  2562. get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
  2563. :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
  2564. assert_response :success
  2565. assert_template 'edit'
  2566. issue = assigns(:issue)
  2567. assert_not_nil issue
  2568. assert_equal 5, issue.status_id
  2569. assert_select 'select[name=?]', 'issue[status_id]' do
  2570. assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
  2571. end
  2572. assert_equal 7, issue.priority_id
  2573. assert_select 'select[name=?]', 'issue[priority_id]' do
  2574. assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
  2575. end
  2576. assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
  2577. assert_select 'select[name=?]', 'time_entry[activity_id]' do
  2578. assert_select 'option[value="10"][selected=selected]', :text => 'Development'
  2579. end
  2580. assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
  2581. end
  2582. def test_get_edit_with_multi_custom_field
  2583. field = CustomField.find(1)
  2584. field.update_attribute :multiple, true
  2585. issue = Issue.find(1)
  2586. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  2587. issue.save!
  2588. @request.session[:user_id] = 2
  2589. get :edit, :id => 1
  2590. assert_response :success
  2591. assert_template 'edit'
  2592. assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
  2593. assert_select 'option', 3
  2594. assert_select 'option[value=MySQL][selected=selected]'
  2595. assert_select 'option[value=Oracle][selected=selected]'
  2596. assert_select 'option[value=PostgreSQL]:not([selected])'
  2597. end
  2598. end
  2599. def test_update_form_for_existing_issue
  2600. @request.session[:user_id] = 2
  2601. xhr :patch, :edit, :id => 1,
  2602. :issue => {:tracker_id => 2,
  2603. :subject => 'This is the test_new issue',
  2604. :description => 'This is the description',
  2605. :priority_id => 5}
  2606. assert_response :success
  2607. assert_equal 'text/javascript', response.content_type
  2608. assert_template 'edit'
  2609. assert_template :partial => '_form'
  2610. issue = assigns(:issue)
  2611. assert_kind_of Issue, issue
  2612. assert_equal 1, issue.id
  2613. assert_equal 1, issue.project_id
  2614. assert_equal 2, issue.tracker_id
  2615. assert_equal 'This is the test_new issue', issue.subject
  2616. end
  2617. def test_update_form_for_existing_issue_should_keep_issue_author
  2618. @request.session[:user_id] = 3
  2619. xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
  2620. assert_response :success
  2621. assert_equal 'text/javascript', response.content_type
  2622. issue = assigns(:issue)
  2623. assert_equal User.find(2), issue.author
  2624. assert_equal 2, issue.author_id
  2625. assert_not_equal User.current, issue.author
  2626. end
  2627. def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
  2628. @request.session[:user_id] = 2
  2629. WorkflowTransition.delete_all
  2630. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
  2631. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
  2632. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
  2633. xhr :patch, :edit, :id => 2,
  2634. :issue => {:tracker_id => 2,
  2635. :status_id => 5,
  2636. :subject => 'This is an issue'}
  2637. assert_equal 5, assigns(:issue).status_id
  2638. assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
  2639. end
  2640. def test_update_form_for_existing_issue_with_project_change
  2641. @request.session[:user_id] = 2
  2642. xhr :patch, :edit, :id => 1,
  2643. :issue => {:project_id => 2,
  2644. :tracker_id => 2,
  2645. :subject => 'This is the test_new issue',
  2646. :description => 'This is the description',
  2647. :priority_id => 5}
  2648. assert_response :success
  2649. assert_template :partial => '_form'
  2650. issue = assigns(:issue)
  2651. assert_kind_of Issue, issue
  2652. assert_equal 1, issue.id
  2653. assert_equal 2, issue.project_id
  2654. assert_equal 2, issue.tracker_id
  2655. assert_equal 'This is the test_new issue', issue.subject
  2656. end
  2657. def test_update_form_should_keep_category_with_same_when_changing_project
  2658. source = Project.generate!
  2659. target = Project.generate!
  2660. source_category = IssueCategory.create!(:name => 'Foo', :project => source)
  2661. target_category = IssueCategory.create!(:name => 'Foo', :project => target)
  2662. issue = Issue.generate!(:project => source, :category => source_category)
  2663. @request.session[:user_id] = 1
  2664. patch :edit, :id => issue.id,
  2665. :issue => {:project_id => target.id, :category_id => source_category.id}
  2666. assert_response :success
  2667. issue = assigns(:issue)
  2668. assert_equal target_category, issue.category
  2669. end
  2670. def test_update_form_should_propose_default_status_for_existing_issue
  2671. @request.session[:user_id] = 2
  2672. WorkflowTransition.delete_all
  2673. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
  2674. xhr :patch, :edit, :id => 2
  2675. assert_response :success
  2676. assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
  2677. end
  2678. def test_put_update_without_custom_fields_param
  2679. @request.session[:user_id] = 2
  2680. issue = Issue.find(1)
  2681. assert_equal '125', issue.custom_value_for(2).value
  2682. assert_difference('Journal.count') do
  2683. assert_difference('JournalDetail.count') do
  2684. put :update, :id => 1, :issue => {:subject => 'New subject'}
  2685. end
  2686. end
  2687. assert_redirected_to :action => 'show', :id => '1'
  2688. issue.reload
  2689. assert_equal 'New subject', issue.subject
  2690. # Make sure custom fields were not cleared
  2691. assert_equal '125', issue.custom_value_for(2).value
  2692. end
  2693. def test_put_update_with_project_change
  2694. @request.session[:user_id] = 2
  2695. ActionMailer::Base.deliveries.clear
  2696. with_settings :notified_events => %w(issue_updated) do
  2697. assert_difference('Journal.count') do
  2698. assert_difference('JournalDetail.count', 3) do
  2699. put :update, :id => 1, :issue => {:project_id => '2',
  2700. :tracker_id => '1', # no change
  2701. :priority_id => '6',
  2702. :category_id => '3'
  2703. }
  2704. end
  2705. end
  2706. end
  2707. assert_redirected_to :action => 'show', :id => '1'
  2708. issue = Issue.find(1)
  2709. assert_equal 2, issue.project_id
  2710. assert_equal 1, issue.tracker_id
  2711. assert_equal 6, issue.priority_id
  2712. assert_equal 3, issue.category_id
  2713. mail = ActionMailer::Base.deliveries.last
  2714. assert_not_nil mail
  2715. assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
  2716. assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
  2717. end
  2718. def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
  2719. target = Project.generate!(:tracker_ids => [])
  2720. assert target.trackers.empty?
  2721. issue = Issue.generate!
  2722. @request.session[:user_id] = 1
  2723. put :update, :id => issue.id, :issue => {:project_id => target.id}
  2724. assert_response 302
  2725. end
  2726. def test_put_update_with_tracker_change
  2727. @request.session[:user_id] = 2
  2728. ActionMailer::Base.deliveries.clear
  2729. with_settings :notified_events => %w(issue_updated) do
  2730. assert_difference('Journal.count') do
  2731. assert_difference('JournalDetail.count', 2) do
  2732. put :update, :id => 1, :issue => {:project_id => '1',
  2733. :tracker_id => '2',
  2734. :priority_id => '6'
  2735. }
  2736. end
  2737. end
  2738. end
  2739. assert_redirected_to :action => 'show', :id => '1'
  2740. issue = Issue.find(1)
  2741. assert_equal 1, issue.project_id
  2742. assert_equal 2, issue.tracker_id
  2743. assert_equal 6, issue.priority_id
  2744. assert_equal 1, issue.category_id
  2745. mail = ActionMailer::Base.deliveries.last
  2746. assert_not_nil mail
  2747. assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
  2748. assert_mail_body_match "Tracker changed from Bug to Feature request", mail
  2749. end
  2750. def test_put_update_with_custom_field_change
  2751. @request.session[:user_id] = 2
  2752. issue = Issue.find(1)
  2753. assert_equal '125', issue.custom_value_for(2).value
  2754. with_settings :notified_events => %w(issue_updated) do
  2755. assert_difference('Journal.count') do
  2756. assert_difference('JournalDetail.count', 3) do
  2757. put :update, :id => 1, :issue => {:subject => 'Custom field change',
  2758. :priority_id => '6',
  2759. :category_id => '1', # no change
  2760. :custom_field_values => { '2' => 'New custom value' }
  2761. }
  2762. end
  2763. end
  2764. end
  2765. assert_redirected_to :action => 'show', :id => '1'
  2766. issue.reload
  2767. assert_equal 'New custom value', issue.custom_value_for(2).value
  2768. mail = ActionMailer::Base.deliveries.last
  2769. assert_not_nil mail
  2770. assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
  2771. end
  2772. def test_put_update_with_multi_custom_field_change
  2773. field = CustomField.find(1)
  2774. field.update_attribute :multiple, true
  2775. issue = Issue.find(1)
  2776. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  2777. issue.save!
  2778. @request.session[:user_id] = 2
  2779. assert_difference('Journal.count') do
  2780. assert_difference('JournalDetail.count', 3) do
  2781. put :update, :id => 1,
  2782. :issue => {
  2783. :subject => 'Custom field change',
  2784. :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
  2785. }
  2786. end
  2787. end
  2788. assert_redirected_to :action => 'show', :id => '1'
  2789. assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
  2790. end
  2791. def test_put_update_with_status_and_assignee_change
  2792. issue = Issue.find(1)
  2793. assert_equal 1, issue.status_id
  2794. @request.session[:user_id] = 2
  2795. with_settings :notified_events => %w(issue_updated) do
  2796. assert_difference('TimeEntry.count', 0) do
  2797. put :update,
  2798. :id => 1,
  2799. :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
  2800. :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
  2801. end
  2802. end
  2803. assert_redirected_to :action => 'show', :id => '1'
  2804. issue.reload
  2805. assert_equal 2, issue.status_id
  2806. j = Journal.order('id DESC').first
  2807. assert_equal 'Assigned to dlopper', j.notes
  2808. assert_equal 2, j.details.size
  2809. mail = ActionMailer::Base.deliveries.last
  2810. assert_mail_body_match "Status changed from New to Assigned", mail
  2811. # subject should contain the new status
  2812. assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
  2813. end
  2814. def test_put_update_with_note_only
  2815. notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
  2816. with_settings :notified_events => %w(issue_updated) do
  2817. # anonymous user
  2818. put :update,
  2819. :id => 1,
  2820. :issue => { :notes => notes }
  2821. end
  2822. assert_redirected_to :action => 'show', :id => '1'
  2823. j = Journal.order('id DESC').first
  2824. assert_equal notes, j.notes
  2825. assert_equal 0, j.details.size
  2826. assert_equal User.anonymous, j.user
  2827. mail = ActionMailer::Base.deliveries.last
  2828. assert_mail_body_match notes, mail
  2829. end
  2830. def test_put_update_with_private_note_only
  2831. notes = 'Private note'
  2832. @request.session[:user_id] = 2
  2833. assert_difference 'Journal.count' do
  2834. put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
  2835. assert_redirected_to :action => 'show', :id => '1'
  2836. end
  2837. j = Journal.order('id DESC').first
  2838. assert_equal notes, j.notes
  2839. assert_equal true, j.private_notes
  2840. end
  2841. def test_put_update_with_private_note_and_changes
  2842. notes = 'Private note'
  2843. @request.session[:user_id] = 2
  2844. assert_difference 'Journal.count', 2 do
  2845. put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
  2846. assert_redirected_to :action => 'show', :id => '1'
  2847. end
  2848. j = Journal.order('id DESC').first
  2849. assert_equal notes, j.notes
  2850. assert_equal true, j.private_notes
  2851. assert_equal 0, j.details.count
  2852. j = Journal.order('id DESC').offset(1).first
  2853. assert_nil j.notes
  2854. assert_equal false, j.private_notes
  2855. assert_equal 1, j.details.count
  2856. end
  2857. def test_put_update_with_note_and_spent_time
  2858. @request.session[:user_id] = 2
  2859. spent_hours_before = Issue.find(1).spent_hours
  2860. assert_difference('TimeEntry.count') do
  2861. put :update,
  2862. :id => 1,
  2863. :issue => { :notes => '2.5 hours added' },
  2864. :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
  2865. end
  2866. assert_redirected_to :action => 'show', :id => '1'
  2867. issue = Issue.find(1)
  2868. j = Journal.order('id DESC').first
  2869. assert_equal '2.5 hours added', j.notes
  2870. assert_equal 0, j.details.size
  2871. t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
  2872. assert_not_nil t
  2873. assert_equal 2.5, t.hours
  2874. assert_equal spent_hours_before + 2.5, issue.spent_hours
  2875. end
  2876. def test_put_update_should_preserve_parent_issue_even_if_not_visible
  2877. parent = Issue.generate!(:project_id => 1, :is_private => true)
  2878. issue = Issue.generate!(:parent_issue_id => parent.id)
  2879. assert !parent.visible?(User.find(3))
  2880. @request.session[:user_id] = 3
  2881. get :edit, :id => issue.id
  2882. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
  2883. put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
  2884. assert_response 302
  2885. assert_equal parent, issue.parent
  2886. end
  2887. def test_put_update_with_attachment_only
  2888. set_tmp_attachments_directory
  2889. # Delete all fixtured journals, a race condition can occur causing the wrong
  2890. # journal to get fetched in the next find.
  2891. Journal.delete_all
  2892. with_settings :notified_events => %w(issue_updated) do
  2893. # anonymous user
  2894. assert_difference 'Attachment.count' do
  2895. put :update, :id => 1,
  2896. :issue => {:notes => ''},
  2897. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
  2898. end
  2899. end
  2900. assert_redirected_to :action => 'show', :id => '1'
  2901. j = Issue.find(1).journals.reorder('id DESC').first
  2902. assert j.notes.blank?
  2903. assert_equal 1, j.details.size
  2904. assert_equal 'testfile.txt', j.details.first.value
  2905. assert_equal User.anonymous, j.user
  2906. attachment = Attachment.order('id DESC').first
  2907. assert_equal Issue.find(1), attachment.container
  2908. assert_equal User.anonymous, attachment.author
  2909. assert_equal 'testfile.txt', attachment.filename
  2910. assert_equal 'text/plain', attachment.content_type
  2911. assert_equal 'test file', attachment.description
  2912. assert_equal 59, attachment.filesize
  2913. assert File.exists?(attachment.diskfile)
  2914. assert_equal 59, File.size(attachment.diskfile)
  2915. mail = ActionMailer::Base.deliveries.last
  2916. assert_mail_body_match 'testfile.txt', mail
  2917. end
  2918. def test_put_update_with_failure_should_save_attachments
  2919. set_tmp_attachments_directory
  2920. @request.session[:user_id] = 2
  2921. assert_no_difference 'Journal.count' do
  2922. assert_difference 'Attachment.count' do
  2923. put :update, :id => 1,
  2924. :issue => { :subject => '' },
  2925. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
  2926. assert_response :success
  2927. assert_template 'edit'
  2928. end
  2929. end
  2930. attachment = Attachment.order('id DESC').first
  2931. assert_equal 'testfile.txt', attachment.filename
  2932. assert File.exists?(attachment.diskfile)
  2933. assert_nil attachment.container
  2934. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  2935. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  2936. end
  2937. def test_put_update_with_failure_should_keep_saved_attachments
  2938. set_tmp_attachments_directory
  2939. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  2940. @request.session[:user_id] = 2
  2941. assert_no_difference 'Journal.count' do
  2942. assert_no_difference 'Attachment.count' do
  2943. put :update, :id => 1,
  2944. :issue => { :subject => '' },
  2945. :attachments => {'p0' => {'token' => attachment.token}}
  2946. assert_response :success
  2947. assert_template 'edit'
  2948. end
  2949. end
  2950. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  2951. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  2952. end
  2953. def test_put_update_should_attach_saved_attachments
  2954. set_tmp_attachments_directory
  2955. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  2956. @request.session[:user_id] = 2
  2957. assert_difference 'Journal.count' do
  2958. assert_difference 'JournalDetail.count' do
  2959. assert_no_difference 'Attachment.count' do
  2960. put :update, :id => 1,
  2961. :issue => {:notes => 'Attachment added'},
  2962. :attachments => {'p0' => {'token' => attachment.token}}
  2963. assert_redirected_to '/issues/1'
  2964. end
  2965. end
  2966. end
  2967. attachment.reload
  2968. assert_equal Issue.find(1), attachment.container
  2969. journal = Journal.order('id DESC').first
  2970. assert_equal 1, journal.details.size
  2971. assert_equal 'testfile.txt', journal.details.first.value
  2972. end
  2973. def test_put_update_with_attachment_that_fails_to_save
  2974. set_tmp_attachments_directory
  2975. # anonymous user
  2976. with_settings :attachment_max_size => 0 do
  2977. put :update,
  2978. :id => 1,
  2979. :issue => {:notes => ''},
  2980. :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
  2981. assert_redirected_to :action => 'show', :id => '1'
  2982. assert_equal '1 file(s) could not be saved.', flash[:warning]
  2983. end
  2984. end
  2985. def test_put_update_with_no_change
  2986. issue = Issue.find(1)
  2987. issue.journals.clear
  2988. ActionMailer::Base.deliveries.clear
  2989. put :update,
  2990. :id => 1,
  2991. :issue => {:notes => ''}
  2992. assert_redirected_to :action => 'show', :id => '1'
  2993. issue.reload
  2994. assert issue.journals.empty?
  2995. # No email should be sent
  2996. assert ActionMailer::Base.deliveries.empty?
  2997. end
  2998. def test_put_update_should_send_a_notification
  2999. @request.session[:user_id] = 2
  3000. ActionMailer::Base.deliveries.clear
  3001. issue = Issue.find(1)
  3002. old_subject = issue.subject
  3003. new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
  3004. with_settings :notified_events => %w(issue_updated) do
  3005. put :update, :id => 1, :issue => {:subject => new_subject,
  3006. :priority_id => '6',
  3007. :category_id => '1' # no change
  3008. }
  3009. assert_equal 1, ActionMailer::Base.deliveries.size
  3010. end
  3011. end
  3012. def test_put_update_with_invalid_spent_time_hours_only
  3013. @request.session[:user_id] = 2
  3014. notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
  3015. assert_no_difference('Journal.count') do
  3016. put :update,
  3017. :id => 1,
  3018. :issue => {:notes => notes},
  3019. :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
  3020. end
  3021. assert_response :success
  3022. assert_template 'edit'
  3023. assert_select_error /Activity cannot be blank/
  3024. assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
  3025. assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
  3026. end
  3027. def test_put_update_with_invalid_spent_time_comments_only
  3028. @request.session[:user_id] = 2
  3029. notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
  3030. assert_no_difference('Journal.count') do
  3031. put :update,
  3032. :id => 1,
  3033. :issue => {:notes => notes},
  3034. :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
  3035. end
  3036. assert_response :success
  3037. assert_template 'edit'
  3038. assert_select_error /Activity cannot be blank/
  3039. assert_select_error /Hours cannot be blank/
  3040. assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
  3041. assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
  3042. end
  3043. def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
  3044. issue = Issue.find(2)
  3045. @request.session[:user_id] = 2
  3046. put :update,
  3047. :id => issue.id,
  3048. :issue => {
  3049. :fixed_version_id => 4
  3050. }
  3051. assert_response :redirect
  3052. issue.reload
  3053. assert_equal 4, issue.fixed_version_id
  3054. assert_not_equal issue.project_id, issue.fixed_version.project_id
  3055. end
  3056. def test_put_update_should_redirect_back_using_the_back_url_parameter
  3057. issue = Issue.find(2)
  3058. @request.session[:user_id] = 2
  3059. put :update,
  3060. :id => issue.id,
  3061. :issue => {
  3062. :fixed_version_id => 4
  3063. },
  3064. :back_url => '/issues'
  3065. assert_response :redirect
  3066. assert_redirected_to '/issues'
  3067. end
  3068. def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
  3069. issue = Issue.find(2)
  3070. @request.session[:user_id] = 2
  3071. put :update,
  3072. :id => issue.id,
  3073. :issue => {
  3074. :fixed_version_id => 4
  3075. },
  3076. :back_url => 'http://google.com'
  3077. assert_response :redirect
  3078. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
  3079. end
  3080. def test_get_bulk_edit
  3081. @request.session[:user_id] = 2
  3082. get :bulk_edit, :ids => [1, 3]
  3083. assert_response :success
  3084. assert_template 'bulk_edit'
  3085. assert_select 'ul#bulk-selection' do
  3086. assert_select 'li', 2
  3087. assert_select 'li a', :text => 'Bug #1'
  3088. end
  3089. assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
  3090. assert_select 'input[name=?]', 'ids[]', 2
  3091. assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
  3092. assert_select 'select[name=?]', 'issue[project_id]'
  3093. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  3094. # Project specific custom field, date type
  3095. field = CustomField.find(9)
  3096. assert !field.is_for_all?
  3097. assert_equal 'date', field.field_format
  3098. assert_select 'input[name=?]', 'issue[custom_field_values][9]'
  3099. # System wide custom field
  3100. assert CustomField.find(1).is_for_all?
  3101. assert_select 'select[name=?]', 'issue[custom_field_values][1]'
  3102. # Be sure we don't display inactive IssuePriorities
  3103. assert ! IssuePriority.find(15).active?
  3104. assert_select 'select[name=?]', 'issue[priority_id]' do
  3105. assert_select 'option[value="15"]', 0
  3106. end
  3107. end
  3108. end
  3109. def test_get_bulk_edit_on_different_projects
  3110. @request.session[:user_id] = 2
  3111. get :bulk_edit, :ids => [1, 2, 6]
  3112. assert_response :success
  3113. assert_template 'bulk_edit'
  3114. # Can not set issues from different projects as children of an issue
  3115. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  3116. # Project specific custom field, date type
  3117. field = CustomField.find(9)
  3118. assert !field.is_for_all?
  3119. assert !field.project_ids.include?(Issue.find(6).project_id)
  3120. assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
  3121. end
  3122. def test_get_bulk_edit_with_user_custom_field
  3123. field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
  3124. @request.session[:user_id] = 2
  3125. get :bulk_edit, :ids => [1, 2]
  3126. assert_response :success
  3127. assert_template 'bulk_edit'
  3128. assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
  3129. assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
  3130. end
  3131. end
  3132. def test_get_bulk_edit_with_version_custom_field
  3133. field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
  3134. @request.session[:user_id] = 2
  3135. get :bulk_edit, :ids => [1, 2]
  3136. assert_response :success
  3137. assert_template 'bulk_edit'
  3138. assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
  3139. assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
  3140. end
  3141. end
  3142. def test_get_bulk_edit_with_multi_custom_field
  3143. field = CustomField.find(1)
  3144. field.update_attribute :multiple, true
  3145. @request.session[:user_id] = 2
  3146. get :bulk_edit, :ids => [1, 3]
  3147. assert_response :success
  3148. assert_template 'bulk_edit'
  3149. assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
  3150. assert_select 'option', field.possible_values.size + 1 # "none" options
  3151. end
  3152. end
  3153. def test_bulk_edit_should_propose_to_clear_text_custom_fields
  3154. @request.session[:user_id] = 2
  3155. get :bulk_edit, :ids => [1, 3]
  3156. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
  3157. end
  3158. def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
  3159. WorkflowTransition.delete_all
  3160. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  3161. :old_status_id => 1, :new_status_id => 1)
  3162. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  3163. :old_status_id => 1, :new_status_id => 3)
  3164. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  3165. :old_status_id => 1, :new_status_id => 4)
  3166. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  3167. :old_status_id => 2, :new_status_id => 1)
  3168. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  3169. :old_status_id => 2, :new_status_id => 3)
  3170. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  3171. :old_status_id => 2, :new_status_id => 5)
  3172. @request.session[:user_id] = 2
  3173. get :bulk_edit, :ids => [1, 2]
  3174. assert_response :success
  3175. statuses = assigns(:available_statuses)
  3176. assert_not_nil statuses
  3177. assert_equal [1, 3], statuses.map(&:id).sort
  3178. assert_select 'select[name=?]', 'issue[status_id]' do
  3179. assert_select 'option', 3 # 2 statuses + "no change" option
  3180. end
  3181. end
  3182. def test_bulk_edit_should_propose_target_project_open_shared_versions
  3183. @request.session[:user_id] = 2
  3184. post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
  3185. assert_response :success
  3186. assert_template 'bulk_edit'
  3187. assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
  3188. assert_select 'select[name=?]', 'issue[fixed_version_id]' do
  3189. assert_select 'option', :text => '2.0'
  3190. end
  3191. end
  3192. def test_bulk_edit_should_propose_target_project_categories
  3193. @request.session[:user_id] = 2
  3194. post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
  3195. assert_response :success
  3196. assert_template 'bulk_edit'
  3197. assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
  3198. assert_select 'select[name=?]', 'issue[category_id]' do
  3199. assert_select 'option', :text => 'Recipes'
  3200. end
  3201. end
  3202. def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
  3203. IssueCustomField.delete_all
  3204. field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
  3205. IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
  3206. @request.session[:user_id] = 2
  3207. issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
  3208. get :bulk_edit, :ids => issue_ids
  3209. assert_equal [field], assigns(:custom_fields)
  3210. end
  3211. def test_bulk_update
  3212. @request.session[:user_id] = 2
  3213. # update issues priority
  3214. post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
  3215. :issue => {:priority_id => 7,
  3216. :assigned_to_id => '',
  3217. :custom_field_values => {'2' => ''}}
  3218. assert_response 302
  3219. # check that the issues were updated
  3220. assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
  3221. issue = Issue.find(1)
  3222. journal = issue.journals.reorder('created_on DESC').first
  3223. assert_equal '125', issue.custom_value_for(2).value
  3224. assert_equal 'Bulk editing', journal.notes
  3225. assert_equal 1, journal.details.size
  3226. end
  3227. def test_bulk_update_with_group_assignee
  3228. group = Group.find(11)
  3229. project = Project.find(1)
  3230. project.members << Member.new(:principal => group, :roles => [Role.givable.first])
  3231. @request.session[:user_id] = 2
  3232. # update issues assignee
  3233. post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
  3234. :issue => {:priority_id => '',
  3235. :assigned_to_id => group.id,
  3236. :custom_field_values => {'2' => ''}}
  3237. assert_response 302
  3238. assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
  3239. end
  3240. def test_bulk_update_on_different_projects
  3241. @request.session[:user_id] = 2
  3242. # update issues priority
  3243. post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
  3244. :issue => {:priority_id => 7,
  3245. :assigned_to_id => '',
  3246. :custom_field_values => {'2' => ''}}
  3247. assert_response 302
  3248. # check that the issues were updated
  3249. assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
  3250. issue = Issue.find(1)
  3251. journal = issue.journals.reorder('created_on DESC').first
  3252. assert_equal '125', issue.custom_value_for(2).value
  3253. assert_equal 'Bulk editing', journal.notes
  3254. assert_equal 1, journal.details.size
  3255. end
  3256. def test_bulk_update_on_different_projects_without_rights
  3257. @request.session[:user_id] = 3
  3258. user = User.find(3)
  3259. action = { :controller => "issues", :action => "bulk_update" }
  3260. assert user.allowed_to?(action, Issue.find(1).project)
  3261. assert ! user.allowed_to?(action, Issue.find(6).project)
  3262. post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
  3263. :issue => {:priority_id => 7,
  3264. :assigned_to_id => '',
  3265. :custom_field_values => {'2' => ''}}
  3266. assert_response 403
  3267. assert_not_equal "Bulk should fail", Journal.last.notes
  3268. end
  3269. def test_bullk_update_should_send_a_notification
  3270. @request.session[:user_id] = 2
  3271. ActionMailer::Base.deliveries.clear
  3272. with_settings :notified_events => %w(issue_updated) do
  3273. post(:bulk_update,
  3274. {
  3275. :ids => [1, 2],
  3276. :notes => 'Bulk editing',
  3277. :issue => {
  3278. :priority_id => 7,
  3279. :assigned_to_id => '',
  3280. :custom_field_values => {'2' => ''}
  3281. }
  3282. })
  3283. assert_response 302
  3284. assert_equal 2, ActionMailer::Base.deliveries.size
  3285. end
  3286. end
  3287. def test_bulk_update_project
  3288. @request.session[:user_id] = 2
  3289. post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
  3290. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  3291. # Issues moved to project 2
  3292. assert_equal 2, Issue.find(1).project_id
  3293. assert_equal 2, Issue.find(2).project_id
  3294. # No tracker change
  3295. assert_equal 1, Issue.find(1).tracker_id
  3296. assert_equal 2, Issue.find(2).tracker_id
  3297. end
  3298. def test_bulk_update_project_on_single_issue_should_follow_when_needed
  3299. @request.session[:user_id] = 2
  3300. post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
  3301. assert_redirected_to '/issues/1'
  3302. end
  3303. def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
  3304. @request.session[:user_id] = 2
  3305. post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
  3306. assert_redirected_to '/projects/onlinestore/issues'
  3307. end
  3308. def test_bulk_update_tracker
  3309. @request.session[:user_id] = 2
  3310. post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
  3311. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  3312. assert_equal 2, Issue.find(1).tracker_id
  3313. assert_equal 2, Issue.find(2).tracker_id
  3314. end
  3315. def test_bulk_update_status
  3316. @request.session[:user_id] = 2
  3317. # update issues priority
  3318. post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
  3319. :issue => {:priority_id => '',
  3320. :assigned_to_id => '',
  3321. :status_id => '5'}
  3322. assert_response 302
  3323. issue = Issue.find(1)
  3324. assert issue.closed?
  3325. end
  3326. def test_bulk_update_priority
  3327. @request.session[:user_id] = 2
  3328. post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
  3329. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  3330. assert_equal 6, Issue.find(1).priority_id
  3331. assert_equal 6, Issue.find(2).priority_id
  3332. end
  3333. def test_bulk_update_with_notes
  3334. @request.session[:user_id] = 2
  3335. post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
  3336. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  3337. assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
  3338. assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
  3339. end
  3340. def test_bulk_update_parent_id
  3341. IssueRelation.delete_all
  3342. @request.session[:user_id] = 2
  3343. post :bulk_update, :ids => [1, 3],
  3344. :notes => 'Bulk editing parent',
  3345. :issue => {:priority_id => '', :assigned_to_id => '',
  3346. :status_id => '', :parent_issue_id => '2'}
  3347. assert_response 302
  3348. parent = Issue.find(2)
  3349. assert_equal parent.id, Issue.find(1).parent_id
  3350. assert_equal parent.id, Issue.find(3).parent_id
  3351. assert_equal [1, 3], parent.children.collect(&:id).sort
  3352. end
  3353. def test_bulk_update_custom_field
  3354. @request.session[:user_id] = 2
  3355. # update issues priority
  3356. post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
  3357. :issue => {:priority_id => '',
  3358. :assigned_to_id => '',
  3359. :custom_field_values => {'2' => '777'}}
  3360. assert_response 302
  3361. issue = Issue.find(1)
  3362. journal = issue.journals.reorder('created_on DESC').first
  3363. assert_equal '777', issue.custom_value_for(2).value
  3364. assert_equal 1, journal.details.size
  3365. assert_equal '125', journal.details.first.old_value
  3366. assert_equal '777', journal.details.first.value
  3367. end
  3368. def test_bulk_update_custom_field_to_blank
  3369. @request.session[:user_id] = 2
  3370. post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
  3371. :issue => {:priority_id => '',
  3372. :assigned_to_id => '',
  3373. :custom_field_values => {'1' => '__none__'}}
  3374. assert_response 302
  3375. assert_equal '', Issue.find(1).custom_field_value(1)
  3376. assert_equal '', Issue.find(3).custom_field_value(1)
  3377. end
  3378. def test_bulk_update_multi_custom_field
  3379. field = CustomField.find(1)
  3380. field.update_attribute :multiple, true
  3381. @request.session[:user_id] = 2
  3382. post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
  3383. :issue => {:priority_id => '',
  3384. :assigned_to_id => '',
  3385. :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
  3386. assert_response 302
  3387. assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
  3388. assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
  3389. # the custom field is not associated with the issue tracker
  3390. assert_nil Issue.find(2).custom_field_value(1)
  3391. end
  3392. def test_bulk_update_multi_custom_field_to_blank
  3393. field = CustomField.find(1)
  3394. field.update_attribute :multiple, true
  3395. @request.session[:user_id] = 2
  3396. post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
  3397. :issue => {:priority_id => '',
  3398. :assigned_to_id => '',
  3399. :custom_field_values => {'1' => ['__none__']}}
  3400. assert_response 302
  3401. assert_equal [''], Issue.find(1).custom_field_value(1)
  3402. assert_equal [''], Issue.find(3).custom_field_value(1)
  3403. end
  3404. def test_bulk_update_unassign
  3405. assert_not_nil Issue.find(2).assigned_to
  3406. @request.session[:user_id] = 2
  3407. # unassign issues
  3408. post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
  3409. assert_response 302
  3410. # check that the issues were updated
  3411. assert_nil Issue.find(2).assigned_to
  3412. end
  3413. def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
  3414. @request.session[:user_id] = 2
  3415. post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
  3416. assert_response :redirect
  3417. issues = Issue.find([1,2])
  3418. issues.each do |issue|
  3419. assert_equal 4, issue.fixed_version_id
  3420. assert_not_equal issue.project_id, issue.fixed_version.project_id
  3421. end
  3422. end
  3423. def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
  3424. @request.session[:user_id] = 2
  3425. post :bulk_update, :ids => [1,2], :back_url => '/issues'
  3426. assert_response :redirect
  3427. assert_redirected_to '/issues'
  3428. end
  3429. def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
  3430. @request.session[:user_id] = 2
  3431. post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
  3432. assert_response :redirect
  3433. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
  3434. end
  3435. def test_bulk_update_with_all_failures_should_show_errors
  3436. @request.session[:user_id] = 2
  3437. post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
  3438. assert_response :success
  3439. assert_template 'bulk_edit'
  3440. assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
  3441. assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
  3442. assert_equal [1, 2], assigns[:issues].map(&:id)
  3443. end
  3444. def test_bulk_update_with_some_failures_should_show_errors
  3445. issue1 = Issue.generate!(:start_date => '2013-05-12')
  3446. issue2 = Issue.generate!(:start_date => '2013-05-15')
  3447. issue3 = Issue.generate!
  3448. @request.session[:user_id] = 2
  3449. post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
  3450. :issue => {:due_date => '2013-05-01'}
  3451. assert_response :success
  3452. assert_template 'bulk_edit'
  3453. assert_select '#errorExplanation span',
  3454. :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
  3455. assert_select '#errorExplanation ul li',
  3456. :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
  3457. assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
  3458. end
  3459. def test_bulk_update_with_failure_should_preserved_form_values
  3460. @request.session[:user_id] = 2
  3461. post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
  3462. assert_response :success
  3463. assert_template 'bulk_edit'
  3464. assert_select 'select[name=?]', 'issue[tracker_id]' do
  3465. assert_select 'option[value="2"][selected=selected]'
  3466. end
  3467. assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
  3468. end
  3469. def test_get_bulk_copy
  3470. @request.session[:user_id] = 2
  3471. get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
  3472. assert_response :success
  3473. assert_template 'bulk_edit'
  3474. issues = assigns(:issues)
  3475. assert_not_nil issues
  3476. assert_equal [1, 2, 3], issues.map(&:id).sort
  3477. assert_select 'select[name=?]', 'issue[project_id]' do
  3478. assert_select 'option[value=""]'
  3479. end
  3480. assert_select 'input[name=copy_attachments]'
  3481. end
  3482. def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
  3483. user = setup_user_with_copy_but_not_add_permission
  3484. @request.session[:user_id] = user.id
  3485. get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
  3486. assert_response :success
  3487. assert_template 'bulk_edit'
  3488. assert_select 'select[name=?]', 'issue[project_id]' do
  3489. assert_select 'option[value=""]', 0
  3490. assert_select 'option[value="2"]'
  3491. end
  3492. end
  3493. def test_bulk_copy_to_another_project
  3494. @request.session[:user_id] = 2
  3495. assert_difference 'Issue.count', 2 do
  3496. assert_no_difference 'Project.find(1).issues.count' do
  3497. post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
  3498. end
  3499. end
  3500. assert_redirected_to '/projects/ecookbook/issues'
  3501. copies = Issue.order('id DESC').limit(issues.size)
  3502. copies.each do |copy|
  3503. assert_equal 2, copy.project_id
  3504. end
  3505. end
  3506. def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
  3507. user = setup_user_with_copy_but_not_add_permission
  3508. @request.session[:user_id] = user.id
  3509. assert_difference 'Issue.count', 3 do
  3510. post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
  3511. assert_response 302
  3512. end
  3513. end
  3514. def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
  3515. user = setup_user_with_copy_but_not_add_permission
  3516. @request.session[:user_id] = user.id
  3517. post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
  3518. assert_response 403
  3519. end
  3520. def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
  3521. user = setup_user_with_copy_but_not_add_permission
  3522. @request.session[:user_id] = user.id
  3523. post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
  3524. assert_response 403
  3525. end
  3526. def test_bulk_copy_should_allow_not_changing_the_issue_attributes
  3527. @request.session[:user_id] = 2
  3528. issues = [
  3529. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
  3530. :priority_id => 2, :subject => 'issue 1', :author_id => 1,
  3531. :assigned_to_id => nil),
  3532. Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
  3533. :priority_id => 1, :subject => 'issue 2', :author_id => 2,
  3534. :assigned_to_id => 3)
  3535. ]
  3536. assert_difference 'Issue.count', issues.size do
  3537. post :bulk_update, :ids => issues.map(&:id), :copy => '1',
  3538. :issue => {
  3539. :project_id => '', :tracker_id => '', :assigned_to_id => '',
  3540. :status_id => '', :start_date => '', :due_date => ''
  3541. }
  3542. end
  3543. copies = Issue.order('id DESC').limit(issues.size)
  3544. issues.each do |orig|
  3545. copy = copies.detect {|c| c.subject == orig.subject}
  3546. assert_not_nil copy
  3547. assert_equal orig.project_id, copy.project_id
  3548. assert_equal orig.tracker_id, copy.tracker_id
  3549. assert_equal orig.status_id, copy.status_id
  3550. assert_equal orig.assigned_to_id, copy.assigned_to_id
  3551. assert_equal orig.priority_id, copy.priority_id
  3552. end
  3553. end
  3554. def test_bulk_copy_should_allow_changing_the_issue_attributes
  3555. # Fixes random test failure with Mysql
  3556. # where Issue.where(:project_id => 2).limit(2).order('id desc')
  3557. # doesn't return the expected results
  3558. Issue.delete_all("project_id=2")
  3559. @request.session[:user_id] = 2
  3560. assert_difference 'Issue.count', 2 do
  3561. assert_no_difference 'Project.find(1).issues.count' do
  3562. post :bulk_update, :ids => [1, 2], :copy => '1',
  3563. :issue => {
  3564. :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
  3565. :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
  3566. }
  3567. end
  3568. end
  3569. copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
  3570. assert_equal 2, copied_issues.size
  3571. copied_issues.each do |issue|
  3572. assert_equal 2, issue.project_id, "Project is incorrect"
  3573. assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
  3574. assert_equal 1, issue.status_id, "Status is incorrect"
  3575. assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
  3576. assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
  3577. end
  3578. end
  3579. def test_bulk_copy_should_allow_adding_a_note
  3580. @request.session[:user_id] = 2
  3581. assert_difference 'Issue.count', 1 do
  3582. post :bulk_update, :ids => [1], :copy => '1',
  3583. :notes => 'Copying one issue',
  3584. :issue => {
  3585. :project_id => '', :tracker_id => '', :assigned_to_id => '4',
  3586. :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
  3587. }
  3588. end
  3589. issue = Issue.order('id DESC').first
  3590. assert_equal 1, issue.journals.size
  3591. journal = issue.journals.first
  3592. assert_equal 'Copying one issue', journal.notes
  3593. end
  3594. def test_bulk_copy_should_allow_not_copying_the_attachments
  3595. attachment_count = Issue.find(3).attachments.size
  3596. assert attachment_count > 0
  3597. @request.session[:user_id] = 2
  3598. assert_difference 'Issue.count', 1 do
  3599. assert_no_difference 'Attachment.count' do
  3600. post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
  3601. :issue => {
  3602. :project_id => ''
  3603. }
  3604. end
  3605. end
  3606. end
  3607. def test_bulk_copy_should_allow_copying_the_attachments
  3608. attachment_count = Issue.find(3).attachments.size
  3609. assert attachment_count > 0
  3610. @request.session[:user_id] = 2
  3611. assert_difference 'Issue.count', 1 do
  3612. assert_difference 'Attachment.count', attachment_count do
  3613. post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
  3614. :issue => {
  3615. :project_id => ''
  3616. }
  3617. end
  3618. end
  3619. end
  3620. def test_bulk_copy_should_add_relations_with_copied_issues
  3621. @request.session[:user_id] = 2
  3622. assert_difference 'Issue.count', 2 do
  3623. assert_difference 'IssueRelation.count', 2 do
  3624. post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
  3625. :issue => {
  3626. :project_id => '1'
  3627. }
  3628. end
  3629. end
  3630. end
  3631. def test_bulk_copy_should_allow_not_copying_the_subtasks
  3632. issue = Issue.generate_with_descendants!
  3633. @request.session[:user_id] = 2
  3634. assert_difference 'Issue.count', 1 do
  3635. post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
  3636. :issue => {
  3637. :project_id => ''
  3638. }
  3639. end
  3640. end
  3641. def test_bulk_copy_should_allow_copying_the_subtasks
  3642. issue = Issue.generate_with_descendants!
  3643. count = issue.descendants.count
  3644. @request.session[:user_id] = 2
  3645. assert_difference 'Issue.count', count+1 do
  3646. post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
  3647. :issue => {
  3648. :project_id => ''
  3649. }
  3650. end
  3651. copy = Issue.where(:parent_id => nil).order("id DESC").first
  3652. assert_equal count, copy.descendants.count
  3653. end
  3654. def test_bulk_copy_should_not_copy_selected_subtasks_twice
  3655. issue = Issue.generate_with_descendants!
  3656. count = issue.descendants.count
  3657. @request.session[:user_id] = 2
  3658. assert_difference 'Issue.count', count+1 do
  3659. post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
  3660. :issue => {
  3661. :project_id => ''
  3662. }
  3663. end
  3664. copy = Issue.where(:parent_id => nil).order("id DESC").first
  3665. assert_equal count, copy.descendants.count
  3666. end
  3667. def test_bulk_copy_to_another_project_should_follow_when_needed
  3668. @request.session[:user_id] = 2
  3669. post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
  3670. issue = Issue.order('id DESC').first
  3671. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
  3672. end
  3673. def test_bulk_copy_with_all_failures_should_display_errors
  3674. @request.session[:user_id] = 2
  3675. post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
  3676. assert_response :success
  3677. end
  3678. def test_destroy_issue_with_no_time_entries
  3679. assert_nil TimeEntry.find_by_issue_id(2)
  3680. @request.session[:user_id] = 2
  3681. assert_difference 'Issue.count', -1 do
  3682. delete :destroy, :id => 2
  3683. end
  3684. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  3685. assert_nil Issue.find_by_id(2)
  3686. end
  3687. def test_destroy_issues_with_time_entries
  3688. @request.session[:user_id] = 2
  3689. assert_no_difference 'Issue.count' do
  3690. delete :destroy, :ids => [1, 3]
  3691. end
  3692. assert_response :success
  3693. assert_template 'destroy'
  3694. assert_not_nil assigns(:hours)
  3695. assert Issue.find_by_id(1) && Issue.find_by_id(3)
  3696. assert_select 'form' do
  3697. assert_select 'input[name=_method][value=delete]'
  3698. end
  3699. end
  3700. def test_destroy_issues_and_destroy_time_entries
  3701. @request.session[:user_id] = 2
  3702. assert_difference 'Issue.count', -2 do
  3703. assert_difference 'TimeEntry.count', -3 do
  3704. delete :destroy, :ids => [1, 3], :todo => 'destroy'
  3705. end
  3706. end
  3707. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  3708. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  3709. assert_nil TimeEntry.find_by_id([1, 2])
  3710. end
  3711. def test_destroy_issues_and_assign_time_entries_to_project
  3712. @request.session[:user_id] = 2
  3713. assert_difference 'Issue.count', -2 do
  3714. assert_no_difference 'TimeEntry.count' do
  3715. delete :destroy, :ids => [1, 3], :todo => 'nullify'
  3716. end
  3717. end
  3718. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  3719. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  3720. assert_nil TimeEntry.find(1).issue_id
  3721. assert_nil TimeEntry.find(2).issue_id
  3722. end
  3723. def test_destroy_issues_and_reassign_time_entries_to_another_issue
  3724. @request.session[:user_id] = 2
  3725. assert_difference 'Issue.count', -2 do
  3726. assert_no_difference 'TimeEntry.count' do
  3727. delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
  3728. end
  3729. end
  3730. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  3731. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  3732. assert_equal 2, TimeEntry.find(1).issue_id
  3733. assert_equal 2, TimeEntry.find(2).issue_id
  3734. end
  3735. def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
  3736. @request.session[:user_id] = 2
  3737. assert_no_difference 'Issue.count' do
  3738. assert_no_difference 'TimeEntry.count' do
  3739. # try to reassign time to an issue of another project
  3740. delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
  3741. end
  3742. end
  3743. assert_response :success
  3744. assert_template 'destroy'
  3745. end
  3746. def test_destroy_issues_from_different_projects
  3747. @request.session[:user_id] = 2
  3748. assert_difference 'Issue.count', -3 do
  3749. delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
  3750. end
  3751. assert_redirected_to :controller => 'issues', :action => 'index'
  3752. assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
  3753. end
  3754. def test_destroy_parent_and_child_issues
  3755. parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
  3756. child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
  3757. assert child.is_descendant_of?(parent.reload)
  3758. @request.session[:user_id] = 2
  3759. assert_difference 'Issue.count', -2 do
  3760. delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
  3761. end
  3762. assert_response 302
  3763. end
  3764. def test_destroy_invalid_should_respond_with_404
  3765. @request.session[:user_id] = 2
  3766. assert_no_difference 'Issue.count' do
  3767. delete :destroy, :id => 999
  3768. end
  3769. assert_response 404
  3770. end
  3771. def test_default_search_scope
  3772. get :index
  3773. assert_select 'div#quick-search form' do
  3774. assert_select 'input[name=issues][value="1"][type=hidden]'
  3775. end
  3776. end
  3777. def setup_user_with_copy_but_not_add_permission
  3778. Role.all.each {|r| r.remove_permission! :add_issues}
  3779. Role.find_by_name('Manager').add_permission! :add_issues
  3780. user = User.generate!
  3781. User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
  3782. User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
  3783. user
  3784. end
  3785. end