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 217KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2019 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require File.expand_path('../../test_helper', __FILE__)
  19. class IssuesControllerTest < Redmine::ControllerTest
  20. fixtures :projects,
  21. :users, :email_addresses, :user_preferences,
  22. :roles,
  23. :members,
  24. :member_roles,
  25. :issues,
  26. :issue_statuses,
  27. :issue_relations,
  28. :versions,
  29. :trackers,
  30. :projects_trackers,
  31. :issue_categories,
  32. :enabled_modules,
  33. :enumerations,
  34. :attachments,
  35. :workflows,
  36. :custom_fields,
  37. :custom_values,
  38. :custom_fields_projects,
  39. :custom_fields_trackers,
  40. :time_entries,
  41. :journals,
  42. :journal_details,
  43. :queries,
  44. :repositories,
  45. :changesets,
  46. :watchers
  47. include Redmine::I18n
  48. def setup
  49. User.current = nil
  50. end
  51. def test_index
  52. with_settings :default_language => "en" do
  53. get :index
  54. assert_response :success
  55. # links to visible issues
  56. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  57. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  58. # private projects hidden
  59. assert_select 'a[href="/issues/6"]', 0
  60. assert_select 'a[href="/issues/4"]', 0
  61. # project column
  62. assert_select 'th', :text => /Project/
  63. end
  64. end
  65. def test_index_should_not_list_issues_when_module_disabled
  66. EnabledModule.where("name = 'issue_tracking' AND project_id = 1").delete_all
  67. get :index
  68. assert_response :success
  69. assert_select 'a[href="/issues/1"]', 0
  70. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  71. end
  72. def test_index_should_list_visible_issues_only
  73. get :index, :params => {
  74. :per_page => 100
  75. }
  76. assert_response :success
  77. Issue.open.each do |issue|
  78. assert_select "tr#issue-#{issue.id}", issue.visible? ? 1 : 0
  79. end
  80. end
  81. def test_index_with_project
  82. Setting.display_subprojects_issues = 0
  83. get :index, :params => {
  84. :project_id => 1
  85. }
  86. assert_response :success
  87. # query form
  88. assert_select 'form#query_form' do
  89. assert_select 'div#query_form_with_buttons.hide-when-print' do
  90. assert_select 'div#query_form_content' do
  91. assert_select 'fieldset#filters.collapsible'
  92. assert_select 'fieldset#options'
  93. end
  94. assert_select 'p.buttons'
  95. end
  96. end
  97. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  98. assert_select 'a[href="/issues/5"]', 0
  99. end
  100. def test_index_with_project_and_subprojects
  101. Setting.display_subprojects_issues = 1
  102. get :index, :params => {
  103. :project_id => 1
  104. }
  105. assert_response :success
  106. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  107. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  108. assert_select 'a[href="/issues/6"]', 0
  109. end
  110. def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
  111. @request.session[:user_id] = 2
  112. Setting.display_subprojects_issues = 1
  113. get :index, :params => {
  114. :project_id => 1
  115. }
  116. assert_response :success
  117. assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
  118. assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
  119. assert_select 'a[href="/issues/6"]', :text => /Issue of a private subproject/
  120. end
  121. def test_index_with_project_and_default_filter
  122. get :index, :params => {
  123. :project_id => 1,
  124. :set_filter => 1
  125. }
  126. assert_response :success
  127. # default filter
  128. assert_query_filters [['status_id', 'o', '']]
  129. end
  130. def test_index_with_project_and_filter
  131. get :index, :params => {
  132. :project_id => 1,
  133. :set_filter => 1,
  134. :f => ['tracker_id'],
  135. :op => {
  136. 'tracker_id' => '='
  137. },
  138. :v => {
  139. 'tracker_id' => ['1']
  140. }
  141. }
  142. assert_response :success
  143. assert_query_filters [['tracker_id', '=', '1']]
  144. end
  145. def test_index_with_short_filters
  146. to_test = {
  147. 'status_id' => {
  148. 'o' => { :op => 'o', :values => [''] },
  149. 'c' => { :op => 'c', :values => [''] },
  150. '7' => { :op => '=', :values => ['7'] },
  151. '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
  152. '=7' => { :op => '=', :values => ['7'] },
  153. '!3' => { :op => '!', :values => ['3'] },
  154. '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
  155. 'subject' => {
  156. 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
  157. 'o' => { :op => '=', :values => ['o'] },
  158. '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
  159. '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
  160. 'tracker_id' => {
  161. '3' => { :op => '=', :values => ['3'] },
  162. '=3' => { :op => '=', :values => ['3'] }},
  163. 'start_date' => {
  164. '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
  165. '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
  166. '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
  167. '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
  168. '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
  169. '<t+2' => { :op => '<t+', :values => ['2'] },
  170. '>t+2' => { :op => '>t+', :values => ['2'] },
  171. 't+2' => { :op => 't+', :values => ['2'] },
  172. 't' => { :op => 't', :values => [''] },
  173. 'w' => { :op => 'w', :values => [''] },
  174. '>t-2' => { :op => '>t-', :values => ['2'] },
  175. '<t-2' => { :op => '<t-', :values => ['2'] },
  176. 't-2' => { :op => 't-', :values => ['2'] }},
  177. 'created_on' => {
  178. '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
  179. '<t-2' => { :op => '<t-', :values => ['2'] },
  180. '>t-2' => { :op => '>t-', :values => ['2'] },
  181. 't-2' => { :op => 't-', :values => ['2'] }},
  182. 'cf_1' => {
  183. 'c' => { :op => '=', :values => ['c'] },
  184. '!c' => { :op => '!', :values => ['c'] },
  185. '!*' => { :op => '!*', :values => [''] },
  186. '*' => { :op => '*', :values => [''] }},
  187. 'estimated_hours' => {
  188. '=13.4' => { :op => '=', :values => ['13.4'] },
  189. '>=45' => { :op => '>=', :values => ['45'] },
  190. '<=125' => { :op => '<=', :values => ['125'] },
  191. '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
  192. '!*' => { :op => '!*', :values => [''] },
  193. '*' => { :op => '*', :values => [''] }}
  194. }
  195. default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
  196. to_test.each do |field, expression_and_expected|
  197. expression_and_expected.each do |filter_expression, expected|
  198. get :index, :params => {
  199. :set_filter => 1, field => filter_expression
  200. }
  201. assert_response :success
  202. expected_with_default = default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}})
  203. assert_query_filters expected_with_default.map {|f, v| [f, v[:operator], v[:values]]}
  204. end
  205. end
  206. end
  207. def test_index_with_project_and_empty_filters
  208. get :index, :params => {
  209. :project_id => 1,
  210. :set_filter => 1,
  211. :fields => ['']
  212. }
  213. assert_response :success
  214. # no filter
  215. assert_query_filters []
  216. end
  217. def test_index_with_project_custom_field_filter
  218. field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
  219. CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
  220. CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
  221. filter_name = "project.cf_#{field.id}"
  222. @request.session[:user_id] = 1
  223. get :index, :params => {
  224. :set_filter => 1,
  225. :f => [filter_name],
  226. :op => {
  227. filter_name => '='
  228. },
  229. :v => {
  230. filter_name => ['Foo']
  231. },
  232. :c => ['project']
  233. }
  234. assert_response :success
  235. assert_equal [3, 5], issues_in_list.map(&:project_id).uniq.sort
  236. end
  237. def test_index_with_project_status_filter
  238. project = Project.find(2)
  239. project.close
  240. project.save
  241. get :index, :params => {
  242. :set_filter => 1,
  243. :f => ['project.status'],
  244. :op => {'project.status' => '='},
  245. :v => {'project.status' => ['1']}
  246. }
  247. assert_response :success
  248. issues = issues_in_list.map(&:id).uniq.sort
  249. assert_include 1, issues
  250. assert_not_include 4, issues
  251. end
  252. def test_index_with_query
  253. get :index, :params => {
  254. :project_id => 1,
  255. :query_id => 5
  256. }
  257. assert_response :success
  258. end
  259. def test_index_with_query_grouped_by_tracker
  260. get :index, :params => {
  261. :project_id => 1,
  262. :query_id => 6
  263. }
  264. assert_response :success
  265. assert_select 'tr.group span.count'
  266. end
  267. def test_index_with_query_grouped_and_sorted_by_category
  268. get :index, :params => {
  269. :project_id => 1,
  270. :set_filter => 1,
  271. :group_by => "category",
  272. :sort => "category"
  273. }
  274. assert_response :success
  275. assert_select 'tr.group span.count'
  276. end
  277. def test_index_with_query_grouped_and_sorted_by_fixed_version
  278. get :index, :params => {
  279. :project_id => 1,
  280. :set_filter => 1,
  281. :group_by => "fixed_version",
  282. :sort => "fixed_version"
  283. }
  284. assert_response :success
  285. assert_select 'tr.group span.count'
  286. end
  287. def test_index_with_query_grouped_and_sorted_by_fixed_version_in_reverse_order
  288. get :index, :params => {
  289. :project_id => 1,
  290. :set_filter => 1,
  291. :group_by => "fixed_version",
  292. :sort => "fixed_version:desc"
  293. }
  294. assert_response :success
  295. assert_select 'tr.group span.count'
  296. end
  297. def test_index_grouped_by_due_date
  298. Issue.destroy_all
  299. Issue.generate!(:due_date => '2018-08-10')
  300. Issue.generate!(:due_date => '2018-08-10')
  301. Issue.generate!
  302. get :index, :params => {
  303. :set_filter => 1,
  304. :group_by => "due_date"
  305. }
  306. assert_response :success
  307. assert_select 'tr.group span.name', :value => '2018-08-10' do
  308. assert_select '~ span.count', value:'2'
  309. end
  310. assert_select 'tr.group span.name', :value => '(blank)' do
  311. assert_select '~ span.count', value:'1'
  312. end
  313. end
  314. def test_index_grouped_by_created_on_if_time_zone_is_utc
  315. # TODO: test fails with mysql
  316. skip if mysql?
  317. skip unless IssueQuery.new.groupable_columns.detect {|c| c.name == :created_on}
  318. @request.session[:user_id] = 2
  319. User.find(2).pref.update(time_zone: 'UTC')
  320. get :index, :params => {
  321. :set_filter => 1,
  322. :group_by => 'created_on'
  323. }
  324. assert_response :success
  325. assert_select 'tr.group span.name', :text => '07/19/2006' do
  326. assert_select '+ span.count', :text => '2'
  327. end
  328. end
  329. def test_index_grouped_by_created_on_if_time_zone_is_nil
  330. skip unless IssueQuery.new.groupable_columns.detect {|c| c.name == :created_on}
  331. current_user = User.find(2)
  332. @request.session[:user_id] = current_user.id
  333. current_user.pref.update(time_zone: nil)
  334. get :index, :params => {
  335. :set_filter => 1,
  336. :group_by => 'created_on'
  337. }
  338. assert_response :success
  339. # group_name depends on localtime
  340. group_name = format_date(Issue.second.created_on.localtime)
  341. assert_select 'tr.group span.name', :text => group_name do
  342. assert_select '+ span.count', :text => '2'
  343. end
  344. end
  345. def test_index_grouped_by_created_on_as_pdf
  346. skip unless IssueQuery.new.groupable_columns.detect {|c| c.name == :created_on}
  347. get :index, :params => {
  348. :set_filter => 1,
  349. :group_by => 'created_on',
  350. :format => 'pdf'
  351. }
  352. assert_response :success
  353. assert_equal 'application/pdf', response.content_type
  354. end
  355. def test_index_with_query_grouped_by_list_custom_field
  356. get :index, :params => {
  357. :project_id => 1,
  358. :query_id => 9
  359. }
  360. assert_response :success
  361. assert_select 'tr.group span.count'
  362. end
  363. def test_index_with_query_grouped_by_key_value_custom_field
  364. cf = IssueCustomField.create!(:name => 'Key', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'enumeration')
  365. cf.enumerations << valueb = CustomFieldEnumeration.new(:name => 'Value B', :position => 1)
  366. cf.enumerations << valuea = CustomFieldEnumeration.new(:name => 'Value A', :position => 2)
  367. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => valueb.id)
  368. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => valueb.id)
  369. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => valuea.id)
  370. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  371. get :index, :params => {
  372. :project_id => 1,
  373. :set_filter => 1,
  374. :group_by => "cf_#{cf.id}"
  375. }
  376. assert_response :success
  377. assert_select 'tr.group', 3
  378. assert_select 'tr.group' do
  379. assert_select 'span.name', :text => 'Value B'
  380. assert_select 'span.count', :text => '2'
  381. end
  382. assert_select 'tr.group' do
  383. assert_select 'span.name', :text => 'Value A'
  384. assert_select 'span.count', :text => '1'
  385. end
  386. end
  387. def test_index_with_query_grouped_by_user_custom_field
  388. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  389. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  390. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  391. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  392. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  393. get :index, :params => {
  394. :project_id => 1,
  395. :set_filter => 1,
  396. :group_by => "cf_#{cf.id}"
  397. }
  398. assert_response :success
  399. assert_select 'tr.group', 3
  400. assert_select 'tr.group' do
  401. assert_select 'a', :text => 'John Smith'
  402. assert_select 'span.count', :text => '1'
  403. end
  404. assert_select 'tr.group' do
  405. assert_select 'a', :text => 'Dave Lopper'
  406. assert_select 'span.count', :text => '2'
  407. end
  408. end
  409. def test_index_grouped_by_boolean_custom_field_should_distinguish_blank_and_false_values
  410. cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool')
  411. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '1')
  412. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
  413. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '')
  414. with_settings :default_language => 'en' do
  415. get :index, :params => {
  416. :project_id => 1,
  417. :set_filter => 1,
  418. :group_by => "cf_#{cf.id}"
  419. }
  420. assert_response :success
  421. end
  422. assert_select 'tr.group', 3
  423. assert_select 'tr.group', :text => /Yes/
  424. assert_select 'tr.group', :text => /No/
  425. assert_select 'tr.group', :text => /blank/
  426. end
  427. def test_index_grouped_by_boolean_custom_field_with_false_group_in_first_position_should_show_the_group
  428. cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool', :is_filter => true)
  429. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '0')
  430. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
  431. with_settings :default_language => 'en' do
  432. get :index, :params => {
  433. :project_id => 1,
  434. :set_filter => 1, "cf_#{cf.id}" => "*",
  435. :group_by => "cf_#{cf.id}"
  436. }
  437. assert_response :success
  438. end
  439. assert_equal [1, 2], issues_in_list.map(&:id).sort
  440. assert_select 'tr.group', 1
  441. assert_select 'tr.group', :text => /No/
  442. end
  443. def test_index_with_query_grouped_by_tracker_in_normal_order
  444. 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
  445. get :index, :params => {
  446. :set_filter => 1,
  447. :group_by => 'tracker',
  448. :sort => 'id:desc'
  449. }
  450. assert_response :success
  451. assert_equal ["Bug", "Feature request", "Support request"],
  452. css_select("tr.issue td.tracker").map(&:text).uniq
  453. end
  454. def test_index_with_query_grouped_by_tracker_in_reverse_order
  455. 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
  456. get :index, :params => {
  457. :set_filter => 1,
  458. :group_by => 'tracker',
  459. :c => ['tracker', 'subject'],
  460. :sort => 'id:desc,tracker:desc'
  461. }
  462. assert_response :success
  463. assert_equal ["Bug", "Feature request", "Support request"].reverse,
  464. css_select("tr.issue td.tracker").map(&:text).uniq
  465. end
  466. def test_index_with_query_id_and_project_id_should_set_session_query
  467. get :index, :params => {
  468. :project_id => 1,
  469. :query_id => 4
  470. }
  471. assert_response :success
  472. assert_kind_of Hash, session[:issue_query]
  473. assert_equal 4, session[:issue_query][:id]
  474. assert_equal 1, session[:issue_query][:project_id]
  475. end
  476. def test_index_with_invalid_query_id_should_respond_404
  477. get :index, :params => {
  478. :project_id => 1,
  479. :query_id => 999
  480. }
  481. assert_response 404
  482. end
  483. def test_index_with_cross_project_query_in_session_should_show_project_issues
  484. q = IssueQuery.create!(:name => "cross_project_query", :user_id => 2, :project => nil, :column_names => ['project'])
  485. @request.session[:issue_query] = {:id => q.id, :project_id => 1}
  486. with_settings :display_subprojects_issues => '0' do
  487. get :index, :params => {
  488. :project_id => 1
  489. }
  490. end
  491. assert_response :success
  492. assert_select 'h2', :text => q.name
  493. assert_equal ["eCookbook"], css_select("tr.issue td.project").map(&:text).uniq
  494. end
  495. def test_private_query_should_not_be_available_to_other_users
  496. q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
  497. @request.session[:user_id] = 3
  498. get :index, :params => {
  499. :query_id => q.id
  500. }
  501. assert_response 403
  502. end
  503. def test_private_query_should_be_available_to_its_user
  504. q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
  505. @request.session[:user_id] = 2
  506. get :index, :params => {
  507. :query_id => q.id
  508. }
  509. assert_response :success
  510. end
  511. def test_public_query_should_be_available_to_other_users
  512. q = IssueQuery.create!(:name => "public", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
  513. @request.session[:user_id] = 3
  514. get :index, :params => {
  515. :query_id => q.id
  516. }
  517. assert_response :success
  518. end
  519. def test_index_should_omit_page_param_in_export_links
  520. get :index, :params => {
  521. :page => 2
  522. }
  523. assert_response :success
  524. assert_select 'a.atom[href="/issues.atom"]'
  525. assert_select 'a.csv[href="/issues.csv"]'
  526. assert_select 'a.pdf[href="/issues.pdf"]'
  527. assert_select 'form#csv-export-form[action="/issues.csv"]'
  528. end
  529. def test_index_should_not_warn_when_not_exceeding_export_limit
  530. with_settings :issues_export_limit => 200 do
  531. get :index
  532. assert_select '#csv-export-options p.icon-warning', 0
  533. end
  534. end
  535. def test_index_should_warn_when_exceeding_export_limit
  536. with_settings :issues_export_limit => 2 do
  537. get :index
  538. assert_select '#csv-export-options p.icon-warning', :text => %r{limit: 2}
  539. end
  540. end
  541. def test_index_should_include_query_params_as_hidden_fields_in_csv_export_form
  542. get :index, :params => {
  543. :project_id => 1,
  544. :set_filter => "1",
  545. :tracker_id => "2",
  546. :sort => 'status',
  547. :c => ["status", "priority"]
  548. }
  549. assert_select '#csv-export-form[action=?]', '/projects/ecookbook/issues.csv'
  550. assert_select '#csv-export-form[method=?]', 'get'
  551. assert_select '#csv-export-form' do
  552. assert_select 'input[name=?][value=?]', 'set_filter', '1'
  553. assert_select 'input[name=?][value=?]', 'f[]', 'tracker_id'
  554. assert_select 'input[name=?][value=?]', 'op[tracker_id]', '='
  555. assert_select 'input[name=?][value=?]', 'v[tracker_id][]', '2'
  556. assert_select 'input[name=?][value=?]', 'c[]', 'status'
  557. assert_select 'input[name=?][value=?]', 'c[]', 'priority'
  558. assert_select 'input[name=?][value=?]', 'sort', 'status'
  559. end
  560. get :index, :params => {
  561. :project_id => 1,
  562. :set_filter => "1",
  563. :f => ['']
  564. }
  565. assert_select '#csv-export-form input[name=?][value=?]', 'f[]', ''
  566. end
  567. def test_index_csv
  568. get :index, :params => {
  569. :format => 'csv'
  570. }
  571. assert_response :success
  572. assert_equal 'text/csv', @response.content_type
  573. assert response.body.starts_with?("#,")
  574. lines = response.body.chomp.split("\n")
  575. # default columns + id and project
  576. assert_equal Setting.issue_list_default_columns.size + 2, lines[0].split(',').size
  577. end
  578. def test_index_csv_with_project
  579. get :index, :params => {
  580. :project_id => 1,
  581. :format => 'csv'
  582. }
  583. assert_response :success
  584. assert_equal 'text/csv', @response.content_type
  585. end
  586. def test_index_csv_without_any_filters
  587. @request.session[:user_id] = 1
  588. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5, :subject => 'Closed issue', :author_id => 1)
  589. get :index, :params => {
  590. :set_filter => 1,
  591. :f => [''],
  592. :format => 'csv'
  593. }
  594. assert_response :success
  595. # -1 for headers
  596. assert_equal Issue.count, response.body.chomp.split("\n").size - 1
  597. end
  598. def test_index_csv_with_description
  599. Issue.generate!(:description => 'test_index_csv_with_description')
  600. with_settings :default_language => 'en' do
  601. get :index, :params => {
  602. :format => 'csv',
  603. :c => [:tracker,
  604. :description]
  605. }
  606. assert_response :success
  607. end
  608. assert_equal 'text/csv', response.content_type
  609. headers = response.body.chomp.split("\n").first.split(',')
  610. assert_include 'Description', headers
  611. assert_include 'test_index_csv_with_description', response.body
  612. end
  613. def test_index_csv_with_spent_time_column
  614. issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
  615. TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
  616. get :index, :params => {
  617. :format => 'csv',
  618. :set_filter => '1',
  619. :c => %w(subject spent_hours)
  620. }
  621. assert_response :success
  622. assert_equal 'text/csv', @response.content_type
  623. lines = @response.body.chomp.split("\n")
  624. assert_include "#{issue.id},#{issue.subject},7.33", lines
  625. end
  626. def test_index_csv_with_all_columns
  627. get :index, :params => {
  628. :format => 'csv',
  629. :c => ['all_inline']
  630. }
  631. assert_response :success
  632. assert_equal 'text/csv', @response.content_type
  633. assert_match /\A#,/, response.body
  634. lines = response.body.chomp.split("\n")
  635. assert_equal IssueQuery.new.available_inline_columns.size, lines[0].split(',').size
  636. end
  637. def test_index_csv_with_multi_column_field
  638. CustomField.find(1).update_attribute :multiple, true
  639. issue = Issue.find(1)
  640. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  641. issue.save!
  642. get :index, :params => {
  643. :format => 'csv',
  644. :c => ['tracker', "cf_1"]
  645. }
  646. assert_response :success
  647. lines = @response.body.chomp.split("\n")
  648. assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
  649. end
  650. def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
  651. field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
  652. issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
  653. with_settings :default_language => 'fr' do
  654. get :index, :params => {
  655. :format => 'csv',
  656. :c => ['id', 'tracker', "cf_#{field.id}"]
  657. }
  658. assert_response :success
  659. issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
  660. assert_include '185,60', issue_line
  661. end
  662. with_settings :default_language => 'en' do
  663. get :index, :params => {
  664. :format => 'csv',
  665. :c => ['id', 'tracker', "cf_#{field.id}"]
  666. }
  667. assert_response :success
  668. issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
  669. assert_include '185.60', issue_line
  670. end
  671. end
  672. def test_index_csv_should_fill_parent_column_with_parent_id
  673. Issue.delete_all
  674. parent = Issue.generate!
  675. child = Issue.generate!(:parent_issue_id => parent.id)
  676. with_settings :default_language => 'en' do
  677. get :index, :params => {
  678. :format => 'csv',
  679. :c => %w(parent)
  680. }
  681. end
  682. lines = response.body.split("\n")
  683. assert_include "#{child.id},#{parent.id}", lines
  684. end
  685. def test_index_csv_big_5
  686. with_settings :default_language => "zh-TW" do
  687. str_utf8 = '一月'
  688. str_big5 = (+"\xa4@\xa4\xeb").force_encoding('Big5')
  689. issue = Issue.generate!(:subject => str_utf8)
  690. get :index, :params => {
  691. :project_id => 1,
  692. :subject => str_utf8,
  693. :format => 'csv'
  694. }
  695. assert_equal 'text/csv', @response.content_type
  696. lines = @response.body.chomp.split("\n")
  697. header = lines[0]
  698. status = (+"\xaa\xac\xbaA").force_encoding('Big5')
  699. assert_include status, header
  700. issue_line = lines.find {|l| l =~ /^#{issue.id},/}
  701. assert_include str_big5, issue_line
  702. end
  703. end
  704. def test_index_csv_cannot_convert_should_be_replaced_big_5
  705. with_settings :default_language => "zh-TW" do
  706. str_utf8 = '以内'
  707. issue = Issue.generate!(:subject => str_utf8)
  708. get :index, :params => {
  709. :project_id => 1,
  710. :subject => str_utf8,
  711. :c => ['status', 'subject'],
  712. :format => 'csv',
  713. :set_filter => 1
  714. }
  715. assert_equal 'text/csv', @response.content_type
  716. lines = @response.body.chomp.split("\n")
  717. header = lines[0]
  718. issue_line = lines.find {|l| l =~ /^#{issue.id},/}
  719. s1 = (+"\xaa\xac\xbaA").force_encoding('Big5') # status
  720. assert header.include?(s1)
  721. s2 = issue_line.split(",")[2]
  722. s3 = (+"\xa5H?").force_encoding('Big5') # subject
  723. assert_equal s3, s2
  724. end
  725. end
  726. def test_index_csv_tw
  727. with_settings :default_language => "zh-TW" do
  728. str1 = "test_index_csv_tw"
  729. issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
  730. get :index, :params => {
  731. :project_id => 1,
  732. :subject => str1,
  733. :c => ['estimated_hours', 'subject'],
  734. :format => 'csv',
  735. :set_filter => 1
  736. }
  737. assert_equal 'text/csv', @response.content_type
  738. lines = @response.body.chomp.split("\n")
  739. assert_include "#{issue.id},1234.50,#{str1}", lines
  740. end
  741. end
  742. def test_index_csv_fr
  743. with_settings :default_language => "fr" do
  744. str1 = "test_index_csv_fr"
  745. issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
  746. get :index, :params => {
  747. :project_id => 1,
  748. :subject => str1,
  749. :c => ['estimated_hours', 'subject'],
  750. :format => 'csv',
  751. :set_filter => 1
  752. }
  753. assert_equal 'text/csv', @response.content_type
  754. lines = @response.body.chomp.split("\n")
  755. assert_include "#{issue.id};1234,50;#{str1}", lines
  756. end
  757. end
  758. def test_index_csv_should_not_change_selected_columns
  759. get :index, :params => {
  760. :set_filter => 1,
  761. :c => ["subject", "due_date"],
  762. :project_id => "ecookbook"
  763. }
  764. assert_response :success
  765. assert_equal [:subject, :due_date], session[:issue_query][:column_names]
  766. get :index, :params => {
  767. :set_filter => 1,
  768. :c =>["all_inline"],
  769. :project_id => "ecookbook",
  770. :format => 'csv'
  771. }
  772. assert_response :success
  773. assert_equal [:subject, :due_date], session[:issue_query][:column_names]
  774. end
  775. def test_index_pdf
  776. ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
  777. with_settings :default_language => lang do
  778. get :index
  779. assert_response :success
  780. get :index, :params => {
  781. :format => 'pdf'
  782. }
  783. assert_response :success
  784. assert_equal 'application/pdf', @response.content_type
  785. get :index, :params => {
  786. :project_id => 1,
  787. :format => 'pdf'
  788. }
  789. assert_response :success
  790. assert_equal 'application/pdf', @response.content_type
  791. get :index, :params => {
  792. :project_id => 1,
  793. :query_id => 6,
  794. :format => 'pdf'
  795. }
  796. assert_response :success
  797. assert_equal 'application/pdf', @response.content_type
  798. end
  799. end
  800. end
  801. def test_index_pdf_with_query_grouped_by_list_custom_field
  802. get :index, :params => {
  803. :project_id => 1,
  804. :query_id => 9,
  805. :format => 'pdf'
  806. }
  807. assert_response :success
  808. assert_equal 'application/pdf', @response.content_type
  809. end
  810. def test_index_atom
  811. get :index, :params => {
  812. :project_id => 'ecookbook',
  813. :format => 'atom'
  814. }
  815. assert_response :success
  816. assert_equal 'application/atom+xml', response.content_type
  817. assert_select 'feed' do
  818. assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
  819. assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
  820. assert_select 'entry link[href=?]', 'http://test.host/issues/1'
  821. end
  822. end
  823. def test_index_should_include_back_url_input
  824. get :index, :params => {
  825. :project_id => 'ecookbook',
  826. :foo => 'bar'
  827. }
  828. assert_response :success
  829. assert_select 'input[name=back_url][value=?]', '/projects/ecookbook/issues?foo=bar'
  830. end
  831. def test_index_sort
  832. get :index, :params => {
  833. :sort => 'tracker,id:desc'
  834. }
  835. assert_response :success
  836. assert_equal issues_in_list.sort_by {|issue| [issue.tracker.position, -issue.id]}, issues_in_list
  837. assert_select 'table.issues.sort-by-tracker.sort-asc'
  838. end
  839. def test_index_sort_by_field_not_included_in_columns
  840. with_settings :issue_list_default_columns => %w(subject author) do
  841. get :index, :params => {
  842. :sort => 'tracker'
  843. }
  844. assert_response :success
  845. end
  846. end
  847. def test_index_sort_by_assigned_to
  848. get :index, :params => {
  849. :sort => 'assigned_to'
  850. }
  851. assert_response :success
  852. assignees = issues_in_list.map(&:assigned_to).compact
  853. assert_equal assignees.sort, assignees
  854. assert_select 'table.issues.sort-by-assigned-to.sort-asc'
  855. end
  856. def test_index_sort_by_assigned_to_desc
  857. get :index, :params => {
  858. :sort => 'assigned_to:desc'
  859. }
  860. assert_response :success
  861. assignees = issues_in_list.map(&:assigned_to).compact
  862. assert_equal assignees.sort.reverse, assignees
  863. assert_select 'table.issues.sort-by-assigned-to.sort-desc'
  864. end
  865. def test_index_group_by_assigned_to
  866. get :index, :params => {
  867. :group_by => 'assigned_to',
  868. :sort => 'priority'
  869. }
  870. assert_response :success
  871. end
  872. def test_index_sort_by_author
  873. get :index, :params => {
  874. :sort => 'author',
  875. :c => ['author']
  876. }
  877. assert_response :success
  878. authors = issues_in_list.map(&:author)
  879. assert_equal authors.sort, authors
  880. end
  881. def test_index_sort_by_author_desc
  882. get :index, :params => {
  883. :sort => 'author:desc'
  884. }
  885. assert_response :success
  886. authors = issues_in_list.map(&:author)
  887. assert_equal authors.sort.reverse, authors
  888. end
  889. def test_index_group_by_author
  890. get :index, :params => {
  891. :group_by => 'author',
  892. :sort => 'priority'
  893. }
  894. assert_response :success
  895. end
  896. def test_index_sort_by_last_updated_by
  897. get :index, :params => {
  898. :sort => 'last_updated_by'
  899. }
  900. assert_response :success
  901. assert_select 'table.issues.sort-by-last-updated-by.sort-asc'
  902. end
  903. def test_index_sort_by_last_updated_by_desc
  904. get :index, :params => {
  905. :sort => 'last_updated_by:desc'
  906. }
  907. assert_response :success
  908. assert_select 'table.issues.sort-by-last-updated-by.sort-desc'
  909. end
  910. def test_index_sort_by_spent_hours
  911. get :index, :params => {
  912. :sort => 'spent_hours:desc'
  913. }
  914. assert_response :success
  915. hours = issues_in_list.map(&:spent_hours)
  916. assert_equal hours.sort.reverse, hours
  917. end
  918. def test_index_sort_by_spent_hours_should_sort_by_visible_spent_hours
  919. TimeEntry.delete_all
  920. TimeEntry.generate!(:issue => Issue.generate!(:project_id => 1), :hours => 3)
  921. TimeEntry.generate!(:issue => Issue.generate!(:project_id => 3), :hours => 4)
  922. get :index, :params => {:sort => "spent_hours:desc", :c => ['subject','spent_hours']}
  923. assert_response :success
  924. assert_equal ['4.00', '3.00', '0.00'], columns_values_in_list('spent_hours')[0..2]
  925. Project.find(3).disable_module!(:time_tracking)
  926. get :index, :params => {:sort => "spent_hours:desc", :c => ['subject','spent_hours']}
  927. assert_response :success
  928. assert_equal ['3.00', '0.00', '0.00'], columns_values_in_list('spent_hours')[0..2]
  929. end
  930. def test_index_sort_by_total_spent_hours
  931. get :index, :params => {
  932. :sort => 'total_spent_hours:desc'
  933. }
  934. assert_response :success
  935. hours = issues_in_list.map(&:total_spent_hours)
  936. assert_equal hours.sort.reverse, hours
  937. end
  938. def test_index_sort_by_total_estimated_hours
  939. get :index, :params => {
  940. :sort => 'total_estimated_hours:desc'
  941. }
  942. assert_response :success
  943. hours = issues_in_list.map(&:total_estimated_hours)
  944. # Removes nil because the position of NULL is database dependent
  945. hours.compact!
  946. assert_equal hours.sort.reverse, hours
  947. end
  948. def test_index_sort_by_user_custom_field
  949. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  950. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  951. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  952. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  953. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  954. get :index, :params => {
  955. :project_id => 1,
  956. :set_filter => 1,
  957. :sort => "cf_#{cf.id},id"
  958. }
  959. assert_response :success
  960. assert_equal [2, 3, 1], issues_in_list.select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
  961. end
  962. def test_index_with_columns
  963. columns = ['tracker', 'subject', 'assigned_to', 'buttons']
  964. get :index, :params => {
  965. :set_filter => 1,
  966. :c => columns
  967. }
  968. assert_response :success
  969. # query should use specified columns + id and checkbox
  970. assert_select 'table.issues thead' do
  971. assert_select 'th', columns.size + 2
  972. assert_select 'th.tracker'
  973. assert_select 'th.subject'
  974. assert_select 'th.assigned_to'
  975. assert_select 'th.buttons'
  976. end
  977. # columns should be stored in session
  978. assert_kind_of Hash, session[:issue_query]
  979. assert_kind_of Array, session[:issue_query][:column_names]
  980. assert_equal columns, session[:issue_query][:column_names].map(&:to_s)
  981. # ensure only these columns are kept in the selected columns list
  982. assert_select 'select[name=?] option', 'c[]' do
  983. assert_select 'option', 3
  984. assert_select 'option[value=tracker]'
  985. assert_select 'option[value=project]', 0
  986. end
  987. end
  988. def test_index_without_project_should_implicitly_add_project_column_to_default_columns
  989. with_settings :issue_list_default_columns => ['tracker', 'subject', 'assigned_to'] do
  990. get :index, :params => {
  991. :set_filter => 1
  992. }
  993. end
  994. # query should use specified columns
  995. assert_equal ["#", "Project", "Tracker", "Subject", "Assignee"], columns_in_issues_list
  996. end
  997. def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
  998. with_settings :issue_list_default_columns => ['tracker', 'subject', 'assigned_to'] do
  999. columns = ['id', 'tracker', 'subject', 'assigned_to']
  1000. get :index, :params => {
  1001. :set_filter => 1,
  1002. :c => columns
  1003. }
  1004. end
  1005. # query should use specified columns
  1006. assert_equal ["#", "Tracker", "Subject", "Assignee"], columns_in_issues_list
  1007. end
  1008. def test_index_with_default_columns_should_respect_default_columns_order
  1009. columns = ['assigned_to', 'subject', 'status', 'tracker']
  1010. with_settings :issue_list_default_columns => columns do
  1011. get :index, :params => {
  1012. :project_id => 1,
  1013. :set_filter => 1
  1014. }
  1015. assert_equal ["#", "Assignee", "Subject", "Status", "Tracker"], columns_in_issues_list
  1016. end
  1017. end
  1018. def test_index_with_custom_field_column
  1019. columns = %w(tracker subject cf_2)
  1020. get :index, :params => {
  1021. :set_filter => 1,
  1022. :c => columns
  1023. }
  1024. assert_response :success
  1025. # query should use specified columns
  1026. assert_equal ["#", "Tracker", "Subject", "Searchable field"], columns_in_issues_list
  1027. assert_select 'table.issues' do
  1028. assert_select 'th.cf_2.string'
  1029. assert_select 'td.cf_2.string'
  1030. end
  1031. end
  1032. def test_index_with_multi_custom_field_column
  1033. field = CustomField.find(1)
  1034. field.update_attribute :multiple, true
  1035. issue = Issue.find(1)
  1036. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  1037. issue.save!
  1038. get :index, :params => {
  1039. :set_filter => 1,
  1040. :c => %w(tracker subject cf_1)
  1041. }
  1042. assert_response :success
  1043. assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
  1044. end
  1045. def test_index_with_multi_user_custom_field_column
  1046. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  1047. :tracker_ids => [1], :is_for_all => true)
  1048. issue = Issue.find(1)
  1049. issue.custom_field_values = {field.id => ['2', '3']}
  1050. issue.save!
  1051. get :index, :params => {
  1052. :set_filter => 1,
  1053. :c => ['tracker', 'subject', "cf_#{field.id}"]
  1054. }
  1055. assert_response :success
  1056. assert_select "table.issues td.cf_#{field.id}" do
  1057. assert_select 'a', 2
  1058. assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
  1059. assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
  1060. end
  1061. end
  1062. def test_index_with_date_column
  1063. with_settings :date_format => '%d/%m/%Y' do
  1064. Issue.find(1).update_attribute :start_date, '1987-08-24'
  1065. get :index, :params => {
  1066. :set_filter => 1,
  1067. :c => %w(start_date)
  1068. }
  1069. assert_select 'table.issues' do
  1070. assert_select 'th.start_date'
  1071. assert_select 'td.start_date', :text => '24/08/1987'
  1072. end
  1073. end
  1074. end
  1075. def test_index_with_done_ratio_column
  1076. Issue.find(1).update_attribute :done_ratio, 40
  1077. get :index, :params => {
  1078. :set_filter => 1,
  1079. :c => %w(done_ratio)
  1080. }
  1081. assert_select 'table.issues td.done_ratio' do
  1082. assert_select 'table.progress' do
  1083. assert_select 'td.closed[style=?]', 'width: 40%;'
  1084. end
  1085. end
  1086. end
  1087. def test_index_with_spent_hours_column
  1088. Issue.expects(:load_visible_spent_hours).once
  1089. get :index, :params => {
  1090. :set_filter => 1,
  1091. :c => %w(subject spent_hours)
  1092. }
  1093. assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
  1094. end
  1095. def test_index_with_total_spent_hours_column
  1096. Issue.expects(:load_visible_total_spent_hours).once
  1097. get :index, :params => {
  1098. :set_filter => 1,
  1099. :c => %w(subject total_spent_hours)
  1100. }
  1101. assert_select 'table.issues tr#issue-3 td.total_spent_hours', :text => '1.00'
  1102. end
  1103. def test_index_with_total_estimated_hours_column
  1104. get :index, :params => {
  1105. :set_filter => 1,
  1106. :c => %w(subject total_estimated_hours)
  1107. }
  1108. assert_select 'table.issues td.total_estimated_hours'
  1109. end
  1110. def test_index_should_not_show_spent_hours_column_without_permission
  1111. Role.anonymous.remove_permission! :view_time_entries
  1112. get :index, :params => {
  1113. :set_filter => 1,
  1114. :c => %w(subject spent_hours)
  1115. }
  1116. assert_select 'td.spent_hours', 0
  1117. end
  1118. def test_index_with_fixed_version_column
  1119. get :index, :params => {
  1120. :set_filter => 1,
  1121. :c => %w(fixed_version)
  1122. }
  1123. assert_select 'table.issues td.fixed_version' do
  1124. assert_select 'a[href=?]', '/versions/2', :text => 'eCookbook - 1.0'
  1125. end
  1126. end
  1127. def test_index_with_relations_column
  1128. IssueRelation.delete_all
  1129. IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
  1130. IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
  1131. IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
  1132. IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
  1133. get :index, :params => {
  1134. :set_filter => 1,
  1135. :c => %w(subject relations)
  1136. }
  1137. assert_response :success
  1138. assert_select "tr#issue-1 td.relations" do
  1139. assert_select "span", 3
  1140. assert_select "span", :text => "Related to #7"
  1141. assert_select "span", :text => "Related to #8"
  1142. assert_select "span", :text => "Blocks #11"
  1143. end
  1144. assert_select "tr#issue-2 td.relations" do
  1145. assert_select "span", 1
  1146. assert_select "span", :text => "Blocked by #12"
  1147. end
  1148. assert_select "tr#issue-3 td.relations" do
  1149. assert_select "span", 0
  1150. end
  1151. get :index, :params => {
  1152. :set_filter => 1,
  1153. :c => %w(relations),
  1154. :format => 'csv'
  1155. }
  1156. assert_response :success
  1157. assert_equal 'text/csv', response.content_type
  1158. lines = response.body.chomp.split("\n")
  1159. assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
  1160. assert_include '2,Blocked by #12', lines
  1161. assert_include '3,""', lines
  1162. get :index, :params => {
  1163. :set_filter => 1,
  1164. :c => %w(subject relations),
  1165. :format => 'pdf'
  1166. }
  1167. assert_response :success
  1168. assert_equal 'application/pdf', response.content_type
  1169. end
  1170. def test_index_with_description_column
  1171. get :index, :params => {
  1172. :set_filter => 1,
  1173. :c => %w(subject description)
  1174. }
  1175. assert_select 'table.issues thead th', 4 # columns: chekbox + id + subject
  1176. assert_select 'td.description[colspan="4"]', :text => 'Unable to print recipes'
  1177. get :index, :params => {
  1178. :set_filter => 1,
  1179. :c => %w(subject description),
  1180. :format => 'pdf'
  1181. }
  1182. assert_response :success
  1183. assert_equal 'application/pdf', response.content_type
  1184. end
  1185. def test_index_with_last_notes_column
  1186. get :index, :params => {
  1187. :set_filter => 1,
  1188. :c => %w(subject last_notes)
  1189. }
  1190. assert_response :success
  1191. assert_select 'table.issues thead th', 4 # columns: chekbox + id + subject
  1192. assert_select 'td.last_notes[colspan="4"]', :text => 'Some notes with Redmine links: #2, r2.'
  1193. assert_select 'td.last_notes[colspan="4"]', :text => 'A comment with inline image: and a reference to #1 and r2.'
  1194. get :index, :params => {
  1195. :set_filter => 1,
  1196. :c => %w(subject last_notes),
  1197. :format => 'pdf'
  1198. }
  1199. assert_response :success
  1200. assert_equal 'application/pdf', response.content_type
  1201. end
  1202. def test_index_with_last_notes_column_should_display_private_notes_with_permission_only
  1203. journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Public notes', :user_id => 1)
  1204. journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
  1205. @request.session[:user_id] = 2
  1206. get :index, :params => {
  1207. :set_filter => 1,
  1208. :c => %w(subject last_notes)
  1209. }
  1210. assert_response :success
  1211. assert_select 'td.last_notes[colspan="4"]', :text => 'Privates notes'
  1212. Role.find(1).remove_permission! :view_private_notes
  1213. get :index, :params => {
  1214. :set_filter => 1,
  1215. :c => %w(subject last_notes)
  1216. }
  1217. assert_response :success
  1218. assert_select 'td.last_notes[colspan="4"]', :text => 'Public notes'
  1219. end
  1220. def test_index_with_description_and_last_notes_columns_should_display_column_name
  1221. get :index, :params => {
  1222. :set_filter => 1,
  1223. :c => %w(subject last_notes description)
  1224. }
  1225. assert_response :success
  1226. assert_select 'td.last_notes[colspan="4"] span', :text => 'Last notes'
  1227. assert_select 'td.description[colspan="4"] span', :text => 'Description'
  1228. end
  1229. def test_index_with_full_width_layout_custom_field_column_should_show_column_as_block_column
  1230. field = IssueCustomField.create!(:name => 'Long text', :field_format => 'text', :full_width_layout => '1',
  1231. :tracker_ids => [1], :is_for_all => true)
  1232. issue = Issue.find(1)
  1233. issue.custom_field_values = {field.id => 'This is a long text'}
  1234. issue.save!
  1235. get :index, :params => {
  1236. :set_filter => 1,
  1237. :c => ['subject', 'description', "cf_#{field.id}"]
  1238. }
  1239. assert_response :success
  1240. assert_select 'td.description[colspan="4"] span', :text => 'Description'
  1241. assert_select "td.cf_#{field.id} span", :text => 'Long text'
  1242. end
  1243. def test_index_with_parent_column
  1244. Issue.delete_all
  1245. parent = Issue.generate!
  1246. child = Issue.generate!(:parent_issue_id => parent.id)
  1247. get :index, :params => {
  1248. :c => %w(parent)
  1249. }
  1250. assert_select 'td.parent', :text => "#{parent.tracker} ##{parent.id}"
  1251. assert_select 'td.parent a[title=?]', parent.subject
  1252. end
  1253. def test_index_with_parent_subject_column
  1254. Issue.delete_all
  1255. parent = Issue.generate!
  1256. child = Issue.generate!(:parent_issue_id => parent.id)
  1257. get :index, :params => {
  1258. :c => %w(parent.subject)
  1259. }
  1260. assert_select 'table.issues' do
  1261. assert_select 'th.parent-subject', :text => l(:field_parent_issue_subject)
  1262. assert_select "tr#issue-#{child.id}" do
  1263. assert_select 'td.parent-subject', :text => parent.subject
  1264. end
  1265. end
  1266. end
  1267. def test_index_with_last_updated_by_column
  1268. get :index, :params => {
  1269. :c => %w(subject last_updated_by),
  1270. :issue_id => '1,2,3',
  1271. :sort => 'id',
  1272. :set_filter => '1'
  1273. }
  1274. assert_select 'td.last_updated_by'
  1275. assert_equal ["John Smith", "John Smith", ""], css_select('td.last_updated_by').map(&:text)
  1276. end
  1277. def test_index_with_attachments_column
  1278. get :index, :params => {
  1279. :c => %w(subject attachments),
  1280. :set_filter => '1',
  1281. :sort => 'id'
  1282. }
  1283. assert_response :success
  1284. assert_select 'td.attachments'
  1285. assert_select 'tr#issue-2' do
  1286. assert_select 'td.attachments' do
  1287. assert_select 'a', :text => 'source.rb'
  1288. assert_select 'a', :text => 'picture.jpg'
  1289. end
  1290. end
  1291. end
  1292. def test_index_with_attachments_column_as_csv
  1293. get :index, :params => {
  1294. :c => %w(subject attachments),
  1295. :set_filter => '1',
  1296. :sort => 'id',
  1297. :format => 'csv'
  1298. }
  1299. assert_response :success
  1300. assert_include "\"source.rb\npicture.jpg\"", response.body
  1301. end
  1302. def test_index_with_estimated_hours_total
  1303. Issue.delete_all
  1304. Issue.generate!(:estimated_hours => 5.5)
  1305. Issue.generate!(:estimated_hours => 1.1)
  1306. get :index, :params => {
  1307. :t => %w(estimated_hours)
  1308. }
  1309. assert_response :success
  1310. assert_select '.query-totals'
  1311. assert_select '.total-for-estimated-hours span.value', :text => '6.60'
  1312. assert_select 'input[type=checkbox][name=?][value=estimated_hours][checked=checked]', 't[]'
  1313. end
  1314. def test_index_with_grouped_query_and_estimated_hours_total
  1315. Issue.delete_all
  1316. Issue.generate!(:estimated_hours => 5.5, :category_id => 1)
  1317. Issue.generate!(:estimated_hours => 2.3, :category_id => 1)
  1318. Issue.generate!(:estimated_hours => 1.1, :category_id => 2)
  1319. Issue.generate!(:estimated_hours => 4.6)
  1320. get :index, :params => {
  1321. :t => %w(estimated_hours),
  1322. :group_by => 'category'
  1323. }
  1324. assert_response :success
  1325. assert_select '.query-totals'
  1326. assert_select '.query-totals .total-for-estimated-hours span.value', :text => '13.50'
  1327. assert_select 'tr.group', :text => /Printing/ do
  1328. assert_select '.total-for-estimated-hours span.value', :text => '7.80'
  1329. end
  1330. assert_select 'tr.group', :text => /Recipes/ do
  1331. assert_select '.total-for-estimated-hours span.value', :text => '1.10'
  1332. end
  1333. assert_select 'tr.group', :text => /blank/ do
  1334. assert_select '.total-for-estimated-hours span.value', :text => '4.60'
  1335. end
  1336. end
  1337. def test_index_with_int_custom_field_total
  1338. field = IssueCustomField.generate!(:field_format => 'int', :is_for_all => true)
  1339. CustomValue.create!(:customized => Issue.find(1), :custom_field => field, :value => '2')
  1340. CustomValue.create!(:customized => Issue.find(2), :custom_field => field, :value => '7')
  1341. get :index, :params => {
  1342. :t => ["cf_#{field.id}"]
  1343. }
  1344. assert_response :success
  1345. assert_select '.query-totals'
  1346. assert_select ".total-for-cf-#{field.id} span.value", :text => '9'
  1347. end
  1348. def test_index_with_spent_time_total_should_sum_visible_spent_time_only
  1349. TimeEntry.delete_all
  1350. TimeEntry.generate!(:issue => Issue.generate!(:project_id => 1), :hours => 3)
  1351. TimeEntry.generate!(:issue => Issue.generate!(:project_id => 3), :hours => 4)
  1352. get :index, :params => {:t => ["spent_hours"]}
  1353. assert_response :success
  1354. assert_select ".total-for-spent-hours span.value", :text => '7.00'
  1355. Project.find(3).disable_module!(:time_tracking)
  1356. get :index, :params => {:t => ["spent_hours"]}
  1357. assert_response :success
  1358. assert_select ".total-for-spent-hours span.value", :text => '3.00'
  1359. end
  1360. def test_index_totals_should_default_to_settings
  1361. with_settings :issue_list_default_totals => ['estimated_hours'] do
  1362. get :index
  1363. assert_response :success
  1364. assert_select '.total-for-estimated-hours span.value'
  1365. assert_select '.query-totals>span', 1
  1366. end
  1367. end
  1368. def test_index_send_html_if_query_is_invalid
  1369. get :index, :params => {
  1370. :f => ['start_date'],
  1371. :op => {
  1372. :start_date => '='
  1373. }
  1374. }
  1375. assert_equal 'text/html', @response.content_type
  1376. assert_select_error /Start date cannot be blank/i
  1377. end
  1378. def test_index_send_nothing_if_query_is_invalid
  1379. get :index, :params => {
  1380. :f => ['start_date'],
  1381. :op => {
  1382. :start_date => '='
  1383. },
  1384. :format => 'csv'
  1385. }
  1386. assert_equal 'text/csv', @response.content_type
  1387. assert @response.body.blank?
  1388. end
  1389. def test_index_should_include_new_issue_link
  1390. @request.session[:user_id] = 2
  1391. get :index, :params => {
  1392. :project_id => 1
  1393. }
  1394. assert_select '#content a.new-issue[href="/projects/ecookbook/issues/new"]', :text => 'New issue'
  1395. end
  1396. def test_index_should_not_include_new_issue_link_for_project_without_trackers
  1397. Project.find(1).trackers.clear
  1398. @request.session[:user_id] = 2
  1399. get :index, :params => {
  1400. :project_id => 1
  1401. }
  1402. assert_select '#content a.new-issue', 0
  1403. end
  1404. def test_index_should_not_include_new_issue_link_for_users_with_copy_issues_permission_only
  1405. role = Role.find(1)
  1406. role.remove_permission! :add_issues
  1407. role.add_permission! :copy_issues
  1408. @request.session[:user_id] = 2
  1409. get :index, :params => {
  1410. :project_id => 1
  1411. }
  1412. assert_select '#content a.new-issue', 0
  1413. end
  1414. def test_index_without_project_should_include_new_issue_link
  1415. @request.session[:user_id] = 2
  1416. get :index
  1417. assert_select '#content a.new-issue[href="/issues/new"]', :text => 'New issue'
  1418. end
  1419. def test_index_should_not_include_new_issue_tab_when_disabled
  1420. with_settings :new_item_menu_tab => '0' do
  1421. @request.session[:user_id] = 2
  1422. get :index, :params => {
  1423. :project_id => 1
  1424. }
  1425. assert_select '#main-menu a.new-issue', 0
  1426. end
  1427. end
  1428. def test_index_should_include_new_issue_tab_when_enabled
  1429. with_settings :new_item_menu_tab => '1' do
  1430. @request.session[:user_id] = 2
  1431. get :index, :params => {
  1432. :project_id => 1
  1433. }
  1434. assert_select '#main-menu a.new-issue[href="/projects/ecookbook/issues/new"]', :text => 'New issue'
  1435. end
  1436. end
  1437. def test_new_should_have_new_issue_tab_as_current_menu_item
  1438. with_settings :new_item_menu_tab => '1' do
  1439. @request.session[:user_id] = 2
  1440. get :new, :params => {
  1441. :project_id => 1
  1442. }
  1443. assert_select '#main-menu a.new-issue.selected'
  1444. end
  1445. end
  1446. def test_index_should_not_include_new_issue_tab_for_project_without_trackers
  1447. with_settings :new_item_menu_tab => '1' do
  1448. Project.find(1).trackers.clear
  1449. @request.session[:user_id] = 2
  1450. get :index, :params => {
  1451. :project_id => 1
  1452. }
  1453. assert_select '#main-menu a.new-issue', 0
  1454. end
  1455. end
  1456. def test_index_should_not_include_new_issue_tab_for_users_with_copy_issues_permission_only
  1457. with_settings :new_item_menu_tab => '1' do
  1458. role = Role.find(1)
  1459. role.remove_permission! :add_issues
  1460. role.add_permission! :copy_issues
  1461. @request.session[:user_id] = 2
  1462. get :index, :params => {
  1463. :project_id => 1
  1464. }
  1465. assert_select '#main-menu a.new-issue', 0
  1466. end
  1467. end
  1468. def test_show_by_anonymous
  1469. get :show, :params => {
  1470. :id => 1
  1471. }
  1472. assert_response :success
  1473. assert_select 'div.issue div.description', :text => /Unable to print recipes/
  1474. # anonymous role is allowed to add a note
  1475. assert_select 'form#issue-form' do
  1476. assert_select 'fieldset' do
  1477. assert_select 'legend', :text => 'Notes'
  1478. assert_select 'textarea[name=?]', 'issue[notes]'
  1479. end
  1480. end
  1481. assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
  1482. end
  1483. def test_show_by_manager
  1484. @request.session[:user_id] = 2
  1485. get :show, :params => {
  1486. :id => 1
  1487. }
  1488. assert_select 'a', :text => /Quote/
  1489. assert_select 'form#issue-form' do
  1490. assert_select 'fieldset' do
  1491. assert_select 'legend', :text => 'Change properties'
  1492. assert_select 'input[name=?]', 'issue[subject]'
  1493. end
  1494. assert_select 'fieldset' do
  1495. assert_select 'legend', :text => 'Log time'
  1496. assert_select 'input[name=?]', 'time_entry[hours]'
  1497. end
  1498. assert_select 'fieldset' do
  1499. assert_select 'legend', :text => 'Notes'
  1500. assert_select 'textarea[name=?]', 'issue[notes]'
  1501. end
  1502. end
  1503. end
  1504. def test_show_should_display_update_form
  1505. @request.session[:user_id] = 2
  1506. get :show, :params => {
  1507. :id => 1
  1508. }
  1509. assert_response :success
  1510. assert_select 'form#issue-form' do
  1511. assert_select 'input[name=?]', 'issue[is_private]'
  1512. assert_select 'select[name=?]', 'issue[project_id]'
  1513. assert_select 'select[name=?]', 'issue[tracker_id]'
  1514. assert_select 'input[name=?]', 'issue[subject]'
  1515. assert_select 'textarea[name=?]', 'issue[description]'
  1516. assert_select 'select[name=?]', 'issue[status_id]'
  1517. assert_select 'select[name=?]', 'issue[priority_id]'
  1518. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  1519. assert_select 'select[name=?]', 'issue[category_id]'
  1520. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  1521. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  1522. assert_select 'input[name=?]', 'issue[start_date]'
  1523. assert_select 'input[name=?]', 'issue[due_date]'
  1524. assert_select 'select[name=?]', 'issue[done_ratio]'
  1525. assert_select 'input[name=?]', 'issue[custom_field_values][2]'
  1526. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  1527. assert_select 'textarea[name=?]', 'issue[notes]'
  1528. end
  1529. end
  1530. def test_show_should_display_update_form_with_minimal_permissions
  1531. Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
  1532. WorkflowTransition.where(:role_id => 1).delete_all
  1533. @request.session[:user_id] = 2
  1534. get :show, :params => {
  1535. :id => 1
  1536. }
  1537. assert_response :success
  1538. assert_select 'form#issue-form' do
  1539. assert_select 'input[name=?]', 'issue[is_private]', 0
  1540. assert_select 'select[name=?]', 'issue[project_id]', 0
  1541. assert_select 'select[name=?]', 'issue[tracker_id]', 0
  1542. assert_select 'input[name=?]', 'issue[subject]', 0
  1543. assert_select 'textarea[name=?]', 'issue[description]', 0
  1544. assert_select 'select[name=?]', 'issue[status_id]', 0
  1545. assert_select 'select[name=?]', 'issue[priority_id]', 0
  1546. assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
  1547. assert_select 'select[name=?]', 'issue[category_id]', 0
  1548. assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
  1549. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  1550. assert_select 'input[name=?]', 'issue[start_date]', 0
  1551. assert_select 'input[name=?]', 'issue[due_date]', 0
  1552. assert_select 'select[name=?]', 'issue[done_ratio]', 0
  1553. assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
  1554. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  1555. assert_select 'textarea[name=?]', 'issue[notes]'
  1556. end
  1557. end
  1558. def test_show_should_not_display_update_form_without_permissions
  1559. Role.find(1).update_attribute :permissions, [:view_issues]
  1560. @request.session[:user_id] = 2
  1561. get :show, :params => {
  1562. :id => 1
  1563. }
  1564. assert_response :success
  1565. assert_select 'form#issue-form', 0
  1566. end
  1567. def test_update_form_should_not_display_inactive_enumerations
  1568. assert !IssuePriority.find(15).active?
  1569. @request.session[:user_id] = 2
  1570. get :show, :params => {
  1571. :id => 1
  1572. }
  1573. assert_response :success
  1574. assert_select 'form#issue-form' do
  1575. assert_select 'select[name=?]', 'issue[priority_id]' do
  1576. assert_select 'option[value="4"]'
  1577. assert_select 'option[value="15"]', 0
  1578. end
  1579. end
  1580. end
  1581. def test_update_form_should_allow_attachment_upload
  1582. @request.session[:user_id] = 2
  1583. get :show, :params => {
  1584. :id => 1
  1585. }
  1586. assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
  1587. assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
  1588. end
  1589. end
  1590. def test_show_should_deny_anonymous_access_without_permission
  1591. Role.anonymous.remove_permission!(:view_issues)
  1592. get :show, :params => {
  1593. :id => 1
  1594. }
  1595. assert_response :redirect
  1596. end
  1597. def test_show_should_deny_anonymous_access_to_private_issue
  1598. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1599. get :show, :params => {
  1600. :id => 1
  1601. }
  1602. assert_response :redirect
  1603. end
  1604. def test_show_should_deny_non_member_access_without_permission
  1605. Role.non_member.remove_permission!(:view_issues)
  1606. @request.session[:user_id] = 9
  1607. get :show, :params => {
  1608. :id => 1
  1609. }
  1610. assert_response 403
  1611. end
  1612. def test_show_should_deny_non_member_access_to_private_issue
  1613. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1614. @request.session[:user_id] = 9
  1615. get :show, :params => {
  1616. :id => 1
  1617. }
  1618. assert_response 403
  1619. end
  1620. def test_show_should_deny_member_access_without_permission
  1621. Role.find(1).remove_permission!(:view_issues)
  1622. @request.session[:user_id] = 2
  1623. get :show, :params => {
  1624. :id => 1
  1625. }
  1626. assert_response 403
  1627. end
  1628. def test_show_should_deny_member_access_to_private_issue_without_permission
  1629. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1630. @request.session[:user_id] = 3
  1631. get :show, :params => {
  1632. :id => 1
  1633. }
  1634. assert_response 403
  1635. end
  1636. def test_show_should_allow_author_access_to_private_issue
  1637. Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
  1638. @request.session[:user_id] = 3
  1639. get :show, :params => {
  1640. :id => 1
  1641. }
  1642. assert_response :success
  1643. end
  1644. def test_show_should_allow_assignee_access_to_private_issue
  1645. Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
  1646. @request.session[:user_id] = 3
  1647. get :show, :params => {
  1648. :id => 1
  1649. }
  1650. assert_response :success
  1651. end
  1652. def test_show_should_allow_member_access_to_private_issue_with_permission
  1653. Issue.where(:id => 1).update_all(["is_private = ?", true])
  1654. User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
  1655. @request.session[:user_id] = 3
  1656. get :show, :params => {
  1657. :id => 1
  1658. }
  1659. assert_response :success
  1660. end
  1661. def test_show_should_format_related_issues_dates
  1662. with_settings :date_format => '%d/%m/%Y' do
  1663. issue = Issue.generate!(:start_date => '2018-11-29', :due_date => '2018-12-01')
  1664. IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => issue, :relation_type => 'relates')
  1665. get :show, :params => {
  1666. :id => 1
  1667. }
  1668. assert_response :success
  1669. assert_select '#relations td.start_date', :text => '29/11/2018'
  1670. assert_select '#relations td.due_date', :text => '01/12/2018'
  1671. end
  1672. end
  1673. def test_show_should_not_disclose_relations_to_invisible_issues
  1674. Setting.cross_project_issue_relations = '1'
  1675. IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
  1676. # Relation to a private project issue
  1677. IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
  1678. get :show, :params => {
  1679. :id => 1
  1680. }
  1681. assert_response :success
  1682. assert_select 'div#relations' do
  1683. assert_select 'a', :text => /#2$/
  1684. assert_select 'a', :text => /#4$/, :count => 0
  1685. end
  1686. end
  1687. def test_show_should_list_subtasks
  1688. Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
  1689. get :show, :params => {
  1690. :id => 1
  1691. }
  1692. assert_response :success
  1693. assert_select 'div#issue_tree' do
  1694. assert_select 'td.subject', :text => /Child Issue/
  1695. end
  1696. end
  1697. def test_show_should_list_parents
  1698. issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
  1699. get :show, :params => {
  1700. :id => issue.id
  1701. }
  1702. assert_response :success
  1703. assert_select 'div.subject' do
  1704. assert_select 'h3', 'Child Issue'
  1705. assert_select 'a[href="/issues/1"]'
  1706. end
  1707. end
  1708. def test_show_should_not_display_prev_next_links_without_query_in_session
  1709. get :show, :params => {
  1710. :id => 1
  1711. }
  1712. assert_response :success
  1713. assert_select 'div.next-prev-links', 0
  1714. end
  1715. def test_show_should_display_prev_next_links_with_query_in_session
  1716. @request.session[:issue_query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil, :sort => [['id', 'asc']]}
  1717. with_settings :display_subprojects_issues => '0' do
  1718. get :show, :params => {
  1719. :id => 3
  1720. }
  1721. end
  1722. assert_response :success
  1723. count = Issue.open.visible.count
  1724. # Previous and next issues for all projects
  1725. assert_select 'div.next-prev-links' do
  1726. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1727. assert_select 'a[href="/issues/5"]', :text => /Next/
  1728. assert_select 'span.position', :text => "3 of #{count}"
  1729. end
  1730. end
  1731. def test_show_should_display_prev_next_links_with_saved_query_in_session
  1732. query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
  1733. :filters => {'status_id' => {:values => ['5'], :operator => '='}},
  1734. :sort_criteria => [['id', 'asc']])
  1735. @request.session[:issue_query] = {:id => query.id, :project_id => nil}
  1736. get :show, :params => {
  1737. :id => 11
  1738. }
  1739. assert_response :success
  1740. # Previous and next issues for all projects
  1741. assert_select 'div.next-prev-links' do
  1742. assert_select 'a[href="/issues/8"]', :text => /Previous/
  1743. assert_select 'a[href="/issues/12"]', :text => /Next/
  1744. end
  1745. end
  1746. def test_show_should_display_prev_next_links_with_query_and_sort_on_association
  1747. @request.session[:issue_query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
  1748. %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
  1749. @request.session[:issue_query][:sort] = [[assoc_sort, 'asc']]
  1750. get :show, :params => {
  1751. :id => 3
  1752. }
  1753. assert_response :success, "Wrong response status for #{assoc_sort} sort"
  1754. assert_select 'div.next-prev-links' do
  1755. assert_select 'a', :text => /(Previous|Next)/
  1756. end
  1757. end
  1758. end
  1759. def test_show_should_display_prev_next_links_with_project_query_in_session
  1760. @request.session[:issue_query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1, :sort => [['id','asc']]}
  1761. with_settings :display_subprojects_issues => '0' do
  1762. get :show, :params => {
  1763. :id => 3
  1764. }
  1765. end
  1766. assert_response :success
  1767. # Previous and next issues inside project
  1768. assert_select 'div.next-prev-links' do
  1769. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1770. assert_select 'a[href="/issues/7"]', :text => /Next/
  1771. end
  1772. end
  1773. def test_show_should_not_display_prev_link_for_first_issue
  1774. @request.session[:issue_query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1, :sort => [['id', 'asc']]}
  1775. with_settings :display_subprojects_issues => '0' do
  1776. get :show, :params => {
  1777. :id => 1
  1778. }
  1779. end
  1780. assert_response :success
  1781. assert_select 'div.next-prev-links' do
  1782. assert_select 'a', :text => /Previous/, :count => 0
  1783. assert_select 'a[href="/issues/2"]', :text => /Next/
  1784. end
  1785. end
  1786. def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
  1787. @request.session[:issue_query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1, :sort => [['id', 'asc']]}
  1788. get :show, :params => {
  1789. :id => 1
  1790. }
  1791. assert_response :success
  1792. assert_select 'a', :text => /Previous/, :count => 0
  1793. assert_select 'a', :text => /Next/, :count => 0
  1794. end
  1795. def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
  1796. cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
  1797. CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
  1798. CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
  1799. CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
  1800. CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
  1801. query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
  1802. :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
  1803. @request.session[:issue_query] = {:id => query.id, :project_id => nil}
  1804. get :show, :params => {
  1805. :id => 3
  1806. }
  1807. assert_response :success
  1808. assert_select 'div.next-prev-links' do
  1809. assert_select 'a[href="/issues/2"]', :text => /Previous/
  1810. assert_select 'a[href="/issues/1"]', :text => /Next/
  1811. end
  1812. end
  1813. def test_show_should_display_prev_next_links_when_request_has_previous_and_next_issue_ids_params
  1814. get :show, :params => {
  1815. :id => 1,
  1816. :prev_issue_id => 1,
  1817. :next_issue_id => 3,
  1818. :issue_position => 2,
  1819. :issue_count => 4
  1820. }
  1821. assert_response :success
  1822. assert_select 'div.next-prev-links' do
  1823. assert_select 'a[href="/issues/1"]', :text => /Previous/
  1824. assert_select 'a[href="/issues/3"]', :text => /Next/
  1825. assert_select 'span.position', :text => "2 of 4"
  1826. end
  1827. end
  1828. def test_show_should_display_category_field_if_categories_are_defined
  1829. Issue.update_all :category_id => nil
  1830. get :show, :params => {
  1831. :id => 1
  1832. }
  1833. assert_response :success
  1834. assert_select '.attributes .category'
  1835. end
  1836. def test_show_should_not_display_category_field_if_no_categories_are_defined
  1837. Project.find(1).issue_categories.delete_all
  1838. get :show, :params => {
  1839. :id => 1
  1840. }
  1841. assert_response :success
  1842. assert_select 'table.attributes .category', 0
  1843. end
  1844. def test_show_should_display_link_to_the_assignee
  1845. get :show, :params => {
  1846. :id => 2
  1847. }
  1848. assert_response :success
  1849. assert_select '.assigned-to' do
  1850. assert_select 'a[href="/users/3"]'
  1851. end
  1852. end
  1853. def test_show_should_display_visible_changesets_from_other_projects
  1854. project = Project.find(2)
  1855. issue = project.issues.first
  1856. issue.changeset_ids = [102]
  1857. issue.save!
  1858. # changesets from other projects should be displayed even if repository
  1859. # is disabled on issue's project
  1860. project.disable_module! :repository
  1861. @request.session[:user_id] = 2
  1862. get :issue_tab, :params => {
  1863. :id => issue.id,
  1864. :name => 'changesets'
  1865. },
  1866. :xhr => true
  1867. assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/3'
  1868. end
  1869. def test_show_should_display_watchers
  1870. @request.session[:user_id] = 2
  1871. Issue.find(1).add_watcher User.find(2)
  1872. get :show, :params => {
  1873. :id => 1
  1874. }
  1875. assert_select 'div#watchers ul' do
  1876. assert_select 'li' do
  1877. assert_select 'a[href="/users/2"]'
  1878. assert_select 'a[class*=delete]'
  1879. end
  1880. end
  1881. end
  1882. def test_show_should_display_watchers_with_gravatars
  1883. @request.session[:user_id] = 2
  1884. Issue.find(1).add_watcher User.find(2)
  1885. with_settings :gravatar_enabled => '1' do
  1886. get :show, :params => {
  1887. :id => 1
  1888. }
  1889. end
  1890. assert_select 'div#watchers ul' do
  1891. assert_select 'li' do
  1892. assert_select 'img.gravatar'
  1893. assert_select 'a[href="/users/2"]'
  1894. assert_select 'a[class*=delete]'
  1895. end
  1896. end
  1897. end
  1898. def test_show_with_thumbnails_enabled_should_display_thumbnails
  1899. @request.session[:user_id] = 2
  1900. with_settings :thumbnails_enabled => '1' do
  1901. get :show, :params => {
  1902. :id => 14
  1903. }
  1904. assert_response :success
  1905. end
  1906. assert_select 'div.thumbnails' do
  1907. assert_select 'a[href="/attachments/16"]' do
  1908. assert_select 'img[src="/attachments/thumbnail/16"]'
  1909. end
  1910. end
  1911. end
  1912. def test_show_with_thumbnails_disabled_should_not_display_thumbnails
  1913. @request.session[:user_id] = 2
  1914. with_settings :thumbnails_enabled => '0' do
  1915. get :show, :params => {
  1916. :id => 14
  1917. }
  1918. assert_response :success
  1919. end
  1920. assert_select 'div.thumbnails', 0
  1921. end
  1922. def test_show_with_multi_custom_field
  1923. field = CustomField.find(1)
  1924. field.update_attribute :multiple, true
  1925. issue = Issue.find(1)
  1926. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  1927. issue.save!
  1928. get :show, :params => {
  1929. :id => 1
  1930. }
  1931. assert_response :success
  1932. assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
  1933. end
  1934. def test_show_with_full_width_layout_custom_field_should_show_field_under_description
  1935. field = IssueCustomField.create!(:name => 'Long text', :field_format => 'text', :full_width_layout => '1',
  1936. :tracker_ids => [1], :is_for_all => true)
  1937. issue = Issue.find(1)
  1938. issue.custom_field_values = {field.id => 'This is a long text'}
  1939. issue.save!
  1940. get :show, :params => {
  1941. :id => 1
  1942. }
  1943. assert_response :success
  1944. # long text custom field should not be render in the attributes div
  1945. assert_select "div.attributes div.attribute.cf_#{field.id} p strong", 0, :text => 'Long text'
  1946. assert_select "div.attributes div.attribute.cf_#{field.id} div.value", 0, :text => 'This is a long text'
  1947. # long text custom field should be render under description field
  1948. assert_select "div.description ~ div.attribute.cf_#{field.id} p strong", :text => 'Long text'
  1949. assert_select "div.description ~ div.attribute.cf_#{field.id} div.value", :text => 'This is a long text'
  1950. end
  1951. def test_show_custom_fields_with_full_text_formatting_should_be_rendered_using_wiki_class
  1952. half_field = IssueCustomField.create!(:name => 'Half width field', :field_format => 'text', :tracker_ids => [1],
  1953. :is_for_all => true, :text_formatting => 'full')
  1954. full_field = IssueCustomField.create!(:name => 'Full width field', :field_format => 'text', :full_width_layout => '1',
  1955. :tracker_ids => [1], :is_for_all => true, :text_formatting => 'full')
  1956. issue = Issue.find(1)
  1957. issue.custom_field_values = {full_field.id => 'This is a long text', half_field.id => 'This is a short text'}
  1958. issue.save!
  1959. get :show, :params => {
  1960. :id => 1
  1961. }
  1962. assert_response :success
  1963. assert_select "div.attribute.cf_#{half_field.id} div.value div.wiki", 1
  1964. assert_select "div.attribute.cf_#{full_field.id} div.value div.wiki", 1
  1965. end
  1966. def test_show_with_multi_user_custom_field
  1967. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  1968. :tracker_ids => [1], :is_for_all => true)
  1969. issue = Issue.find(1)
  1970. issue.custom_field_values = {field.id => ['2', '3']}
  1971. issue.save!
  1972. get :show, :params => {
  1973. :id => 1
  1974. }
  1975. assert_response :success
  1976. assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
  1977. assert_select 'a', :text => 'Dave Lopper'
  1978. assert_select 'a', :text => 'John Smith'
  1979. end
  1980. end
  1981. def test_show_should_not_display_default_value_for_new_custom_field
  1982. prior = Issue.generate!
  1983. field = IssueCustomField.generate!(:name => 'WithDefault', :field_format => 'string', :default_value => 'DEFAULT')
  1984. after = Issue.generate!
  1985. get :show, :params => {:id => prior.id}
  1986. assert_response :success
  1987. assert_select ".cf_#{field.id} .value", :text => ''
  1988. get :show, :params => {:id => after.id}
  1989. assert_response :success
  1990. assert_select ".cf_#{field.id} .value", :text => 'DEFAULT'
  1991. end
  1992. def test_show_should_display_private_notes_with_permission_only
  1993. journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
  1994. @request.session[:user_id] = 2
  1995. get :show, :params => {
  1996. :id => 2
  1997. }
  1998. assert_response :success
  1999. assert_select "#change-#{journal.id}", 1
  2000. Role.find(1).remove_permission! :view_private_notes
  2001. get :show, :params => {
  2002. :id => 2
  2003. }
  2004. assert_response :success
  2005. assert_select "#change-#{journal.id}", 0
  2006. end
  2007. def test_show_should_display_private_notes_created_by_current_user
  2008. User.find(3).roles_for_project(Project.find(1)).each do |role|
  2009. role.remove_permission! :view_private_notes
  2010. end
  2011. visible = Journal.create!(:journalized => Issue.find(2), :notes => 'Private notes', :private_notes => true, :user_id => 3)
  2012. not_visible = Journal.create!(:journalized => Issue.find(2), :notes => 'Private notes', :private_notes => true, :user_id => 1)
  2013. @request.session[:user_id] = 3
  2014. get :show, :params => {
  2015. :id => 2
  2016. }
  2017. assert_response :success
  2018. assert_select "#change-#{visible.id}", 1
  2019. assert_select "#change-#{not_visible.id}", 0
  2020. end
  2021. def test_show_atom
  2022. get :show, :params => {
  2023. :id => 2,
  2024. :format => 'atom'
  2025. }
  2026. assert_response :success
  2027. assert_equal 'application/atom+xml', response.content_type
  2028. # Inline image
  2029. assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
  2030. end
  2031. def test_show_export_to_pdf
  2032. issue = Issue.find(3)
  2033. assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
  2034. get :show, :params => {
  2035. :id => 3,
  2036. :format => 'pdf'
  2037. }
  2038. assert_response :success
  2039. assert_equal 'application/pdf', @response.content_type
  2040. assert @response.body.starts_with?('%PDF')
  2041. end
  2042. def test_export_to_pdf_with_utf8_u_fffd
  2043. issue = Issue.generate!(:subject => "�")
  2044. ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
  2045. with_settings :default_language => lang do
  2046. get :show, :params => {
  2047. :id => issue.id,
  2048. :format => 'pdf'
  2049. }
  2050. assert_response :success
  2051. assert_equal 'application/pdf', @response.content_type
  2052. assert @response.body.starts_with?('%PDF')
  2053. end
  2054. end
  2055. end
  2056. def test_show_export_to_pdf_with_ancestors
  2057. issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  2058. get :show, :params => {
  2059. :id => issue.id,
  2060. :format => 'pdf'
  2061. }
  2062. assert_response :success
  2063. assert_equal 'application/pdf', @response.content_type
  2064. assert @response.body.starts_with?('%PDF')
  2065. end
  2066. def test_show_export_to_pdf_with_descendants
  2067. c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  2068. c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
  2069. c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
  2070. get :show, :params => {
  2071. :id => 1,
  2072. :format => 'pdf'
  2073. }
  2074. assert_response :success
  2075. assert_equal 'application/pdf', @response.content_type
  2076. assert @response.body.starts_with?('%PDF')
  2077. end
  2078. def test_show_export_to_pdf_with_journals
  2079. get :show, :params => {
  2080. :id => 1,
  2081. :format => 'pdf'
  2082. }
  2083. assert_response :success
  2084. assert_equal 'application/pdf', @response.content_type
  2085. assert @response.body.starts_with?('%PDF')
  2086. end
  2087. def test_show_export_to_pdf_with_changesets
  2088. [[100], [100, 101], [100, 101, 102]].each do |cs|
  2089. issue1 = Issue.find(3)
  2090. issue1.changesets = Changeset.find(cs)
  2091. issue1.save!
  2092. issue = Issue.find(3)
  2093. assert_equal issue.changesets.count, cs.size
  2094. get :show, :params => {
  2095. :id => 3,
  2096. :format => 'pdf'
  2097. }
  2098. assert_response :success
  2099. assert_equal 'application/pdf', @response.content_type
  2100. assert @response.body.starts_with?('%PDF')
  2101. end
  2102. end
  2103. def test_show_invalid_should_respond_with_404
  2104. get :show, :params => {
  2105. :id => 999
  2106. }
  2107. assert_response 404
  2108. end
  2109. def test_show_on_active_project_should_display_edit_links
  2110. @request.session[:user_id] = 1
  2111. get :show, :params => {
  2112. :id => 1
  2113. }
  2114. assert_response :success
  2115. assert_select 'a', :text => 'Edit'
  2116. assert_select 'a', :text => 'Delete'
  2117. end
  2118. def test_show_on_closed_project_should_not_display_edit_links
  2119. Issue.find(1).project.close
  2120. @request.session[:user_id] = 1
  2121. get :show, :params => {
  2122. :id => 1
  2123. }
  2124. assert_response :success
  2125. assert_select 'a', :text => 'Edit', :count => 0
  2126. assert_select 'a', :text => 'Delete', :count => 0
  2127. end
  2128. def test_show_should_not_display_history_tabs_for_issue_without_journals
  2129. @request.session[:user_id] = 1
  2130. get :show, :params => {:id => 5}
  2131. assert_response :success
  2132. assert_select '#history div.tabs', 0
  2133. assert_select '#history p.nodata', :text => 'No data to display'
  2134. end
  2135. def test_show_display_only_all_and_notes_tabs_for_issue_with_notes_only
  2136. @request.session[:user_id] = 1
  2137. get :show, :params => {:id => 6}
  2138. assert_response :success
  2139. assert_select '#history' do
  2140. assert_select 'div.tabs ul a', 2
  2141. assert_select 'div.tabs a[id=?]', 'tab-history', :text => 'History'
  2142. assert_select 'div.tabs a[id=?]', 'tab-notes', :text => 'Notes'
  2143. end
  2144. end
  2145. def test_show_display_only_all_and_history_tabs_for_issue_with_history_changes_only
  2146. journal = Journal.create!(:journalized => Issue.find(5), :user_id => 1)
  2147. detail = JournalDetail.create!(:journal => journal, :property => 'attr', :prop_key => 'description',
  2148. :old_value => 'Foo', :value => 'Bar')
  2149. @request.session[:user_id] = 1
  2150. get :show, :params => {:id => 5}
  2151. assert_response :success
  2152. assert_select '#history' do
  2153. assert_select 'div.tabs ul a', 2
  2154. assert_select 'div.tabs a[id=?]', 'tab-history', :text => 'History'
  2155. assert_select 'div.tabs a[id=?]', 'tab-properties', :text => 'Property changes'
  2156. end
  2157. end
  2158. def test_show_display_all_notes_and_history_tabs_for_issue_with_notes_and_history_changes
  2159. journal = Journal.create!(:journalized => Issue.find(6), :user_id => 1)
  2160. detail = JournalDetail.create!(:journal => journal, :property => 'attr', :prop_key => 'description',
  2161. :old_value => 'Foo', :value => 'Bar')
  2162. @request.session[:user_id] = 1
  2163. get :show, :params => {:id => 6}
  2164. assert_response :success
  2165. assert_select '#history' do
  2166. assert_select 'div.tabs ul a', 3
  2167. assert_select 'div.tabs a[id=?]', 'tab-history', :text => 'History'
  2168. assert_select 'div.tabs a[id=?]', 'tab-notes', :text => 'Notes'
  2169. assert_select 'div.tabs a[id=?]', 'tab-properties', :text => 'Property changes'
  2170. end
  2171. end
  2172. def test_show_display_changesets_tab_for_issue_with_changesets
  2173. project = Project.find(2)
  2174. issue = Issue.find(9)
  2175. issue.changeset_ids = [102]
  2176. issue.save!
  2177. @request.session[:user_id] = 2
  2178. get :show, :params => {:id => issue.id}
  2179. assert_select '#history' do
  2180. assert_select 'div.tabs ul a', 1
  2181. assert_select 'div.tabs a[id=?]', 'tab-changesets', :text => 'Associated revisions'
  2182. end
  2183. end
  2184. def test_show_should_display_spent_time_tab_for_issue_with_time_entries
  2185. @request.session[:user_id] = 1
  2186. get :show, :params => {:id => 3}
  2187. assert_response :success
  2188. assert_select '#history' do
  2189. assert_select 'div.tabs ul a', 1
  2190. assert_select 'div.tabs a[id=?]', 'tab-time_entries', :text => 'Spent time'
  2191. end
  2192. get :issue_tab, :params => {
  2193. :id => 3,
  2194. :name => 'time_entries'
  2195. },
  2196. :xhr => true
  2197. assert_response :success
  2198. assert_select 'div[id=?]', 'time-entry-3' do
  2199. assert_select 'a[title=?][href=?]', 'Edit', '/time_entries/3/edit'
  2200. assert_select 'a[title=?][href=?]', 'Delete', '/time_entries/3'
  2201. assert_select 'ul[class=?]', 'details', :text => /1.00 h/
  2202. end
  2203. end
  2204. def test_get_new
  2205. @request.session[:user_id] = 2
  2206. get :new, :params => {
  2207. :project_id => 1,
  2208. :tracker_id => 1
  2209. }
  2210. assert_response :success
  2211. assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
  2212. assert_select 'form#issue-form' do
  2213. assert_select 'input[name=?]', 'issue[is_private]'
  2214. assert_select 'select[name=?]', 'issue[project_id]'
  2215. assert_select 'select[name=?]', 'issue[tracker_id]'
  2216. assert_select 'input[name=?]', 'issue[subject]'
  2217. assert_select 'textarea[name=?]', 'issue[description]'
  2218. assert_select 'select[name=?]', 'issue[status_id]'
  2219. assert_select 'select[name=?]', 'issue[priority_id]'
  2220. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  2221. assert_select 'select[name=?]', 'issue[category_id]'
  2222. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  2223. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  2224. assert_select 'input[name=?]', 'issue[start_date]'
  2225. assert_select 'input[name=?]', 'issue[due_date]'
  2226. assert_select 'select[name=?]', 'issue[done_ratio]'
  2227. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
  2228. assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
  2229. end
  2230. # Be sure we don't display inactive IssuePriorities
  2231. assert ! IssuePriority.find(15).active?
  2232. assert_select 'select[name=?]', 'issue[priority_id]' do
  2233. assert_select 'option[value="15"]', 0
  2234. end
  2235. end
  2236. def test_get_new_should_show_project_selector_for_project_with_subprojects
  2237. @request.session[:user_id] = 2
  2238. get :new, :params => {
  2239. :project_id => 1,
  2240. :tracker_id => 1
  2241. }
  2242. assert_response :success
  2243. assert_select 'select[name="issue[project_id]"]' do
  2244. assert_select 'option', 3
  2245. assert_select 'option[selected=selected]', :text => 'eCookbook'
  2246. assert_select 'option[value=?]', '5', :text => '  » Private child of eCookbook'
  2247. assert_select 'option[value=?]', '3', :text => '  » eCookbook Subproject 1'
  2248. # user_id 2 is not allowed to add issues on project_id 4 (it's not a member)
  2249. assert_select 'option[value=?]', '4', 0
  2250. end
  2251. end
  2252. def test_get_new_should_not_show_project_selector_for_project_without_subprojects
  2253. @request.session[:user_id] = 2
  2254. get :new, :params => {
  2255. :project_id => 2,
  2256. :tracker_id => 1
  2257. }
  2258. assert_response :success
  2259. assert_select 'select[name="issue[project_id]"]', 0
  2260. end
  2261. def test_get_new_with_minimal_permissions
  2262. Role.find(1).update_attribute :permissions, [:add_issues]
  2263. WorkflowTransition.where(:role_id => 1).delete_all
  2264. @request.session[:user_id] = 2
  2265. get :new, :params => {
  2266. :project_id => 1,
  2267. :tracker_id => 1
  2268. }
  2269. assert_response :success
  2270. assert_select 'form#issue-form' do
  2271. assert_select 'input[name=?]', 'issue[is_private]', 0
  2272. assert_select 'select[name=?]', 'issue[project_id]'
  2273. assert_select 'select[name=?]', 'issue[tracker_id]'
  2274. assert_select 'input[name=?]', 'issue[subject]'
  2275. assert_select 'textarea[name=?]', 'issue[description]'
  2276. assert_select 'select[name=?]', 'issue[status_id]'
  2277. assert_select 'select[name=?]', 'issue[priority_id]'
  2278. assert_select 'select[name=?]', 'issue[assigned_to_id]'
  2279. assert_select 'select[name=?]', 'issue[category_id]'
  2280. assert_select 'select[name=?]', 'issue[fixed_version_id]'
  2281. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  2282. assert_select 'input[name=?]', 'issue[start_date]'
  2283. assert_select 'input[name=?]', 'issue[due_date]'
  2284. assert_select 'select[name=?]', 'issue[done_ratio]'
  2285. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
  2286. assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
  2287. end
  2288. end
  2289. def test_new_without_project_id
  2290. @request.session[:user_id] = 2
  2291. get :new
  2292. assert_response :success
  2293. assert_select 'form#issue-form[action=?]', '/issues'
  2294. assert_select 'form#issue-form' do
  2295. assert_select 'select[name=?]', 'issue[project_id]'
  2296. end
  2297. end
  2298. def test_new_with_me_assigned_to_id
  2299. @request.session[:user_id] = 2
  2300. get :new, :params => {
  2301. :issue => { :assigned_to_id => 'me' }
  2302. }
  2303. assert_response :success
  2304. assert_select 'select[name=?]', 'issue[assigned_to_id]' do
  2305. assert_select 'option[value="2"][selected=selected]'
  2306. end
  2307. end
  2308. def test_new_should_select_default_status
  2309. @request.session[:user_id] = 2
  2310. get :new, :params => {
  2311. :project_id => 1
  2312. }
  2313. assert_response :success
  2314. assert_select 'select[name=?]', 'issue[status_id]' do
  2315. assert_select 'option[value="1"][selected=selected]'
  2316. end
  2317. assert_select 'input[name=was_default_status][value="1"]'
  2318. end
  2319. def test_new_should_propose_allowed_statuses
  2320. WorkflowTransition.delete_all
  2321. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
  2322. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
  2323. @request.session[:user_id] = 2
  2324. get :new, :params => {
  2325. :project_id => 1
  2326. }
  2327. assert_response :success
  2328. assert_select 'select[name=?]', 'issue[status_id]' do
  2329. assert_select 'option[value="1"]'
  2330. assert_select 'option[value="3"]'
  2331. assert_select 'option', 2
  2332. assert_select 'option[value="1"][selected=selected]'
  2333. end
  2334. end
  2335. def test_new_should_propose_allowed_statuses_without_default_status_allowed
  2336. WorkflowTransition.delete_all
  2337. WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
  2338. assert_equal 1, Tracker.find(1).default_status_id
  2339. @request.session[:user_id] = 2
  2340. get :new, :params => {
  2341. :project_id => 1
  2342. }
  2343. assert_response :success
  2344. assert_select 'select[name=?]', 'issue[status_id]' do
  2345. assert_select 'option[value="2"]'
  2346. assert_select 'option', 1
  2347. assert_select 'option[value="2"][selected=selected]'
  2348. end
  2349. end
  2350. def test_new_should_propose_allowed_trackers
  2351. role = Role.find(1)
  2352. role.set_permission_trackers 'add_issues', [1, 3]
  2353. role.save!
  2354. @request.session[:user_id] = 2
  2355. get :new, :params => {
  2356. :project_id => 1
  2357. }
  2358. assert_response :success
  2359. assert_select 'select[name=?]', 'issue[tracker_id]' do
  2360. assert_select 'option', 2
  2361. assert_select 'option[value="1"]'
  2362. assert_select 'option[value="3"]'
  2363. end
  2364. end
  2365. def test_new_should_default_to_first_tracker
  2366. @request.session[:user_id] = 2
  2367. get :new, :params => {
  2368. :project_id => 1
  2369. }
  2370. assert_response :success
  2371. assert_select 'select[name=?]', 'issue[tracker_id]' do
  2372. assert_select 'option', 3
  2373. assert_select 'option[value="1"][selected=selected]'
  2374. end
  2375. end
  2376. def test_new_with_parent_issue_id_should_default_to_first_tracker_without_disabled_parent_field
  2377. tracker = Tracker.find(1)
  2378. tracker.core_fields -= ['parent_issue_id']
  2379. tracker.save!
  2380. @request.session[:user_id] = 2
  2381. get :new, :params => {
  2382. :project_id => 1,
  2383. :issue => {
  2384. :parent_issue_id => 1
  2385. }
  2386. }
  2387. assert_response :success
  2388. assert_select 'select[name=?]', 'issue[tracker_id]' do
  2389. assert_select 'option', 2
  2390. assert_select 'option[value="2"][selected=selected]'
  2391. assert_select 'option[value="1"]', 0
  2392. end
  2393. end
  2394. def test_new_without_allowed_trackers_should_respond_with_403
  2395. role = Role.find(1)
  2396. role.set_permission_trackers 'add_issues', []
  2397. role.save!
  2398. @request.session[:user_id] = 2
  2399. get :new, :params => {
  2400. :project_id => 1
  2401. }
  2402. assert_response 403
  2403. end
  2404. def test_new_without_projects_should_respond_with_403
  2405. Project.delete_all
  2406. @request.session[:user_id] = 2
  2407. get :new
  2408. assert_response 403
  2409. assert_select_error /no projects/
  2410. end
  2411. def test_new_without_enabled_trackers_on_projects_should_respond_with_403
  2412. Project.all.each {|p| p.trackers.clear }
  2413. @request.session[:user_id] = 2
  2414. get :new
  2415. assert_response 403
  2416. assert_select_error /no projects/
  2417. end
  2418. def test_new_should_preselect_default_version
  2419. version = Version.generate!(:project_id => 1)
  2420. Project.find(1).update_attribute :default_version_id, version.id
  2421. @request.session[:user_id] = 2
  2422. get :new, :params => {
  2423. :project_id => 1
  2424. }
  2425. assert_response :success
  2426. assert_select 'select[name=?]', 'issue[fixed_version_id]' do
  2427. assert_select 'option[value=?][selected=selected]', version.id.to_s
  2428. end
  2429. end
  2430. def test_get_new_with_list_custom_field
  2431. @request.session[:user_id] = 2
  2432. get :new, :params => {
  2433. :project_id => 1,
  2434. :tracker_id => 1
  2435. }
  2436. assert_response :success
  2437. assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
  2438. assert_select 'option', 4
  2439. assert_select 'option[value=MySQL]', :text => 'MySQL'
  2440. end
  2441. end
  2442. def test_get_new_with_multi_custom_field
  2443. field = IssueCustomField.find(1)
  2444. field.update_attribute :multiple, true
  2445. @request.session[:user_id] = 2
  2446. get :new, :params => {
  2447. :project_id => 1,
  2448. :tracker_id => 1
  2449. }
  2450. assert_response :success
  2451. assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
  2452. assert_select 'option', 3
  2453. assert_select 'option[value=MySQL]', :text => 'MySQL'
  2454. end
  2455. assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
  2456. end
  2457. def test_get_new_with_multi_user_custom_field
  2458. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  2459. :tracker_ids => [1], :is_for_all => true)
  2460. @request.session[:user_id] = 2
  2461. get :new, :params => {
  2462. :project_id => 1,
  2463. :tracker_id => 1
  2464. }
  2465. assert_response :success
  2466. assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
  2467. assert_select 'option', Project.find(1).users.count + 1 # users + 'me'
  2468. assert_select 'option[value="2"]', :text => 'John Smith'
  2469. end
  2470. assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
  2471. end
  2472. def test_get_new_with_date_custom_field
  2473. field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
  2474. @request.session[:user_id] = 2
  2475. get :new, :params => {
  2476. :project_id => 1,
  2477. :tracker_id => 1
  2478. }
  2479. assert_response :success
  2480. assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
  2481. end
  2482. def test_get_new_with_text_custom_field
  2483. field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
  2484. @request.session[:user_id] = 2
  2485. get :new, :params => {
  2486. :project_id => 1,
  2487. :tracker_id => 1
  2488. }
  2489. assert_response :success
  2490. assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
  2491. end
  2492. def test_get_new_without_default_start_date_is_creation_date
  2493. with_settings :default_issue_start_date_to_creation_date => 0 do
  2494. @request.session[:user_id] = 2
  2495. get :new, :params => {
  2496. :project_id => 1,
  2497. :tracker_id => 1
  2498. }
  2499. assert_response :success
  2500. assert_select 'input[name=?]', 'issue[start_date]'
  2501. assert_select 'input[name=?][value]', 'issue[start_date]', 0
  2502. end
  2503. end
  2504. def test_get_new_with_default_start_date_is_creation_date
  2505. with_settings :default_issue_start_date_to_creation_date => 1 do
  2506. @request.session[:user_id] = 2
  2507. get :new, :params => {
  2508. :project_id => 1,
  2509. :tracker_id => 1
  2510. }
  2511. assert_response :success
  2512. assert_select 'input[name=?][value=?]', 'issue[start_date]',
  2513. Date.today.to_s
  2514. end
  2515. end
  2516. def test_get_new_form_should_allow_attachment_upload
  2517. @request.session[:user_id] = 2
  2518. get :new, :params => {
  2519. :project_id => 1,
  2520. :tracker_id => 1
  2521. }
  2522. assert_response :success
  2523. assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
  2524. assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
  2525. end
  2526. end
  2527. def test_get_new_should_prefill_the_form_from_params
  2528. @request.session[:user_id] = 2
  2529. get :new, :params => {
  2530. :project_id => 1,
  2531. :issue => {
  2532. :tracker_id => 3,
  2533. :description => 'Prefilled',
  2534. :custom_field_values => {
  2535. '2' => 'Custom field value'}
  2536. }
  2537. }
  2538. assert_select 'select[name=?]', 'issue[tracker_id]' do
  2539. assert_select 'option[value="3"][selected=selected]'
  2540. end
  2541. assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
  2542. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
  2543. end
  2544. def test_get_new_should_mark_required_fields
  2545. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2546. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2547. WorkflowPermission.delete_all
  2548. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
  2549. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  2550. @request.session[:user_id] = 2
  2551. get :new, :params => {
  2552. :project_id => 1
  2553. }
  2554. assert_response :success
  2555. assert_select 'label[for=issue_start_date]' do
  2556. assert_select 'span[class=required]', 0
  2557. end
  2558. assert_select 'label[for=issue_due_date]' do
  2559. assert_select 'span[class=required]'
  2560. end
  2561. assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
  2562. assert_select 'span[class=required]', 0
  2563. end
  2564. assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
  2565. assert_select 'span[class=required]'
  2566. end
  2567. end
  2568. def test_get_new_should_not_display_readonly_fields
  2569. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2570. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2571. WorkflowPermission.delete_all
  2572. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
  2573. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
  2574. @request.session[:user_id] = 2
  2575. get :new, :params => {
  2576. :project_id => 1
  2577. }
  2578. assert_response :success
  2579. assert_select 'input[name=?]', 'issue[start_date]'
  2580. assert_select 'input[name=?]', 'issue[due_date]', 0
  2581. assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
  2582. assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
  2583. end
  2584. def test_new_with_tracker_set_as_readonly_should_accept_status
  2585. WorkflowPermission.delete_all
  2586. [1, 2].each do |status_id|
  2587. WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
  2588. end
  2589. @request.session[:user_id] = 2
  2590. get :new, :params => {
  2591. :project_id => 1,
  2592. :issue => {
  2593. :status_id => 2
  2594. }
  2595. }
  2596. assert_select 'select[name=?]', 'issue[tracker_id]', 0
  2597. assert_select 'select[name=?]', 'issue[status_id]' do
  2598. assert_select 'option[value=?][selected=selected]', '2'
  2599. end
  2600. end
  2601. def test_get_new_without_tracker_id
  2602. @request.session[:user_id] = 2
  2603. get :new, :params => {
  2604. :project_id => 1
  2605. }
  2606. assert_response :success
  2607. assert_select 'select[name=?]', 'issue[tracker_id]' do
  2608. assert_select 'option[value=?][selected=selected]', Project.find(1).trackers.first.id.to_s
  2609. end
  2610. end
  2611. def test_get_new_with_no_default_status_should_display_an_error
  2612. @request.session[:user_id] = 2
  2613. IssueStatus.delete_all
  2614. get :new, :params => {
  2615. :project_id => 1
  2616. }
  2617. assert_response 500
  2618. assert_select_error /No default issue/
  2619. end
  2620. def test_get_new_with_no_tracker_should_display_an_error
  2621. @request.session[:user_id] = 2
  2622. Tracker.delete_all
  2623. get :new, :params => {
  2624. :project_id => 1
  2625. }
  2626. assert_response 500
  2627. assert_select_error /No tracker/
  2628. end
  2629. def test_new_with_invalid_project_id
  2630. @request.session[:user_id] = 1
  2631. get :new, :params => {
  2632. :project_id => 'invalid'
  2633. }
  2634. assert_response 404
  2635. end
  2636. def test_new_with_parent_id_should_only_propose_valid_trackers
  2637. @request.session[:user_id] = 2
  2638. t = Tracker.find(3)
  2639. assert !t.disabled_core_fields.include?('parent_issue_id')
  2640. get :new, :params => {
  2641. :project_id => 1, issue: { parent_issue_id: 1
  2642. }
  2643. }
  2644. assert_response :success
  2645. assert_select 'option', text: /#{t.name}/, count: 1
  2646. t.core_fields = Tracker::CORE_FIELDS - ['parent_issue_id']
  2647. t.save!
  2648. assert t.disabled_core_fields.include?('parent_issue_id')
  2649. get :new, :params => {
  2650. :project_id => 1, issue: { parent_issue_id: 1
  2651. }
  2652. }
  2653. assert_response :success
  2654. assert_select 'option', text: /#{t.name}/, count: 0
  2655. end
  2656. def test_get_new_should_show_trackers_description
  2657. @request.session[:user_id] = 2
  2658. get :new, :params => {
  2659. :project_id => 1,
  2660. :issue => {
  2661. :tracker_id => 1
  2662. }
  2663. }
  2664. assert_response :success
  2665. assert_select 'form#issue-form' do
  2666. assert_select 'a[title=?]', 'View all trackers description', :text => 'View all trackers description'
  2667. assert_select 'select[name=?][title=?]', 'issue[tracker_id]', 'Description for Bug tracker'
  2668. end
  2669. assert_select 'div#trackers_description' do
  2670. assert_select 'h3', 1, :text => 'Trackers description'
  2671. # only Bug and Feature have descriptions
  2672. assert_select 'dt', 2, :text => 'Bug'
  2673. assert_select 'dd', 2, :text => 'Description for Bug tracker'
  2674. end
  2675. end
  2676. def test_get_new_should_not_show_trackers_description_for_trackers_without_description
  2677. Tracker.update_all(:description => '')
  2678. @request.session[:user_id] = 2
  2679. get :new, :params => {
  2680. :project_id => 1,
  2681. :issue => {
  2682. :tracker_id => 1
  2683. }
  2684. }
  2685. assert_response :success
  2686. assert_select 'form#issue-form' do
  2687. assert_select 'a[title=?]', 'View all trackers description', 0
  2688. assert_select 'select[name=?][title=?]', 'issue[tracker_id]', ''
  2689. end
  2690. assert_select 'div#trackers_description', 0
  2691. end
  2692. def test_update_form_for_new_issue
  2693. @request.session[:user_id] = 2
  2694. post :new, :params => {
  2695. :project_id => 1,
  2696. :issue => {
  2697. :tracker_id => 2,
  2698. :subject => 'This is the test_new issue',
  2699. :description => 'This is the description',
  2700. :priority_id => 5
  2701. }
  2702. },
  2703. :xhr => true
  2704. assert_response :success
  2705. assert_equal 'text/javascript', response.content_type
  2706. assert_include 'This is the test_new issue', response.body
  2707. end
  2708. def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
  2709. @request.session[:user_id] = 2
  2710. WorkflowTransition.delete_all
  2711. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
  2712. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
  2713. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
  2714. post :new, :params => {
  2715. :project_id => 1,
  2716. :issue => {
  2717. :tracker_id => 1,
  2718. :status_id => 5,
  2719. :subject => 'This is an issue'
  2720. }
  2721. }
  2722. assert_select 'select[name=?]', 'issue[status_id]' do
  2723. assert_select 'option[value=?][selected=selected]', '5'
  2724. assert_select 'option[value=?]', '2'
  2725. assert_select 'option', :count => 2
  2726. end
  2727. end
  2728. def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
  2729. @request.session[:user_id] = 2
  2730. tracker = Tracker.find(2)
  2731. tracker.update! :default_status_id => 2
  2732. tracker.generate_transitions! 2 => 1, :clear => true
  2733. post :new, :params => {
  2734. :project_id => 1,
  2735. :issue => {
  2736. :tracker_id => 2,
  2737. :status_id => 1
  2738. },
  2739. :was_default_status => 1
  2740. }
  2741. assert_response :success
  2742. assert_select 'select[name=?]', 'issue[status_id]' do
  2743. assert_select 'option[value=?][selected=selected]', '2'
  2744. end
  2745. end
  2746. def test_update_form_for_new_issue_should_ignore_version_when_changing_project
  2747. version = Version.generate!(:project_id => 1)
  2748. Project.find(1).update_attribute :default_version_id, version.id
  2749. @request.session[:user_id] = 2
  2750. post :new, :params => {
  2751. :issue => {
  2752. :project_id => 1,
  2753. :fixed_version_id => ''
  2754. },
  2755. :form_update_triggered_by => 'issue_project_id'
  2756. }
  2757. assert_response :success
  2758. assert_select 'select[name=?]', 'issue[project_id]' do
  2759. assert_select 'option[value=?][selected=selected]', '1'
  2760. end
  2761. assert_select 'select[name=?]', 'issue[fixed_version_id]' do
  2762. assert_select 'option[value=?][selected=selected]', version.id.to_s
  2763. end
  2764. end
  2765. def test_post_create
  2766. @request.session[:user_id] = 2
  2767. assert_difference 'Issue.count' do
  2768. assert_no_difference 'Journal.count' do
  2769. post :create, :params => {
  2770. :project_id => 1,
  2771. :issue => {
  2772. :tracker_id => 3,
  2773. :status_id => 2,
  2774. :subject => 'This is the test_new issue',
  2775. :description => 'This is the description',
  2776. :priority_id => 5,
  2777. :start_date => '2010-11-07',
  2778. :estimated_hours => '',
  2779. :custom_field_values => {
  2780. '2' => 'Value for field 2'}
  2781. }
  2782. }
  2783. end
  2784. end
  2785. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  2786. issue = Issue.find_by_subject('This is the test_new issue')
  2787. assert_not_nil issue
  2788. assert_equal 2, issue.author_id
  2789. assert_equal 3, issue.tracker_id
  2790. assert_equal 2, issue.status_id
  2791. assert_equal Date.parse('2010-11-07'), issue.start_date
  2792. assert_nil issue.estimated_hours
  2793. v = issue.custom_values.where(:custom_field_id => 2).first
  2794. assert_not_nil v
  2795. assert_equal 'Value for field 2', v.value
  2796. end
  2797. def test_post_new_with_group_assignment
  2798. group = Group.find(11)
  2799. project = Project.find(1)
  2800. project.members << Member.new(:principal => group, :roles => [Role.givable.first])
  2801. with_settings :issue_group_assignment => '1' do
  2802. @request.session[:user_id] = 2
  2803. assert_difference 'Issue.count' do
  2804. post :create, :params => {
  2805. :project_id => project.id,
  2806. :issue => {
  2807. :tracker_id => 3,
  2808. :status_id => 1,
  2809. :subject => 'This is the test_new_with_group_assignment issue',
  2810. :assigned_to_id => group.id
  2811. }
  2812. }
  2813. end
  2814. end
  2815. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  2816. issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
  2817. assert_not_nil issue
  2818. assert_equal group, issue.assigned_to
  2819. end
  2820. def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
  2821. with_settings :default_issue_start_date_to_creation_date => 0 do
  2822. @request.session[:user_id] = 2
  2823. assert_difference 'Issue.count' do
  2824. post :create, :params => {
  2825. :project_id => 1,
  2826. :issue => {
  2827. :tracker_id => 3,
  2828. :status_id => 2,
  2829. :subject => 'This is the test_new issue',
  2830. :description => 'This is the description',
  2831. :priority_id => 5,
  2832. :estimated_hours => '',
  2833. :custom_field_values => {
  2834. '2' => 'Value for field 2'}
  2835. }
  2836. }
  2837. end
  2838. assert_redirected_to :controller => 'issues', :action => 'show',
  2839. :id => Issue.last.id
  2840. issue = Issue.find_by_subject('This is the test_new issue')
  2841. assert_not_nil issue
  2842. assert_nil issue.start_date
  2843. end
  2844. end
  2845. def test_post_create_without_start_date_and_default_start_date_is_creation_date
  2846. with_settings :default_issue_start_date_to_creation_date => 1 do
  2847. @request.session[:user_id] = 2
  2848. assert_difference 'Issue.count' do
  2849. post :create, :params => {
  2850. :project_id => 1,
  2851. :issue => {
  2852. :tracker_id => 3,
  2853. :status_id => 2,
  2854. :subject => 'This is the test_new issue',
  2855. :description => 'This is the description',
  2856. :priority_id => 5,
  2857. :estimated_hours => '',
  2858. :custom_field_values => {
  2859. '2' => 'Value for field 2'}
  2860. }
  2861. }
  2862. end
  2863. assert_redirected_to :controller => 'issues', :action => 'show',
  2864. :id => Issue.last.id
  2865. issue = Issue.find_by_subject('This is the test_new issue')
  2866. assert_not_nil issue
  2867. assert_equal Date.today, issue.start_date
  2868. end
  2869. end
  2870. def test_post_create_and_continue
  2871. @request.session[:user_id] = 2
  2872. assert_difference 'Issue.count' do
  2873. post :create, :params => {
  2874. :project_id => 1,
  2875. :issue => {
  2876. :tracker_id => 3,
  2877. :subject => 'This is first issue',
  2878. :priority_id => 5
  2879. },
  2880. :continue => ''
  2881. }
  2882. end
  2883. issue = Issue.order('id DESC').first
  2884. assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
  2885. assert_not_nil flash[:notice], "flash was not set"
  2886. assert_select_in flash[:notice],
  2887. 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
  2888. end
  2889. def test_post_create_without_custom_fields_param
  2890. @request.session[:user_id] = 2
  2891. assert_difference 'Issue.count' do
  2892. post :create, :params => {
  2893. :project_id => 1,
  2894. :issue => {
  2895. :tracker_id => 1,
  2896. :subject => 'This is the test_new issue',
  2897. :description => 'This is the description',
  2898. :priority_id => 5
  2899. }
  2900. }
  2901. end
  2902. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  2903. end
  2904. def test_post_create_with_multi_custom_field
  2905. field = IssueCustomField.find_by_name('Database')
  2906. field.update_attribute(:multiple, true)
  2907. @request.session[:user_id] = 2
  2908. assert_difference 'Issue.count' do
  2909. post :create, :params => {
  2910. :project_id => 1,
  2911. :issue => {
  2912. :tracker_id => 1,
  2913. :subject => 'This is the test_new issue',
  2914. :description => 'This is the description',
  2915. :priority_id => 5,
  2916. :custom_field_values => {
  2917. '1' => ['', 'MySQL', 'Oracle']}
  2918. }
  2919. }
  2920. end
  2921. assert_response 302
  2922. issue = Issue.order('id DESC').first
  2923. assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
  2924. end
  2925. def test_post_create_with_empty_multi_custom_field
  2926. field = IssueCustomField.find_by_name('Database')
  2927. field.update_attribute(:multiple, true)
  2928. @request.session[:user_id] = 2
  2929. assert_difference 'Issue.count' do
  2930. post :create, :params => {
  2931. :project_id => 1,
  2932. :issue => {
  2933. :tracker_id => 1,
  2934. :subject => 'This is the test_new issue',
  2935. :description => 'This is the description',
  2936. :priority_id => 5,
  2937. :custom_field_values => {
  2938. '1' => ['']}
  2939. }
  2940. }
  2941. end
  2942. assert_response 302
  2943. issue = Issue.order('id DESC').first
  2944. assert_equal [''], issue.custom_field_value(1).sort
  2945. end
  2946. def test_post_create_with_multi_user_custom_field
  2947. field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
  2948. :tracker_ids => [1], :is_for_all => true)
  2949. @request.session[:user_id] = 2
  2950. assert_difference 'Issue.count' do
  2951. post :create, :params => {
  2952. :project_id => 1,
  2953. :issue => {
  2954. :tracker_id => 1,
  2955. :subject => 'This is the test_new issue',
  2956. :description => 'This is the description',
  2957. :priority_id => 5,
  2958. :custom_field_values => {
  2959. field.id.to_s => ['', '2', '3']}
  2960. }
  2961. }
  2962. end
  2963. assert_response 302
  2964. issue = Issue.order('id DESC').first
  2965. assert_equal ['2', '3'], issue.custom_field_value(field).sort
  2966. end
  2967. def test_post_create_with_required_custom_field_and_without_custom_fields_param
  2968. field = IssueCustomField.find_by_name('Database')
  2969. field.update_attribute(:is_required, true)
  2970. @request.session[:user_id] = 2
  2971. assert_no_difference 'Issue.count' do
  2972. post :create, :params => {
  2973. :project_id => 1,
  2974. :issue => {
  2975. :tracker_id => 1,
  2976. :subject => 'This is the test_new issue',
  2977. :description => 'This is the description',
  2978. :priority_id => 5
  2979. }
  2980. }
  2981. end
  2982. assert_response :success
  2983. assert_select_error /Database cannot be blank/
  2984. end
  2985. def test_create_should_validate_required_fields
  2986. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2987. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  2988. WorkflowPermission.delete_all
  2989. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
  2990. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  2991. @request.session[:user_id] = 2
  2992. assert_no_difference 'Issue.count' do
  2993. post :create, :params => {
  2994. :project_id => 1,
  2995. :issue => {
  2996. :tracker_id => 2,
  2997. :status_id => 1,
  2998. :subject => 'Test',
  2999. :start_date => '',
  3000. :due_date => '',
  3001. :custom_field_values => {
  3002. cf1.id.to_s => '', cf2.id.to_s => ''
  3003. }
  3004. }
  3005. }
  3006. assert_response :success
  3007. end
  3008. assert_select_error /Due date cannot be blank/i
  3009. assert_select_error /Bar cannot be blank/i
  3010. end
  3011. def test_create_should_validate_required_list_fields
  3012. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
  3013. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
  3014. WorkflowPermission.delete_all
  3015. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
  3016. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
  3017. @request.session[:user_id] = 2
  3018. assert_no_difference 'Issue.count' do
  3019. post :create, :params => {
  3020. :project_id => 1,
  3021. :issue => {
  3022. :tracker_id => 2,
  3023. :status_id => 1,
  3024. :subject => 'Test',
  3025. :start_date => '',
  3026. :due_date => '',
  3027. :custom_field_values => {
  3028. cf1.id.to_s => '', cf2.id.to_s => ['']
  3029. }
  3030. }
  3031. }
  3032. assert_response :success
  3033. end
  3034. assert_select_error /Foo cannot be blank/i
  3035. assert_select_error /Bar cannot be blank/i
  3036. end
  3037. def test_create_should_ignore_readonly_fields
  3038. cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  3039. cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
  3040. WorkflowPermission.delete_all
  3041. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
  3042. WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
  3043. @request.session[:user_id] = 2
  3044. assert_difference 'Issue.count' do
  3045. post :create, :params => {
  3046. :project_id => 1,
  3047. :issue => {
  3048. :tracker_id => 2,
  3049. :status_id => 1,
  3050. :subject => 'Test',
  3051. :start_date => '2012-07-14',
  3052. :due_date => '2012-07-16',
  3053. :custom_field_values => {
  3054. cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'
  3055. }
  3056. }
  3057. }
  3058. assert_response 302
  3059. end
  3060. issue = Issue.order('id DESC').first
  3061. assert_equal Date.parse('2012-07-14'), issue.start_date
  3062. assert_nil issue.due_date
  3063. assert_equal 'value1', issue.custom_field_value(cf1)
  3064. assert_nil issue.custom_field_value(cf2)
  3065. end
  3066. def test_create_should_ignore_unallowed_trackers
  3067. role = Role.find(1)
  3068. role.set_permission_trackers :add_issues, [3]
  3069. role.save!
  3070. @request.session[:user_id] = 2
  3071. issue = new_record(Issue) do
  3072. post :create, :params => {
  3073. :project_id => 1,
  3074. :issue => {
  3075. :tracker_id => 1,
  3076. :status_id => 1,
  3077. :subject => 'Test'
  3078. }
  3079. }
  3080. assert_response 302
  3081. end
  3082. assert_equal 3, issue.tracker_id
  3083. end
  3084. def test_post_create_with_watchers
  3085. @request.session[:user_id] = 2
  3086. ActionMailer::Base.deliveries.clear
  3087. with_settings :notified_events => %w(issue_added) do
  3088. assert_difference 'Watcher.count', 2 do
  3089. post :create, :params => {
  3090. :project_id => 1,
  3091. :issue => {
  3092. :tracker_id => 1,
  3093. :subject => 'This is a new issue with watchers',
  3094. :description => 'This is the description',
  3095. :priority_id => 5,
  3096. :watcher_user_ids => ['2', '3']
  3097. }
  3098. }
  3099. end
  3100. end
  3101. issue = Issue.find_by_subject('This is a new issue with watchers')
  3102. assert_not_nil issue
  3103. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
  3104. # Watchers added
  3105. assert_equal [2, 3], issue.watcher_user_ids.sort
  3106. assert issue.watched_by?(User.find(3))
  3107. # Watchers notified
  3108. mail = ActionMailer::Base.deliveries.last
  3109. assert_not_nil mail
  3110. assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
  3111. end
  3112. def test_post_create_subissue
  3113. @request.session[:user_id] = 2
  3114. assert_difference 'Issue.count' do
  3115. post :create, :params => {
  3116. :project_id => 1,
  3117. :issue => {
  3118. :tracker_id => 1,
  3119. :subject => 'This is a child issue',
  3120. :parent_issue_id => '2'
  3121. }
  3122. }
  3123. assert_response 302
  3124. end
  3125. issue = Issue.order('id DESC').first
  3126. assert_equal Issue.find(2), issue.parent
  3127. end
  3128. def test_post_create_subissue_with_sharp_parent_id
  3129. @request.session[:user_id] = 2
  3130. assert_difference 'Issue.count' do
  3131. post :create, :params => {
  3132. :project_id => 1,
  3133. :issue => {
  3134. :tracker_id => 1,
  3135. :subject => 'This is a child issue',
  3136. :parent_issue_id => '#2'
  3137. }
  3138. }
  3139. assert_response 302
  3140. end
  3141. issue = Issue.order('id DESC').first
  3142. assert_equal Issue.find(2), issue.parent
  3143. end
  3144. def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
  3145. @request.session[:user_id] = 2
  3146. assert_no_difference 'Issue.count' do
  3147. post :create, :params => {
  3148. :project_id => 1,
  3149. :issue => {
  3150. :tracker_id => 1,
  3151. :subject => 'This is a child issue',
  3152. :parent_issue_id => '4'
  3153. }
  3154. }
  3155. assert_response :success
  3156. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
  3157. assert_select_error /Parent task is invalid/i
  3158. end
  3159. end
  3160. def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
  3161. @request.session[:user_id] = 2
  3162. assert_no_difference 'Issue.count' do
  3163. post :create, :params => {
  3164. :project_id => 1,
  3165. :issue => {
  3166. :tracker_id => 1,
  3167. :subject => 'This is a child issue',
  3168. :parent_issue_id => '01ABC'
  3169. }
  3170. }
  3171. assert_response :success
  3172. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
  3173. assert_select_error /Parent task is invalid/i
  3174. end
  3175. end
  3176. def test_post_create_private
  3177. @request.session[:user_id] = 2
  3178. assert_difference 'Issue.count' do
  3179. post :create, :params => {
  3180. :project_id => 1,
  3181. :issue => {
  3182. :tracker_id => 1,
  3183. :subject => 'This is a private issue',
  3184. :is_private => '1'
  3185. }
  3186. }
  3187. end
  3188. issue = Issue.order('id DESC').first
  3189. assert issue.is_private?
  3190. end
  3191. def test_post_create_private_with_set_own_issues_private_permission
  3192. role = Role.find(1)
  3193. role.remove_permission! :set_issues_private
  3194. role.add_permission! :set_own_issues_private
  3195. @request.session[:user_id] = 2
  3196. assert_difference 'Issue.count' do
  3197. post :create, :params => {
  3198. :project_id => 1,
  3199. :issue => {
  3200. :tracker_id => 1,
  3201. :subject => 'This is a private issue',
  3202. :is_private => '1'
  3203. }
  3204. }
  3205. end
  3206. issue = Issue.order('id DESC').first
  3207. assert issue.is_private?
  3208. end
  3209. def test_create_without_project_id
  3210. @request.session[:user_id] = 2
  3211. assert_difference 'Issue.count' do
  3212. post :create, :params => {
  3213. :issue => {
  3214. :project_id => 3,
  3215. :tracker_id => 2,
  3216. :subject => 'Foo'
  3217. }
  3218. }
  3219. assert_response 302
  3220. end
  3221. issue = Issue.order('id DESC').first
  3222. assert_equal 3, issue.project_id
  3223. assert_equal 2, issue.tracker_id
  3224. end
  3225. def test_create_without_project_id_and_continue_should_redirect_without_project_id
  3226. @request.session[:user_id] = 2
  3227. assert_difference 'Issue.count' do
  3228. post :create, :params => {
  3229. :issue => {
  3230. :project_id => 3,
  3231. :tracker_id => 2,
  3232. :subject => 'Foo'
  3233. },
  3234. :continue => '1'
  3235. }
  3236. assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
  3237. end
  3238. end
  3239. def test_create_without_project_id_should_be_denied_without_permission
  3240. Role.non_member.remove_permission! :add_issues
  3241. Role.anonymous.remove_permission! :add_issues
  3242. @request.session[:user_id] = 2
  3243. assert_no_difference 'Issue.count' do
  3244. post :create, :params => {
  3245. :issue => {
  3246. :project_id => 3,
  3247. :tracker_id => 2,
  3248. :subject => 'Foo'
  3249. }
  3250. }
  3251. assert_response 422
  3252. end
  3253. end
  3254. def test_create_without_project_id_with_failure_should_not_set_project
  3255. @request.session[:user_id] = 2
  3256. post :create, :params => {
  3257. :issue => {
  3258. :project_id => 3,
  3259. :tracker_id => 2,
  3260. :subject => ''
  3261. }
  3262. }
  3263. assert_response :success
  3264. # no project menu
  3265. assert_select '#main-menu a.overview', 0
  3266. end
  3267. def test_post_create_should_send_a_notification
  3268. ActionMailer::Base.deliveries.clear
  3269. @request.session[:user_id] = 2
  3270. with_settings :notified_events => %w(issue_added) do
  3271. assert_difference 'Issue.count' do
  3272. post :create, :params => {
  3273. :project_id => 1,
  3274. :issue => {
  3275. :tracker_id => 3,
  3276. :subject => 'This is the test_new issue',
  3277. :description => 'This is the description',
  3278. :priority_id => 5,
  3279. :estimated_hours => '',
  3280. :custom_field_values => {
  3281. '2' => 'Value for field 2'}
  3282. }
  3283. }
  3284. end
  3285. assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
  3286. assert_equal 2, ActionMailer::Base.deliveries.size
  3287. end
  3288. end
  3289. def test_post_create_should_preserve_fields_values_on_validation_failure
  3290. @request.session[:user_id] = 2
  3291. post :create, :params => {
  3292. :project_id => 1,
  3293. :issue => {
  3294. :tracker_id => 1,
  3295. :subject => '', # empty subject
  3296. :description => 'This is a description',
  3297. :priority_id => 6,
  3298. :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}
  3299. }
  3300. }
  3301. assert_response :success
  3302. assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
  3303. assert_select 'select[name=?]', 'issue[priority_id]' do
  3304. assert_select 'option[value="6"][selected=selected]', :text => 'High'
  3305. end
  3306. # Custom fields
  3307. assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
  3308. assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
  3309. end
  3310. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
  3311. end
  3312. def test_post_create_with_failure_should_preserve_watchers
  3313. assert !User.find(8).member_of?(Project.find(1))
  3314. @request.session[:user_id] = 2
  3315. post :create, :params => {
  3316. :project_id => 1,
  3317. :issue => {
  3318. :tracker_id => 1,
  3319. :watcher_user_ids => ['3', '8']
  3320. }
  3321. }
  3322. assert_response :success
  3323. assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
  3324. assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
  3325. assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
  3326. end
  3327. def test_post_create_should_ignore_non_safe_attributes
  3328. @request.session[:user_id] = 2
  3329. assert_nothing_raised do
  3330. post :create, :params => {
  3331. :project_id => 1,
  3332. :issue => {
  3333. :tracker => "A param can not be a Tracker"
  3334. }
  3335. }
  3336. end
  3337. end
  3338. def test_post_create_with_attachment
  3339. set_tmp_attachments_directory
  3340. @request.session[:user_id] = 2
  3341. assert_difference 'Issue.count' do
  3342. assert_difference 'Attachment.count' do
  3343. assert_no_difference 'Journal.count' do
  3344. post :create, :params => {
  3345. :project_id => 1,
  3346. :issue => {
  3347. :tracker_id => '1',
  3348. :subject => 'With attachment'
  3349. },
  3350. :attachments => {
  3351. '1' => {
  3352. 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
  3353. }
  3354. }
  3355. end
  3356. end
  3357. end
  3358. issue = Issue.order('id DESC').first
  3359. attachment = Attachment.order('id DESC').first
  3360. assert_equal issue, attachment.container
  3361. assert_equal 2, attachment.author_id
  3362. assert_equal 'testfile.txt', attachment.filename
  3363. assert_equal 'text/plain', attachment.content_type
  3364. assert_equal 'test file', attachment.description
  3365. assert_equal 59, attachment.filesize
  3366. assert File.exists?(attachment.diskfile)
  3367. assert_equal 59, File.size(attachment.diskfile)
  3368. end
  3369. def test_post_create_with_attachment_should_notify_with_attachments
  3370. ActionMailer::Base.deliveries.clear
  3371. set_tmp_attachments_directory
  3372. @request.session[:user_id] = 2
  3373. with_settings :notified_events => %w(issue_added) do
  3374. assert_difference 'Issue.count' do
  3375. post :create, :params => {
  3376. :project_id => 1,
  3377. :issue => {
  3378. :tracker_id => '1',
  3379. :subject => 'With attachment'
  3380. },
  3381. :attachments => {
  3382. '1' => {
  3383. 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
  3384. }
  3385. }
  3386. end
  3387. end
  3388. assert_not_nil ActionMailer::Base.deliveries.last
  3389. assert_select_email do
  3390. assert_select 'a[href^=?]', 'http://localhost:3000/attachments/download', 'testfile.txt'
  3391. end
  3392. end
  3393. def test_post_create_with_failure_should_save_attachments
  3394. set_tmp_attachments_directory
  3395. @request.session[:user_id] = 2
  3396. assert_no_difference 'Issue.count' do
  3397. assert_difference 'Attachment.count' do
  3398. post :create, :params => {
  3399. :project_id => 1,
  3400. :issue => {
  3401. :tracker_id => '1',
  3402. :subject => ''
  3403. },
  3404. :attachments => {
  3405. '1' => {
  3406. 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
  3407. }
  3408. }
  3409. assert_response :success
  3410. end
  3411. end
  3412. attachment = Attachment.order('id DESC').first
  3413. assert_equal 'testfile.txt', attachment.filename
  3414. assert File.exists?(attachment.diskfile)
  3415. assert_nil attachment.container
  3416. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  3417. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  3418. end
  3419. def test_post_create_with_failure_should_keep_saved_attachments
  3420. set_tmp_attachments_directory
  3421. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  3422. @request.session[:user_id] = 2
  3423. assert_no_difference 'Issue.count' do
  3424. assert_no_difference 'Attachment.count' do
  3425. post :create, :params => {
  3426. :project_id => 1,
  3427. :issue => {
  3428. :tracker_id => '1',
  3429. :subject => ''
  3430. },
  3431. :attachments => {
  3432. 'p0' => {
  3433. 'token' => attachment.token}
  3434. }
  3435. }
  3436. assert_response :success
  3437. end
  3438. end
  3439. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  3440. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  3441. end
  3442. def test_post_create_should_attach_saved_attachments
  3443. set_tmp_attachments_directory
  3444. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  3445. @request.session[:user_id] = 2
  3446. assert_difference 'Issue.count' do
  3447. assert_no_difference 'Attachment.count' do
  3448. post :create, :params => {
  3449. :project_id => 1,
  3450. :issue => {
  3451. :tracker_id => '1',
  3452. :subject => 'Saved attachments'
  3453. },
  3454. :attachments => {
  3455. 'p0' => {
  3456. 'token' => attachment.token}
  3457. }
  3458. }
  3459. assert_response 302
  3460. end
  3461. end
  3462. issue = Issue.order('id DESC').first
  3463. assert_equal 1, issue.attachments.count
  3464. attachment.reload
  3465. assert_equal issue, attachment.container
  3466. end
  3467. def setup_without_workflow_privilege
  3468. WorkflowTransition.where(["role_id = ?", Role.anonymous.id]).delete_all
  3469. Role.anonymous.add_permission! :add_issues, :add_issue_notes
  3470. end
  3471. private :setup_without_workflow_privilege
  3472. test "without workflow privilege #new should propose default status only" do
  3473. setup_without_workflow_privilege
  3474. get :new, :params => {
  3475. :project_id => 1
  3476. }
  3477. assert_response :success
  3478. assert_select 'select[name=?]', 'issue[status_id]' do
  3479. assert_select 'option', 1
  3480. assert_select 'option[value=?][selected=selected]', '1'
  3481. end
  3482. end
  3483. test "without workflow privilege #create should accept default status" do
  3484. setup_without_workflow_privilege
  3485. assert_difference 'Issue.count' do
  3486. post :create, :params => {
  3487. :project_id => 1,
  3488. :issue => {
  3489. :tracker_id => 1,
  3490. :subject => 'This is an issue',
  3491. :status_id => 1
  3492. }
  3493. }
  3494. end
  3495. issue = Issue.order('id').last
  3496. assert_not_nil issue.default_status
  3497. assert_equal issue.default_status, issue.status
  3498. end
  3499. test "without workflow privilege #create should ignore unauthorized status" do
  3500. setup_without_workflow_privilege
  3501. assert_difference 'Issue.count' do
  3502. post :create, :params => {
  3503. :project_id => 1,
  3504. :issue => {
  3505. :tracker_id => 1,
  3506. :subject => 'This is an issue',
  3507. :status_id => 3
  3508. }
  3509. }
  3510. end
  3511. issue = Issue.order('id').last
  3512. assert_not_nil issue.default_status
  3513. assert_equal issue.default_status, issue.status
  3514. end
  3515. test "without workflow privilege #update should ignore status change" do
  3516. setup_without_workflow_privilege
  3517. assert_difference 'Journal.count' do
  3518. put :update, :params => {
  3519. :id => 1,
  3520. :issue => {
  3521. :status_id => 3,
  3522. :notes => 'just trying'
  3523. }
  3524. }
  3525. end
  3526. assert_equal 1, Issue.find(1).status_id
  3527. end
  3528. test "without workflow privilege #update ignore attributes changes" do
  3529. setup_without_workflow_privilege
  3530. assert_difference 'Journal.count' do
  3531. put :update, :params => {
  3532. :id => 1,
  3533. :issue => {
  3534. :subject => 'changed',
  3535. :assigned_to_id => 2,
  3536. :notes => 'just trying'
  3537. }
  3538. }
  3539. end
  3540. issue = Issue.find(1)
  3541. assert_equal "Cannot print recipes", issue.subject
  3542. assert_nil issue.assigned_to
  3543. end
  3544. def setup_with_workflow_privilege
  3545. WorkflowTransition.where(["role_id = ?", Role.anonymous.id]).delete_all
  3546. WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
  3547. :old_status_id => 1, :new_status_id => 3)
  3548. WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
  3549. :old_status_id => 1, :new_status_id => 4)
  3550. Role.anonymous.add_permission! :add_issues, :add_issue_notes
  3551. end
  3552. private :setup_with_workflow_privilege
  3553. def setup_with_workflow_privilege_and_edit_issues_permission
  3554. setup_with_workflow_privilege
  3555. Role.anonymous.add_permission! :add_issues, :edit_issues
  3556. end
  3557. private :setup_with_workflow_privilege_and_edit_issues_permission
  3558. test "with workflow privilege and :edit_issues permission should accept authorized status" do
  3559. setup_with_workflow_privilege_and_edit_issues_permission
  3560. assert_difference 'Journal.count' do
  3561. put :update, :params => {
  3562. :id => 1,
  3563. :issue => {
  3564. :status_id => 3,
  3565. :notes => 'just trying'
  3566. }
  3567. }
  3568. end
  3569. assert_equal 3, Issue.find(1).status_id
  3570. end
  3571. test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
  3572. setup_with_workflow_privilege_and_edit_issues_permission
  3573. assert_difference 'Journal.count' do
  3574. put :update, :params => {
  3575. :id => 1,
  3576. :issue => {
  3577. :status_id => 2,
  3578. :notes => 'just trying'
  3579. }
  3580. }
  3581. end
  3582. assert_equal 1, Issue.find(1).status_id
  3583. end
  3584. test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
  3585. setup_with_workflow_privilege_and_edit_issues_permission
  3586. assert_difference 'Journal.count' do
  3587. put :update, :params => {
  3588. :id => 1,
  3589. :issue => {
  3590. :subject => 'changed',
  3591. :assigned_to_id => 2,
  3592. :notes => 'just trying'
  3593. }
  3594. }
  3595. end
  3596. issue = Issue.find(1)
  3597. assert_equal "changed", issue.subject
  3598. assert_equal 2, issue.assigned_to_id
  3599. end
  3600. def test_new_as_copy
  3601. orig = Issue.find(1)
  3602. @request.session[:user_id] = 2
  3603. get :new, :params => {
  3604. :project_id => 1,
  3605. :copy_from => orig.id
  3606. }
  3607. assert_response :success
  3608. assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
  3609. assert_select 'select[name=?]', 'issue[project_id]' do
  3610. assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
  3611. assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
  3612. end
  3613. assert_select 'input[name=?][value=?]', 'issue[subject]', orig.subject
  3614. assert_select 'input[name=copy_from][value="1"]'
  3615. end
  3616. end
  3617. def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
  3618. user = setup_user_with_copy_but_not_add_permission
  3619. @request.session[:user_id] = user.id
  3620. get :new, :params => {
  3621. :project_id => 1,
  3622. :copy_from => 1
  3623. }
  3624. assert_response :success
  3625. assert_select 'select[name=?]', 'issue[project_id]' do
  3626. assert_select 'option[value="1"]', 0
  3627. assert_select 'option[value="2"]', :text => 'OnlineStore'
  3628. end
  3629. end
  3630. def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
  3631. @request.session[:user_id] = 2
  3632. issue = Issue.find(3)
  3633. assert issue.attachments.count > 0
  3634. get :new, :params => {
  3635. :project_id => 1,
  3636. :copy_from => 3
  3637. }
  3638. assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
  3639. end
  3640. def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
  3641. @request.session[:user_id] = 2
  3642. issue = Issue.find(3)
  3643. issue.attachments.delete_all
  3644. get :new, :params => {
  3645. :project_id => 1,
  3646. :copy_from => 3
  3647. }
  3648. assert_select 'input[name=copy_attachments]', 0
  3649. end
  3650. def test_new_as_copy_should_preserve_parent_id
  3651. @request.session[:user_id] = 2
  3652. issue = Issue.generate!(:parent_issue_id => 2)
  3653. get :new, :params => {
  3654. :project_id => 1,
  3655. :copy_from => issue.id
  3656. }
  3657. assert_select 'input[name=?][value="2"]', 'issue[parent_issue_id]'
  3658. end
  3659. def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
  3660. @request.session[:user_id] = 2
  3661. issue = Issue.generate_with_descendants!
  3662. get :new, :params => {
  3663. :project_id => 1,
  3664. :copy_from => issue.id
  3665. }
  3666. assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
  3667. end
  3668. def test_new_as_copy_should_preserve_watchers
  3669. @request.session[:user_id] = 2
  3670. user = User.generate!
  3671. Watcher.create!(:watchable => Issue.find(1), :user => user)
  3672. get :new, :params => {
  3673. :project_id => 1,
  3674. :copy_from => 1
  3675. }
  3676. assert_select 'input[type=checkbox][name=?][checked=checked]', 'issue[watcher_user_ids][]', 1
  3677. assert_select 'input[type=checkbox][name=?][checked=checked][value=?]', 'issue[watcher_user_ids][]', user.id.to_s
  3678. assert_select 'input[type=hidden][name=?][value=?]', 'issue[watcher_user_ids][]', '', 1
  3679. end
  3680. def test_new_as_copy_should_not_propose_locked_watchers
  3681. @request.session[:user_id] = 2
  3682. issue = Issue.find(1)
  3683. user = User.generate!
  3684. user2 = User.generate!
  3685. Watcher.create!(:watchable => issue, :user => user)
  3686. Watcher.create!(:watchable => issue, :user => user2)
  3687. user2.status = User::STATUS_LOCKED
  3688. user2.save!
  3689. get :new, :params => {
  3690. :project_id => 1,
  3691. :copy_from => 1
  3692. }
  3693. assert_select 'input[type=checkbox][name=?][checked=checked]', 'issue[watcher_user_ids][]', 1
  3694. assert_select 'input[type=checkbox][name=?][checked=checked][value=?]', 'issue[watcher_user_ids][]', user.id.to_s
  3695. assert_select 'input[type=checkbox][name=?][checked=checked][value=?]', 'issue[watcher_user_ids][]', user2.id.to_s, 0
  3696. assert_select 'input[type=hidden][name=?][value=?]', 'issue[watcher_user_ids][]', '', 1
  3697. end
  3698. def test_new_as_copy_with_invalid_issue_should_respond_with_404
  3699. @request.session[:user_id] = 2
  3700. get :new, :params => {
  3701. :project_id => 1,
  3702. :copy_from => 99999
  3703. }
  3704. assert_response 404
  3705. end
  3706. def test_create_as_copy_on_different_project
  3707. @request.session[:user_id] = 2
  3708. assert_difference 'Issue.count' do
  3709. post :create, :params => {
  3710. :project_id => 1,
  3711. :copy_from => 1,
  3712. :issue => {
  3713. :project_id => '2',
  3714. :tracker_id => '3',
  3715. :status_id => '1',
  3716. :subject => 'Copy'
  3717. }
  3718. }
  3719. end
  3720. issue = Issue.order('id DESC').first
  3721. assert_redirected_to "/issues/#{issue.id}"
  3722. assert_equal 2, issue.project_id
  3723. assert_equal 3, issue.tracker_id
  3724. assert_equal 'Copy', issue.subject
  3725. end
  3726. def test_create_as_copy_should_allow_status_to_be_set_to_default
  3727. copied = Issue.generate! :status_id => 2
  3728. assert_equal 2, copied.reload.status_id
  3729. @request.session[:user_id] = 2
  3730. assert_difference 'Issue.count' do
  3731. post :create, :params => {
  3732. :project_id => 1,
  3733. :copy_from => copied.id,
  3734. :issue => {
  3735. :project_id => '1',
  3736. :tracker_id => '1',
  3737. :status_id => '1'
  3738. },
  3739. :was_default_status => '1'
  3740. }
  3741. end
  3742. issue = Issue.order('id DESC').first
  3743. assert_equal 1, issue.status_id
  3744. end
  3745. def test_create_as_copy_should_fail_without_add_issue_permission_on_original_tracker
  3746. role = Role.find(2)
  3747. role.set_permission_trackers :add_issues, [1, 3]
  3748. role.save!
  3749. Role.non_member.remove_permission! :add_issues
  3750. issue = Issue.generate!(:project_id => 1, :tracker_id => 2)
  3751. @request.session[:user_id] = 3
  3752. assert_no_difference 'Issue.count' do
  3753. post :create, :params => {
  3754. :project_id => 1,
  3755. :copy_from => issue.id,
  3756. :issue => {
  3757. :project_id => '1'
  3758. }
  3759. }
  3760. end
  3761. assert_select_error 'Tracker is invalid'
  3762. end
  3763. def test_create_as_copy_should_copy_attachments
  3764. @request.session[:user_id] = 2
  3765. issue = Issue.find(3)
  3766. count = issue.attachments.count
  3767. assert count > 0
  3768. assert_difference 'Issue.count' do
  3769. assert_difference 'Attachment.count', count do
  3770. post :create, :params => {
  3771. :project_id => 1,
  3772. :copy_from => 3,
  3773. :issue => {
  3774. :project_id => '1',
  3775. :tracker_id => '3',
  3776. :status_id => '1',
  3777. :subject => 'Copy with attachments'
  3778. },
  3779. :copy_attachments => '1'
  3780. }
  3781. end
  3782. end
  3783. copy = Issue.order('id DESC').first
  3784. assert_equal count, copy.attachments.count
  3785. assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
  3786. end
  3787. def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
  3788. @request.session[:user_id] = 2
  3789. issue = Issue.find(3)
  3790. count = issue.attachments.count
  3791. assert count > 0
  3792. assert_difference 'Issue.count' do
  3793. assert_no_difference 'Attachment.count' do
  3794. post :create, :params => {
  3795. :project_id => 1,
  3796. :copy_from => 3,
  3797. :issue => {
  3798. :project_id => '1',
  3799. :tracker_id => '3',
  3800. :status_id => '1',
  3801. :subject => 'Copy with attachments'
  3802. }
  3803. }
  3804. end
  3805. end
  3806. copy = Issue.order('id DESC').first
  3807. assert_equal 0, copy.attachments.count
  3808. end
  3809. def test_create_as_copy_with_attachments_should_also_add_new_files
  3810. @request.session[:user_id] = 2
  3811. issue = Issue.find(3)
  3812. count = issue.attachments.count
  3813. assert count > 0
  3814. assert_difference 'Issue.count' do
  3815. assert_difference 'Attachment.count', count + 1 do
  3816. post :create, :params => {
  3817. :project_id => 1,
  3818. :copy_from => 3,
  3819. :issue => {
  3820. :project_id => '1',
  3821. :tracker_id => '3',
  3822. :status_id => '1',
  3823. :subject => 'Copy with attachments'
  3824. },
  3825. :copy_attachments => '1',
  3826. :attachments => {
  3827. '1' => {
  3828. 'file' => uploaded_test_file('testfile.txt', 'text/plain'),
  3829. 'description' => 'test file'
  3830. }
  3831. }
  3832. }
  3833. end
  3834. end
  3835. copy = Issue.order('id DESC').first
  3836. assert_equal count + 1, copy.attachments.count
  3837. end
  3838. def test_create_as_copy_should_add_relation_with_copied_issue
  3839. @request.session[:user_id] = 2
  3840. assert_difference 'Issue.count' do
  3841. assert_difference 'IssueRelation.count' do
  3842. post :create, :params => {
  3843. :project_id => 1,
  3844. :copy_from => 1,
  3845. :link_copy => '1',
  3846. :issue => {
  3847. :project_id => '1',
  3848. :tracker_id => '3',
  3849. :status_id => '1',
  3850. :subject => 'Copy'
  3851. }
  3852. }
  3853. end
  3854. end
  3855. copy = Issue.order('id DESC').first
  3856. assert_equal 1, copy.relations.size
  3857. end
  3858. def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
  3859. @request.session[:user_id] = 2
  3860. assert_difference 'Issue.count' do
  3861. assert_no_difference 'IssueRelation.count' do
  3862. post :create, :params => {
  3863. :project_id => 1,
  3864. :copy_from => 1,
  3865. :issue => {
  3866. :subject => 'Copy'
  3867. }
  3868. }
  3869. end
  3870. end
  3871. end
  3872. def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
  3873. with_settings :link_copied_issue => 'yes' do
  3874. @request.session[:user_id] = 2
  3875. assert_difference 'Issue.count' do
  3876. assert_difference 'IssueRelation.count' do
  3877. post :create, :params => {
  3878. :project_id => 1,
  3879. :copy_from => 1,
  3880. :issue => {
  3881. :subject => 'Copy'
  3882. }
  3883. }
  3884. end
  3885. end
  3886. end
  3887. end
  3888. def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
  3889. with_settings :link_copied_issue => 'no' do
  3890. @request.session[:user_id] = 2
  3891. assert_difference 'Issue.count' do
  3892. assert_no_difference 'IssueRelation.count' do
  3893. post :create, :params => {
  3894. :project_id => 1,
  3895. :copy_from => 1,
  3896. :link_copy => '1',
  3897. :issue => {
  3898. :subject => 'Copy'
  3899. }
  3900. }
  3901. end
  3902. end
  3903. end
  3904. end
  3905. def test_create_as_copy_should_copy_subtasks
  3906. @request.session[:user_id] = 2
  3907. issue = Issue.generate_with_descendants!
  3908. count = issue.descendants.count
  3909. assert_difference 'Issue.count', count + 1 do
  3910. post :create, :params => {
  3911. :project_id => 1,
  3912. :copy_from => issue.id,
  3913. :issue => {
  3914. :project_id => '1',
  3915. :tracker_id => '3',
  3916. :status_id => '1',
  3917. :subject => 'Copy with subtasks'
  3918. },
  3919. :copy_subtasks => '1'
  3920. }
  3921. end
  3922. copy = Issue.where(:parent_id => nil).order('id DESC').first
  3923. assert_equal count, copy.descendants.count
  3924. assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
  3925. end
  3926. def test_create_as_copy_to_a_different_project_should_copy_subtask_custom_fields
  3927. issue = Issue.generate! {|i| i.custom_field_values = {'2' => 'Foo'}}
  3928. child = Issue.generate!(:parent_issue_id => issue.id) {|i| i.custom_field_values = {'2' => 'Bar'}}
  3929. @request.session[:user_id] = 1
  3930. assert_difference 'Issue.count', 2 do
  3931. post :create, :params => {
  3932. :project_id => 'ecookbook',
  3933. :copy_from => issue.id,
  3934. :issue => {
  3935. :project_id => '2',
  3936. :tracker_id => 1,
  3937. :status_id => '1',
  3938. :subject => 'Copy with subtasks',
  3939. :custom_field_values => {
  3940. '2' => 'Foo'}
  3941. },
  3942. :copy_subtasks => '1'
  3943. }
  3944. end
  3945. child_copy, issue_copy = Issue.order(:id => :desc).limit(2).to_a
  3946. assert_equal 2, issue_copy.project_id
  3947. assert_equal 'Foo', issue_copy.custom_field_value(2)
  3948. assert_equal 'Bar', child_copy.custom_field_value(2)
  3949. end
  3950. def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
  3951. @request.session[:user_id] = 2
  3952. issue = Issue.generate_with_descendants!
  3953. assert_difference 'Issue.count', 1 do
  3954. post :create, :params => {
  3955. :project_id => 1,
  3956. :copy_from => 3,
  3957. :issue => {
  3958. :project_id => '1',
  3959. :tracker_id => '3',
  3960. :status_id => '1',
  3961. :subject => 'Copy with subtasks'
  3962. }
  3963. }
  3964. end
  3965. copy = Issue.where(:parent_id => nil).order('id DESC').first
  3966. assert_equal 0, copy.descendants.count
  3967. end
  3968. def test_create_as_copy_with_failure
  3969. @request.session[:user_id] = 2
  3970. post :create, :params => {
  3971. :project_id => 1,
  3972. :copy_from => 1,
  3973. :issue => {
  3974. :project_id => '2',
  3975. :tracker_id => '3',
  3976. :status_id => '1',
  3977. :subject => ''
  3978. }
  3979. }
  3980. assert_response :success
  3981. assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
  3982. assert_select 'select[name=?]', 'issue[project_id]' do
  3983. assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
  3984. assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
  3985. end
  3986. assert_select 'input[name=copy_from][value="1"]'
  3987. end
  3988. end
  3989. def test_create_as_copy_on_project_without_permission_should_ignore_target_project
  3990. @request.session[:user_id] = 2
  3991. assert !User.find(2).member_of?(Project.find(4))
  3992. assert_difference 'Issue.count' do
  3993. post :create, :params => {
  3994. :project_id => 1,
  3995. :copy_from => 1,
  3996. :issue => {
  3997. :project_id => '4',
  3998. :tracker_id => '3',
  3999. :status_id => '1',
  4000. :subject => 'Copy'
  4001. }
  4002. }
  4003. end
  4004. issue = Issue.order('id DESC').first
  4005. assert_equal 1, issue.project_id
  4006. end
  4007. def test_create_as_copy_with_watcher_user_ids_should_copy_watchers
  4008. @request.session[:user_id] = 2
  4009. copied = Issue.generate!
  4010. copied.add_watcher User.find(2)
  4011. copied.add_watcher User.find(3)
  4012. assert_difference 'Issue.count' do
  4013. post :create, :params => {
  4014. :project_id => 1,
  4015. :copy_from => copied.id,
  4016. :issue => {
  4017. :subject => 'Copy cleared watchers',
  4018. :watcher_user_ids => ['', '3']
  4019. }
  4020. }
  4021. end
  4022. issue = Issue.order('id DESC').first
  4023. assert_equal [3], issue.watcher_user_ids
  4024. end
  4025. def test_create_as_copy_without_watcher_user_ids_should_not_copy_watchers
  4026. @request.session[:user_id] = 2
  4027. copied = Issue.generate!
  4028. copied.add_watcher User.find(2)
  4029. copied.add_watcher User.find(3)
  4030. assert_difference 'Issue.count' do
  4031. post :create, :params => {
  4032. :project_id => 1,
  4033. :copy_from => copied.id,
  4034. :issue => {
  4035. :subject => 'Copy cleared watchers',
  4036. :watcher_user_ids => ['']
  4037. }
  4038. }
  4039. end
  4040. issue = Issue.order('id DESC').first
  4041. assert_equal [], issue.watcher_user_ids
  4042. end
  4043. def test_get_edit
  4044. @request.session[:user_id] = 2
  4045. get :edit, :params => {
  4046. :id => 1
  4047. }
  4048. assert_response :success
  4049. assert_select 'select[name=?]', 'issue[project_id]'
  4050. # Be sure we don't display inactive IssuePriorities
  4051. assert ! IssuePriority.find(15).active?
  4052. assert_select 'select[name=?]', 'issue[priority_id]' do
  4053. assert_select 'option[value="15"]', 0
  4054. end
  4055. end
  4056. def test_edit_should_hide_project_if_user_is_not_allowed_to_change_project
  4057. WorkflowPermission.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :field_name => 'project_id', :rule => 'readonly')
  4058. @request.session[:user_id] = 2
  4059. get :edit, :params => {
  4060. :id => 1
  4061. }
  4062. assert_response :success
  4063. assert_select 'select[name=?]', 'issue[project_id]', 0
  4064. end
  4065. def test_edit_should_not_hide_project_when_user_changes_the_project_even_if_project_is_readonly_on_target_project
  4066. WorkflowPermission.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :field_name => 'project_id', :rule => 'readonly')
  4067. issue = Issue.generate!(:project_id => 2)
  4068. @request.session[:user_id] = 2
  4069. get :edit, :params => {
  4070. :id => issue.id,
  4071. :issue => {
  4072. :project_id => 1
  4073. }
  4074. }
  4075. assert_response :success
  4076. assert_select 'select[name=?]', 'issue[project_id]'
  4077. end
  4078. def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
  4079. @request.session[:user_id] = 2
  4080. Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
  4081. get :edit, :params => {
  4082. :id => 1
  4083. }
  4084. assert_select 'input[name=?]', 'time_entry[hours]'
  4085. end
  4086. def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
  4087. @request.session[:user_id] = 2
  4088. Role.find_by_name('Manager').remove_permission! :log_time
  4089. get :edit, :params => {
  4090. :id => 1
  4091. }
  4092. assert_select 'input[name=?]', 'time_entry[hours]', 0
  4093. end
  4094. def test_get_edit_with_params
  4095. @request.session[:user_id] = 2
  4096. get :edit, :params => {
  4097. :id => 1,
  4098. :issue => {
  4099. :status_id => 5,
  4100. :priority_id => 7
  4101. },
  4102. :time_entry => {
  4103. :hours => '2.5',
  4104. :comments => 'test_get_edit_with_params',
  4105. :activity_id => 10
  4106. }
  4107. }
  4108. assert_response :success
  4109. assert_select 'select[name=?]', 'issue[status_id]' do
  4110. assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
  4111. end
  4112. assert_select 'select[name=?]', 'issue[priority_id]' do
  4113. assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
  4114. end
  4115. assert_select 'input[name=?][value="2.50"]', 'time_entry[hours]'
  4116. assert_select 'select[name=?]', 'time_entry[activity_id]' do
  4117. assert_select 'option[value="10"][selected=selected]', :text => 'Development'
  4118. end
  4119. assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
  4120. end
  4121. def test_get_edit_with_multi_custom_field
  4122. field = CustomField.find(1)
  4123. field.update_attribute :multiple, true
  4124. issue = Issue.find(1)
  4125. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  4126. issue.save!
  4127. @request.session[:user_id] = 2
  4128. get :edit, :params => {
  4129. :id => 1
  4130. }
  4131. assert_response :success
  4132. assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
  4133. assert_select 'option', 3
  4134. assert_select 'option[value=MySQL][selected=selected]'
  4135. assert_select 'option[value=Oracle][selected=selected]'
  4136. assert_select 'option[value=PostgreSQL]:not([selected])'
  4137. end
  4138. end
  4139. def test_get_edit_with_me_assigned_to_id
  4140. @request.session[:user_id] = 2
  4141. get :edit, :params => {
  4142. :id => 1,
  4143. :issue => { :assigned_to_id => 'me' }
  4144. }
  4145. assert_response :success
  4146. assert_select 'select[name=?]', 'issue[assigned_to_id]' do
  4147. assert_select 'option[value="2"][selected=selected]'
  4148. end
  4149. end
  4150. def test_update_form_for_existing_issue
  4151. @request.session[:user_id] = 2
  4152. patch :edit, :params => {
  4153. :id => 1,
  4154. :issue => {
  4155. :tracker_id => 2,
  4156. :subject => 'This is the test_new issue',
  4157. :description => 'This is the description',
  4158. :priority_id => 5
  4159. }
  4160. },
  4161. :xhr => true
  4162. assert_response :success
  4163. assert_equal 'text/javascript', response.content_type
  4164. assert_include 'This is the test_new issue', response.body
  4165. end
  4166. def test_update_form_for_existing_issue_should_keep_issue_author
  4167. @request.session[:user_id] = 3
  4168. patch :edit, :params => {
  4169. :id => 1,
  4170. :issue => {
  4171. :subject => 'Changed'
  4172. }
  4173. }
  4174. assert_response :success
  4175. assert_equal User.find(2), Issue.find(1).author
  4176. end
  4177. def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
  4178. @request.session[:user_id] = 2
  4179. WorkflowTransition.delete_all
  4180. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
  4181. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
  4182. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
  4183. patch :edit, :params => {
  4184. :id => 2,
  4185. :issue => {
  4186. :tracker_id => 2,
  4187. :status_id => 5,
  4188. :subject => 'This is an issue'
  4189. }
  4190. }
  4191. assert_select 'select[name=?]', 'issue[status_id]' do
  4192. assert_select 'option[value="1"]'
  4193. assert_select 'option[value="2"]'
  4194. assert_select 'option[value="5"][selected=selected]'
  4195. assert_select 'option', 3
  4196. end
  4197. end
  4198. def test_update_form_for_existing_issue_with_project_change
  4199. @request.session[:user_id] = 2
  4200. patch :edit, :params => {
  4201. :id => 1,
  4202. :issue => {
  4203. :project_id => 2,
  4204. :tracker_id => 2,
  4205. :subject => 'This is the test_new issue',
  4206. :description => 'This is the description',
  4207. :priority_id => 5
  4208. }
  4209. }
  4210. assert_response :success
  4211. assert_select 'select[name=?]', 'issue[project_id]' do
  4212. assert_select 'option[value="2"][selected=selected]'
  4213. end
  4214. assert_select 'select[name=?]', 'issue[tracker_id]' do
  4215. assert_select 'option[value="2"][selected=selected]'
  4216. end
  4217. assert_select 'input[name=?][value=?]', 'issue[subject]', 'This is the test_new issue'
  4218. end
  4219. def test_update_form_should_keep_category_with_same_when_changing_project
  4220. source = Project.generate!
  4221. target = Project.generate!
  4222. source_category = IssueCategory.create!(:name => 'Foo', :project => source)
  4223. target_category = IssueCategory.create!(:name => 'Foo', :project => target)
  4224. issue = Issue.generate!(:project => source, :category => source_category)
  4225. @request.session[:user_id] = 1
  4226. patch :edit, :params => {
  4227. :id => issue.id,
  4228. :issue => {
  4229. :project_id => target.id,
  4230. :category_id => source_category.id
  4231. }
  4232. }
  4233. assert_response :success
  4234. assert_select 'select[name=?]', 'issue[category_id]' do
  4235. assert_select 'option[value=?][selected=selected]', target_category.id.to_s
  4236. end
  4237. end
  4238. def test_update_form_should_propose_default_status_for_existing_issue
  4239. @request.session[:user_id] = 2
  4240. WorkflowTransition.delete_all
  4241. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
  4242. patch :edit, :params => {
  4243. :id => 2
  4244. }
  4245. assert_response :success
  4246. assert_select 'select[name=?]', 'issue[status_id]' do
  4247. assert_select 'option[value="2"]'
  4248. assert_select 'option[value="3"]'
  4249. assert_select 'option', 2
  4250. end
  4251. end
  4252. def test_put_update_without_custom_fields_param
  4253. @request.session[:user_id] = 2
  4254. issue = Issue.find(1)
  4255. assert_equal '125', issue.custom_value_for(2).value
  4256. assert_difference('Journal.count') do
  4257. assert_difference('JournalDetail.count') do
  4258. put :update, :params => {
  4259. :id => 1,
  4260. :issue => {
  4261. :subject => 'New subject'
  4262. }
  4263. }
  4264. end
  4265. end
  4266. assert_redirected_to :action => 'show', :id => '1'
  4267. issue.reload
  4268. assert_equal 'New subject', issue.subject
  4269. # Make sure custom fields were not cleared
  4270. assert_equal '125', issue.custom_value_for(2).value
  4271. end
  4272. def test_put_update_with_project_change
  4273. @request.session[:user_id] = 2
  4274. ActionMailer::Base.deliveries.clear
  4275. with_settings :notified_events => %w(issue_updated) do
  4276. assert_difference('Journal.count') do
  4277. assert_difference('JournalDetail.count', 3) do
  4278. put :update, :params => {
  4279. :id => 1,
  4280. :issue => {
  4281. :project_id => '2',
  4282. :tracker_id => '1', # no change
  4283. :priority_id => '6',
  4284. :category_id => '3'
  4285. }
  4286. }
  4287. end
  4288. end
  4289. end
  4290. assert_redirected_to :action => 'show', :id => '1'
  4291. issue = Issue.find(1)
  4292. assert_equal 2, issue.project_id
  4293. assert_equal 1, issue.tracker_id
  4294. assert_equal 6, issue.priority_id
  4295. assert_equal 3, issue.category_id
  4296. mail = ActionMailer::Base.deliveries.last
  4297. assert_not_nil mail
  4298. assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
  4299. assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
  4300. end
  4301. def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
  4302. target = Project.generate!(:tracker_ids => [])
  4303. assert target.trackers.empty?
  4304. issue = Issue.generate!
  4305. @request.session[:user_id] = 1
  4306. put :update, :params => {
  4307. :id => issue.id,
  4308. :issue => {
  4309. :project_id => target.id
  4310. }
  4311. }
  4312. assert_response 302
  4313. end
  4314. def test_put_update_with_tracker_change
  4315. @request.session[:user_id] = 2
  4316. ActionMailer::Base.deliveries.clear
  4317. with_settings :notified_events => %w(issue_updated) do
  4318. assert_difference('Journal.count') do
  4319. assert_difference('JournalDetail.count', 3) do
  4320. put :update, :params => {
  4321. :id => 1,
  4322. :issue => {
  4323. :project_id => '1',
  4324. :tracker_id => '2',
  4325. :priority_id => '6'
  4326. }
  4327. }
  4328. end
  4329. end
  4330. end
  4331. assert_redirected_to :action => 'show', :id => '1'
  4332. issue = Issue.find(1)
  4333. assert_equal 1, issue.project_id
  4334. assert_equal 2, issue.tracker_id
  4335. assert_equal 6, issue.priority_id
  4336. assert_equal 1, issue.category_id
  4337. mail = ActionMailer::Base.deliveries.last
  4338. assert_not_nil mail
  4339. assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
  4340. assert_mail_body_match "Tracker changed from Bug to Feature request", mail
  4341. end
  4342. def test_put_update_with_custom_field_change
  4343. @request.session[:user_id] = 2
  4344. issue = Issue.find(1)
  4345. assert_equal '125', issue.custom_value_for(2).value
  4346. with_settings :notified_events => %w(issue_updated) do
  4347. assert_difference('Journal.count') do
  4348. assert_difference('JournalDetail.count', 3) do
  4349. put :update, :params => {
  4350. :id => 1,
  4351. :issue => {
  4352. :subject => 'Custom field change',
  4353. :priority_id => '6',
  4354. :category_id => '1', # no change
  4355. :custom_field_values => { '2' => 'New custom value' }
  4356. }
  4357. }
  4358. end
  4359. end
  4360. end
  4361. assert_redirected_to :action => 'show', :id => '1'
  4362. issue.reload
  4363. assert_equal 'New custom value', issue.custom_value_for(2).value
  4364. mail = ActionMailer::Base.deliveries.last
  4365. assert_not_nil mail
  4366. assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
  4367. end
  4368. def test_put_update_with_multi_custom_field_change
  4369. field = CustomField.find(1)
  4370. field.update_attribute :multiple, true
  4371. issue = Issue.find(1)
  4372. issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
  4373. issue.save!
  4374. @request.session[:user_id] = 2
  4375. assert_difference('Journal.count') do
  4376. assert_difference('JournalDetail.count', 3) do
  4377. put :update, :params => {
  4378. :id => 1,
  4379. :issue => {
  4380. :subject => 'Custom field change',
  4381. :custom_field_values => {
  4382. '1' => ['', 'Oracle', 'PostgreSQL']
  4383. }
  4384. }
  4385. }
  4386. end
  4387. end
  4388. assert_redirected_to :action => 'show', :id => '1'
  4389. assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
  4390. end
  4391. def test_put_update_with_status_and_assignee_change
  4392. issue = Issue.find(1)
  4393. assert_equal 1, issue.status_id
  4394. @request.session[:user_id] = 2
  4395. with_settings :notified_events => %w(issue_updated) do
  4396. assert_difference('TimeEntry.count', 0) do
  4397. put :update, :params => {
  4398. :id => 1,
  4399. :issue => {
  4400. :status_id => 2,
  4401. :assigned_to_id => 3,
  4402. :notes => 'Assigned to dlopper'
  4403. },
  4404. :time_entry => {
  4405. :hours => '',
  4406. :comments => '',
  4407. :activity_id => TimeEntryActivity.first
  4408. }
  4409. }
  4410. end
  4411. end
  4412. assert_redirected_to :action => 'show', :id => '1'
  4413. issue.reload
  4414. assert_equal 2, issue.status_id
  4415. j = Journal.order('id DESC').first
  4416. assert_equal 'Assigned to dlopper', j.notes
  4417. assert_equal 2, j.details.size
  4418. mail = ActionMailer::Base.deliveries.last
  4419. assert_mail_body_match "Status changed from New to Assigned", mail
  4420. # subject should contain the new status
  4421. assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
  4422. end
  4423. def test_put_update_with_note_only
  4424. notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
  4425. with_settings :notified_events => %w(issue_updated) do
  4426. # anonymous user
  4427. put :update, :params => {
  4428. :id => 1,
  4429. :issue => {
  4430. :notes => notes
  4431. }
  4432. }
  4433. end
  4434. assert_redirected_to :action => 'show', :id => '1'
  4435. j = Journal.order('id DESC').first
  4436. assert_equal notes, j.notes
  4437. assert_equal 0, j.details.size
  4438. assert_equal User.anonymous, j.user
  4439. mail = ActionMailer::Base.deliveries.last
  4440. assert_mail_body_match notes, mail
  4441. end
  4442. def test_put_update_with_private_note_only
  4443. notes = 'Private note'
  4444. @request.session[:user_id] = 2
  4445. assert_difference 'Journal.count' do
  4446. put :update, :params => {
  4447. :id => 1,
  4448. :issue => {
  4449. :notes => notes,
  4450. :private_notes => '1'
  4451. }
  4452. }
  4453. assert_redirected_to :action => 'show', :id => '1'
  4454. end
  4455. j = Journal.order('id DESC').first
  4456. assert_equal notes, j.notes
  4457. assert_equal true, j.private_notes
  4458. end
  4459. def test_put_update_with_private_note_and_changes
  4460. notes = 'Private note'
  4461. @request.session[:user_id] = 2
  4462. assert_difference 'Journal.count', 2 do
  4463. put :update, :params => {
  4464. :id => 1,
  4465. :issue => {
  4466. :subject => 'New subject',
  4467. :notes => notes,
  4468. :private_notes => '1'
  4469. }
  4470. }
  4471. assert_redirected_to :action => 'show', :id => '1'
  4472. end
  4473. j = Journal.order('id DESC').first
  4474. assert_equal notes, j.notes
  4475. assert_equal true, j.private_notes
  4476. assert_equal 0, j.details.count
  4477. j = Journal.order('id DESC').offset(1).first
  4478. assert_nil j.notes
  4479. assert_equal false, j.private_notes
  4480. assert_equal 1, j.details.count
  4481. end
  4482. def test_put_update_with_note_and_spent_time
  4483. @request.session[:user_id] = 2
  4484. spent_hours_before = Issue.find(1).spent_hours
  4485. assert_difference('TimeEntry.count') do
  4486. put :update, :params => {
  4487. :id => 1,
  4488. :issue => {
  4489. :notes => '2.5 hours added'
  4490. },
  4491. :time_entry => {
  4492. :hours => '2.5',
  4493. :comments => 'test_put_update_with_note_and_spent_time',
  4494. :activity_id => TimeEntryActivity.first.id
  4495. }
  4496. }
  4497. end
  4498. assert_redirected_to :action => 'show', :id => '1'
  4499. issue = Issue.find(1)
  4500. j = Journal.order('id DESC').first
  4501. assert_equal '2.5 hours added', j.notes
  4502. assert_equal 0, j.details.size
  4503. t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
  4504. assert_not_nil t
  4505. assert_equal 2.5, t.hours
  4506. assert_equal spent_hours_before + 2.5, issue.spent_hours
  4507. end
  4508. def test_put_update_should_preserve_parent_issue_even_if_not_visible
  4509. parent = Issue.generate!(:project_id => 1, :is_private => true)
  4510. issue = Issue.generate!(:parent_issue_id => parent.id)
  4511. assert !parent.visible?(User.find(3))
  4512. @request.session[:user_id] = 3
  4513. get :edit, :params => {
  4514. :id => issue.id
  4515. }
  4516. assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
  4517. put :update, :params => {
  4518. :id => issue.id,
  4519. :issue => {
  4520. :subject => 'New subject',
  4521. :parent_issue_id => parent.id.to_s
  4522. }
  4523. }
  4524. assert_response 302
  4525. assert_equal parent, issue.parent
  4526. end
  4527. def test_put_update_with_attachment_only
  4528. set_tmp_attachments_directory
  4529. # Delete all fixtured journals, a race condition can occur causing the wrong
  4530. # journal to get fetched in the next find.
  4531. Journal.delete_all
  4532. JournalDetail.delete_all
  4533. with_settings :notified_events => %w(issue_updated) do
  4534. # anonymous user
  4535. assert_difference 'Attachment.count' do
  4536. put :update, :params => {
  4537. :id => 1,
  4538. :issue => {
  4539. :notes => ''
  4540. },
  4541. :attachments => {
  4542. '1' => {
  4543. 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
  4544. }
  4545. }
  4546. end
  4547. end
  4548. assert_redirected_to :action => 'show', :id => '1'
  4549. j = Issue.find(1).journals.reorder('id DESC').first
  4550. assert j.notes.blank?
  4551. assert_equal 1, j.details.size
  4552. assert_equal 'testfile.txt', j.details.first.value
  4553. assert_equal User.anonymous, j.user
  4554. attachment = Attachment.order('id DESC').first
  4555. assert_equal Issue.find(1), attachment.container
  4556. assert_equal User.anonymous, attachment.author
  4557. assert_equal 'testfile.txt', attachment.filename
  4558. assert_equal 'text/plain', attachment.content_type
  4559. assert_equal 'test file', attachment.description
  4560. assert_equal 59, attachment.filesize
  4561. assert File.exists?(attachment.diskfile)
  4562. assert_equal 59, File.size(attachment.diskfile)
  4563. mail = ActionMailer::Base.deliveries.last
  4564. assert_mail_body_match 'testfile.txt', mail
  4565. end
  4566. def test_put_update_with_failure_should_save_attachments
  4567. set_tmp_attachments_directory
  4568. @request.session[:user_id] = 2
  4569. assert_no_difference 'Journal.count' do
  4570. assert_difference 'Attachment.count' do
  4571. put :update, :params => {
  4572. :id => 1,
  4573. :issue => {
  4574. :subject => ''
  4575. },
  4576. :attachments => {
  4577. '1' => {
  4578. 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
  4579. }
  4580. }
  4581. assert_response :success
  4582. end
  4583. end
  4584. attachment = Attachment.order('id DESC').first
  4585. assert_equal 'testfile.txt', attachment.filename
  4586. assert File.exists?(attachment.diskfile)
  4587. assert_nil attachment.container
  4588. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  4589. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  4590. end
  4591. def test_put_update_with_failure_should_keep_saved_attachments
  4592. set_tmp_attachments_directory
  4593. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  4594. @request.session[:user_id] = 2
  4595. assert_no_difference 'Journal.count' do
  4596. assert_no_difference 'Attachment.count' do
  4597. put :update, :params => {
  4598. :id => 1,
  4599. :issue => {
  4600. :subject => ''
  4601. },
  4602. :attachments => {
  4603. 'p0' => {
  4604. 'token' => attachment.token}
  4605. }
  4606. }
  4607. assert_response :success
  4608. end
  4609. end
  4610. assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
  4611. assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
  4612. end
  4613. def test_put_update_should_attach_saved_attachments
  4614. set_tmp_attachments_directory
  4615. attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
  4616. @request.session[:user_id] = 2
  4617. assert_difference 'Journal.count' do
  4618. assert_difference 'JournalDetail.count' do
  4619. assert_no_difference 'Attachment.count' do
  4620. put :update, :params => {
  4621. :id => 1,
  4622. :issue => {
  4623. :notes => 'Attachment added'
  4624. },
  4625. :attachments => {
  4626. 'p0' => {
  4627. 'token' => attachment.token}
  4628. }
  4629. }
  4630. assert_redirected_to '/issues/1'
  4631. end
  4632. end
  4633. end
  4634. attachment.reload
  4635. assert_equal Issue.find(1), attachment.container
  4636. journal = Journal.order('id DESC').first
  4637. assert_equal 1, journal.details.size
  4638. assert_equal 'testfile.txt', journal.details.first.value
  4639. end
  4640. def test_put_update_with_attachment_that_fails_to_save
  4641. set_tmp_attachments_directory
  4642. # anonymous user
  4643. with_settings :attachment_max_size => 0 do
  4644. put :update, :params => {
  4645. :id => 1,
  4646. :issue => {
  4647. :notes => ''
  4648. },
  4649. :attachments => {
  4650. '1' => {
  4651. 'file' => uploaded_test_file('testfile.txt', 'text/plain')}
  4652. }
  4653. }
  4654. assert_redirected_to :action => 'show', :id => '1'
  4655. assert_equal '1 file(s) could not be saved.', flash[:warning]
  4656. end
  4657. end
  4658. def test_put_update_with_attachment_deletion_should_create_a_single_journal
  4659. set_tmp_attachments_directory
  4660. ActionMailer::Base.deliveries.clear
  4661. @request.session[:user_id] = 2
  4662. journal = new_record(Journal) do
  4663. assert_difference 'Attachment.count', -2 do
  4664. put :update, :params => {
  4665. :id => 3,
  4666. :issue => {
  4667. :notes => 'Removing attachments',
  4668. :deleted_attachment_ids => ['1', '5']
  4669. }
  4670. }
  4671. end
  4672. end
  4673. assert_equal 'Removing attachments', journal.notes
  4674. assert_equal 2, journal.details.count
  4675. assert_select_email do
  4676. assert_select 'ul.journal.details li', 2
  4677. assert_select 'del', :text => 'error281.txt'
  4678. assert_select 'del', :text => 'changeset_iso8859-1.diff'
  4679. end
  4680. end
  4681. def test_put_update_with_attachment_deletion_and_failure_should_preserve_selected_attachments
  4682. set_tmp_attachments_directory
  4683. @request.session[:user_id] = 2
  4684. assert_no_difference 'Journal.count' do
  4685. assert_no_difference 'Attachment.count' do
  4686. put :update, :params => {
  4687. :id => 3,
  4688. :issue => {
  4689. :subject => '',
  4690. :notes => 'Removing attachments',
  4691. :deleted_attachment_ids => ['1', '5']
  4692. }
  4693. }
  4694. end
  4695. end
  4696. assert_select 'input[name=?][value="1"][checked=checked]', 'issue[deleted_attachment_ids][]'
  4697. assert_select 'input[name=?][value="5"][checked=checked]', 'issue[deleted_attachment_ids][]'
  4698. assert_select 'input[name=?][value="6"]:not([checked])', 'issue[deleted_attachment_ids][]'
  4699. end
  4700. def test_put_update_with_no_change
  4701. issue = Issue.find(1)
  4702. issue.journals.clear
  4703. ActionMailer::Base.deliveries.clear
  4704. put :update, :params => {
  4705. :id => 1,
  4706. :issue => {
  4707. :notes => ''
  4708. }
  4709. }
  4710. assert_redirected_to :action => 'show', :id => '1'
  4711. issue.reload
  4712. assert issue.journals.empty?
  4713. # No email should be sent
  4714. assert ActionMailer::Base.deliveries.empty?
  4715. end
  4716. def test_put_update_should_send_a_notification
  4717. @request.session[:user_id] = 2
  4718. ActionMailer::Base.deliveries.clear
  4719. issue = Issue.find(1)
  4720. old_subject = issue.subject
  4721. new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
  4722. with_settings :notified_events => %w(issue_updated) do
  4723. put :update, :params => {
  4724. :id => 1,
  4725. :issue => {
  4726. :subject => new_subject,
  4727. :priority_id => '6',
  4728. :category_id => '1' # no change
  4729. }
  4730. }
  4731. assert_equal 2, ActionMailer::Base.deliveries.size
  4732. end
  4733. end
  4734. def test_put_update_with_invalid_spent_time_hours_only
  4735. @request.session[:user_id] = 2
  4736. notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
  4737. assert_no_difference('Journal.count') do
  4738. put :update, :params => {
  4739. :id => 1,
  4740. :issue => {
  4741. :notes => notes
  4742. },
  4743. :time_entry => {
  4744. "comments"=>"", "activity_id"=>"", "hours"=>"2z"
  4745. }
  4746. }
  4747. end
  4748. assert_response :success
  4749. assert_select_error /Activity cannot be blank/
  4750. assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
  4751. assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
  4752. end
  4753. def test_put_update_with_invalid_spent_time_comments_only
  4754. @request.session[:user_id] = 2
  4755. notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
  4756. assert_no_difference('Journal.count') do
  4757. put :update, :params => {
  4758. :id => 1,
  4759. :issue => {
  4760. :notes => notes
  4761. },
  4762. :time_entry => {
  4763. "comments"=>"this is my comment", "activity_id"=>"", "hours"=>""
  4764. }
  4765. }
  4766. end
  4767. assert_response :success
  4768. assert_select_error /Activity cannot be blank/
  4769. assert_select_error /Hours cannot be blank/
  4770. assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
  4771. assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
  4772. end
  4773. def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
  4774. issue = Issue.find(2)
  4775. @request.session[:user_id] = 2
  4776. put :update, :params => {
  4777. :id => issue.id,
  4778. :issue => {
  4779. :fixed_version_id => 4
  4780. }
  4781. }
  4782. assert_response :redirect
  4783. issue.reload
  4784. assert_equal 4, issue.fixed_version_id
  4785. assert_not_equal issue.project_id, issue.fixed_version.project_id
  4786. end
  4787. def test_put_update_should_redirect_back_using_the_back_url_parameter
  4788. issue = Issue.find(2)
  4789. @request.session[:user_id] = 2
  4790. put :update, :params => {
  4791. :id => issue.id,
  4792. :issue => {
  4793. :fixed_version_id => 4
  4794. },
  4795. :back_url => '/issues'
  4796. }
  4797. assert_response :redirect
  4798. assert_redirected_to '/issues'
  4799. end
  4800. def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
  4801. issue = Issue.find(2)
  4802. @request.session[:user_id] = 2
  4803. put :update, :params => {
  4804. :id => issue.id,
  4805. :issue => {
  4806. :fixed_version_id => 4
  4807. },
  4808. :back_url => 'http://google.com'
  4809. }
  4810. assert_response :redirect
  4811. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
  4812. end
  4813. def test_put_update_should_redirect_with_previous_and_next_issue_ids_params
  4814. @request.session[:user_id] = 2
  4815. put :update, :params => {
  4816. :id => 11,
  4817. :issue => {
  4818. :status_id => 6,
  4819. :notes => 'Notes'
  4820. },
  4821. :prev_issue_id => 8,
  4822. :next_issue_id => 12,
  4823. :issue_position => 2,
  4824. :issue_count => 3
  4825. }
  4826. assert_redirected_to '/issues/11?issue_count=3&issue_position=2&next_issue_id=12&prev_issue_id=8'
  4827. end
  4828. def test_update_with_permission_on_tracker_should_be_allowed
  4829. role = Role.find(1)
  4830. role.set_permission_trackers :edit_issues, [1]
  4831. role.save!
  4832. issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'Original subject')
  4833. @request.session[:user_id] = 2
  4834. put :update, :params => {
  4835. :id => issue.id,
  4836. :issue => {
  4837. :subject => 'Changed subject'
  4838. }
  4839. }
  4840. assert_response 302
  4841. assert_equal 'Changed subject', issue.reload.subject
  4842. end
  4843. def test_update_without_permission_on_tracker_should_be_denied
  4844. role = Role.find(1)
  4845. role.set_permission_trackers :edit_issues, [1]
  4846. role.save!
  4847. issue = Issue.generate!(:project_id => 1, :tracker_id => 2, :subject => 'Original subject')
  4848. @request.session[:user_id] = 2
  4849. put :update, :params => {
  4850. :id => issue.id,
  4851. :issue => {
  4852. :subject => 'Changed subject'
  4853. }
  4854. }
  4855. assert_response 302
  4856. assert_equal 'Original subject', issue.reload.subject
  4857. end
  4858. def test_update_with_me_assigned_to_id
  4859. @request.session[:user_id] = 2
  4860. issue = Issue.find(1)
  4861. assert_not_equal 2, issue.assigned_to_id
  4862. put :update, :params => {
  4863. :id => issue.id,
  4864. :issue => {
  4865. :assigned_to_id => 'me'
  4866. }
  4867. }
  4868. assert_response 302
  4869. assert_equal 2, issue.reload.assigned_to_id
  4870. end
  4871. def test_get_bulk_edit
  4872. @request.session[:user_id] = 2
  4873. get :bulk_edit, :params => {
  4874. :ids => [1, 3]
  4875. }
  4876. assert_response :success
  4877. assert_select 'ul#bulk-selection' do
  4878. assert_select 'li', 2
  4879. assert_select 'li a', :text => 'Bug #1'
  4880. end
  4881. assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
  4882. assert_select 'input[name=?]', 'ids[]', 2
  4883. assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
  4884. assert_select 'select[name=?]', 'issue[project_id]'
  4885. assert_select 'input[name=?]', 'issue[parent_issue_id]'
  4886. # Project specific custom field, date type
  4887. field = CustomField.find(9)
  4888. assert !field.is_for_all?
  4889. assert_equal 'date', field.field_format
  4890. assert_select 'input[name=?]', 'issue[custom_field_values][9]'
  4891. # System wide custom field
  4892. assert CustomField.find(1).is_for_all?
  4893. assert_select 'select[name=?]', 'issue[custom_field_values][1]'
  4894. # Be sure we don't display inactive IssuePriorities
  4895. assert ! IssuePriority.find(15).active?
  4896. assert_select 'select[name=?]', 'issue[priority_id]' do
  4897. assert_select 'option[value="15"]', 0
  4898. end
  4899. end
  4900. end
  4901. def test_get_bulk_edit_on_different_projects
  4902. @request.session[:user_id] = 2
  4903. get :bulk_edit, :params => {
  4904. :ids => [1, 2, 6]
  4905. }
  4906. assert_response :success
  4907. # Can not set issues from different projects as children of an issue
  4908. assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
  4909. # Project specific custom field, date type
  4910. field = CustomField.find(9)
  4911. assert !field.is_for_all?
  4912. assert !field.project_ids.include?(Issue.find(6).project_id)
  4913. assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
  4914. end
  4915. def test_get_bulk_edit_with_user_custom_field
  4916. field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
  4917. @request.session[:user_id] = 2
  4918. get :bulk_edit, :params => {
  4919. :ids => [1, 2]
  4920. }
  4921. assert_response :success
  4922. assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
  4923. assert_select 'option', Project.find(1).users.count + 3 # "no change" + "none" + "me" options
  4924. end
  4925. end
  4926. def test_get_bulk_edit_with_version_custom_field
  4927. field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
  4928. @request.session[:user_id] = 2
  4929. get :bulk_edit, :params => {
  4930. :ids => [1, 2]
  4931. }
  4932. assert_response :success
  4933. assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
  4934. assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
  4935. end
  4936. end
  4937. def test_get_bulk_edit_with_multi_custom_field
  4938. field = CustomField.find(1)
  4939. field.update_attribute :multiple, true
  4940. @request.session[:user_id] = 2
  4941. get :bulk_edit, :params => {
  4942. :ids => [1, 3]
  4943. }
  4944. assert_response :success
  4945. assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
  4946. assert_select 'option', field.possible_values.size + 1 # "none" options
  4947. end
  4948. end
  4949. def test_bulk_edit_should_propose_to_clear_text_custom_fields
  4950. @request.session[:user_id] = 2
  4951. get :bulk_edit, :params => {
  4952. :ids => [1, 3]
  4953. }
  4954. assert_response :success
  4955. assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
  4956. end
  4957. def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
  4958. WorkflowTransition.delete_all
  4959. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  4960. :old_status_id => 1, :new_status_id => 1)
  4961. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  4962. :old_status_id => 1, :new_status_id => 3)
  4963. WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
  4964. :old_status_id => 1, :new_status_id => 4)
  4965. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  4966. :old_status_id => 2, :new_status_id => 1)
  4967. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  4968. :old_status_id => 2, :new_status_id => 3)
  4969. WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
  4970. :old_status_id => 2, :new_status_id => 5)
  4971. @request.session[:user_id] = 2
  4972. get :bulk_edit, :params => {
  4973. :ids => [1, 2]
  4974. }
  4975. assert_select 'select[name=?]', 'issue[status_id]' do
  4976. assert_select 'option[value=""]'
  4977. assert_select 'option[value="1"]'
  4978. assert_select 'option[value="3"]'
  4979. assert_select 'option', 3 # 2 statuses + "no change" option
  4980. end
  4981. end
  4982. def test_bulk_edit_should_propose_target_project_open_shared_versions
  4983. @request.session[:user_id] = 2
  4984. post :bulk_edit, :params => {
  4985. :ids => [1, 2, 6],
  4986. :issue => {
  4987. :project_id => 1
  4988. }
  4989. }
  4990. assert_response :success
  4991. expected_versions = Project.find(1).shared_versions.open.to_a.sort
  4992. assert_select 'select[name=?]', 'issue[fixed_version_id]' do
  4993. expected_versions.each do |version|
  4994. assert_select 'option[value=?]', version.id.to_s
  4995. end
  4996. assert_select 'option[value=""]'
  4997. assert_select 'option[value="none"]'
  4998. assert_select 'option', expected_versions.size + 2
  4999. end
  5000. end
  5001. def test_bulk_edit_should_propose_target_project_categories
  5002. @request.session[:user_id] = 2
  5003. post :bulk_edit, :params => {
  5004. :ids => [1, 2, 6],
  5005. :issue => {
  5006. :project_id => 1
  5007. }
  5008. }
  5009. assert_response :success
  5010. expected_categories = Project.find(1).issue_categories.sort
  5011. assert_select 'select[name=?]', 'issue[category_id]' do
  5012. expected_categories.each do |category|
  5013. assert_select 'option[value=?]', category.id.to_s
  5014. end
  5015. assert_select 'option[value=""]'
  5016. assert_select 'option[value="none"]'
  5017. assert_select 'option', expected_categories.size + 2
  5018. end
  5019. end
  5020. def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
  5021. IssueCustomField.delete_all
  5022. field1 = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
  5023. field2 = IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
  5024. @request.session[:user_id] = 2
  5025. issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
  5026. get :bulk_edit, :params => {
  5027. :ids => issue_ids
  5028. }
  5029. assert_response :success
  5030. assert_select 'input[name=?]', "issue[custom_field_values][#{field1.id}]"
  5031. assert_select 'input[name=?]', "issue[custom_field_values][#{field2.id}]", 0
  5032. end
  5033. def test_bulk_edit_should_propose_target_tracker_custom_fields
  5034. IssueCustomField.delete_all
  5035. field1 = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
  5036. field2 = IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
  5037. @request.session[:user_id] = 2
  5038. issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
  5039. get :bulk_edit, :params => {
  5040. :ids => issue_ids,
  5041. :issue => {
  5042. :tracker_id => 2
  5043. }
  5044. }
  5045. assert_response :success
  5046. assert_select 'input[name=?]', "issue[custom_field_values][#{field1.id}]", 0
  5047. assert_select 'input[name=?]', "issue[custom_field_values][#{field2.id}]"
  5048. end
  5049. def test_bulk_edit_should_warn_about_custom_field_values_about_to_be_cleared
  5050. CustomField.destroy_all
  5051. cleared = IssueCustomField.generate!(:name => 'Cleared', :tracker_ids => [2], :is_for_all => true)
  5052. CustomValue.create!(:customized => Issue.find(2), :custom_field => cleared, :value => 'foo')
  5053. not_cleared = IssueCustomField.generate!(:name => 'Not cleared', :tracker_ids => [2, 3], :is_for_all => true)
  5054. CustomValue.create!(:customized => Issue.find(2), :custom_field => not_cleared, :value => 'bar')
  5055. @request.session[:user_id] = 2
  5056. get :bulk_edit, :params => {
  5057. :ids => [1, 2],
  5058. :issue => {
  5059. :tracker_id => 3
  5060. }
  5061. }
  5062. assert_response :success
  5063. assert_select '.warning', :text => /automatic deletion of values/
  5064. assert_select '.warning span', :text => 'Cleared (1)'
  5065. assert_select '.warning span', :text => /Not cleared/, :count => 0
  5066. end
  5067. def test_bulk_update
  5068. @request.session[:user_id] = 2
  5069. # update issues priority
  5070. post :bulk_update, :params => {
  5071. :ids => [1, 2],
  5072. :notes => 'Bulk editing',
  5073. :issue => {
  5074. :priority_id => 7,
  5075. :assigned_to_id => '',
  5076. :custom_field_values => {
  5077. '2' => ''}
  5078. }
  5079. }
  5080. assert_response 302
  5081. # check that the issues were updated
  5082. assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
  5083. issue = Issue.find(1)
  5084. journal = issue.journals.reorder('created_on DESC').first
  5085. assert_equal '125', issue.custom_value_for(2).value
  5086. assert_equal 'Bulk editing', journal.notes
  5087. assert_equal 1, journal.details.size
  5088. end
  5089. def test_bulk_update_with_group_assignee
  5090. group = Group.find(11)
  5091. project = Project.find(1)
  5092. project.members << Member.new(:principal => group, :roles => [Role.givable.first])
  5093. @request.session[:user_id] = 2
  5094. # update issues assignee
  5095. with_settings :issue_group_assignment => '1' do
  5096. post :bulk_update, :params => {
  5097. :ids => [1, 2],
  5098. :notes => 'Bulk editing',
  5099. :issue => {
  5100. :priority_id => '',
  5101. :assigned_to_id => group.id,
  5102. :custom_field_values => {
  5103. '2' => ''}
  5104. }
  5105. }
  5106. assert_response 302
  5107. assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
  5108. end
  5109. end
  5110. def test_bulk_update_on_different_projects
  5111. @request.session[:user_id] = 2
  5112. # update issues priority
  5113. post :bulk_update, :params => {
  5114. :ids => [1, 2, 6],
  5115. :notes => 'Bulk editing',
  5116. :issue => {
  5117. :priority_id => 7,
  5118. :assigned_to_id => '',
  5119. :custom_field_values => {
  5120. '2' => ''}
  5121. }
  5122. }
  5123. assert_response 302
  5124. # check that the issues were updated
  5125. assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
  5126. issue = Issue.find(1)
  5127. journal = issue.journals.reorder('created_on DESC').first
  5128. assert_equal '125', issue.custom_value_for(2).value
  5129. assert_equal 'Bulk editing', journal.notes
  5130. assert_equal 1, journal.details.size
  5131. end
  5132. def test_bulk_update_on_different_projects_without_rights
  5133. @request.session[:user_id] = 3
  5134. user = User.find(3)
  5135. action = { :controller => "issues", :action => "bulk_update" }
  5136. assert user.allowed_to?(action, Issue.find(1).project)
  5137. assert ! user.allowed_to?(action, Issue.find(6).project)
  5138. post :bulk_update, :params => {
  5139. :ids => [1, 6],
  5140. :notes => 'Bulk should fail',
  5141. :issue => {
  5142. :priority_id => 7,
  5143. :assigned_to_id => '',
  5144. :custom_field_values => {
  5145. '2' => ''}
  5146. }
  5147. }
  5148. assert_response 403
  5149. assert_not_equal "Bulk should fail", Journal.last.notes
  5150. end
  5151. def test_bulk_update_should_send_a_notification
  5152. @request.session[:user_id] = 2
  5153. ActionMailer::Base.deliveries.clear
  5154. with_settings :notified_events => %w(issue_updated) do
  5155. post :bulk_update, :params => {
  5156. :ids => [1, 2],
  5157. :notes => 'Bulk editing',
  5158. :issue => {
  5159. :priority_id => 7,
  5160. :assigned_to_id => '',
  5161. :custom_field_values => {'2' => ''}
  5162. }
  5163. }
  5164. assert_response 302
  5165. # 4 emails for 2 members and 2 issues
  5166. # 1 email for a watcher of issue #2
  5167. assert_equal 5, ActionMailer::Base.deliveries.size
  5168. end
  5169. end
  5170. def test_bulk_update_project
  5171. @request.session[:user_id] = 2
  5172. post :bulk_update, :params => {
  5173. :ids => [1, 2],
  5174. :issue => {
  5175. :project_id => '2'
  5176. }
  5177. }
  5178. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5179. # Issues moved to project 2
  5180. assert_equal 2, Issue.find(1).project_id
  5181. assert_equal 2, Issue.find(2).project_id
  5182. # No tracker change
  5183. assert_equal 1, Issue.find(1).tracker_id
  5184. assert_equal 2, Issue.find(2).tracker_id
  5185. end
  5186. def test_bulk_update_project_on_single_issue_should_follow_when_needed
  5187. @request.session[:user_id] = 2
  5188. post :bulk_update, :params => {
  5189. :id => 1,
  5190. :issue => {
  5191. :project_id => '2'
  5192. },
  5193. :follow => '1'
  5194. }
  5195. assert_redirected_to '/issues/1'
  5196. end
  5197. def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
  5198. @request.session[:user_id] = 2
  5199. post :bulk_update, :params => {
  5200. :id => [1, 2],
  5201. :issue => {
  5202. :project_id => '2'
  5203. },
  5204. :follow => '1'
  5205. }
  5206. assert_redirected_to '/projects/onlinestore/issues'
  5207. end
  5208. def test_bulk_update_tracker
  5209. @request.session[:user_id] = 2
  5210. post :bulk_update, :params => {
  5211. :ids => [1, 2],
  5212. :issue => {
  5213. :tracker_id => '2'
  5214. }
  5215. }
  5216. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5217. assert_equal 2, Issue.find(1).tracker_id
  5218. assert_equal 2, Issue.find(2).tracker_id
  5219. end
  5220. def test_bulk_update_status
  5221. @request.session[:user_id] = 2
  5222. # update issues priority
  5223. post :bulk_update, :params => {
  5224. :ids => [1, 2],
  5225. :notes => 'Bulk editing status',
  5226. :issue => {
  5227. :priority_id => '',
  5228. :assigned_to_id => '',
  5229. :status_id => '5'
  5230. }
  5231. }
  5232. assert_response 302
  5233. issue = Issue.find(1)
  5234. assert issue.closed?
  5235. end
  5236. def test_bulk_update_priority
  5237. @request.session[:user_id] = 2
  5238. post :bulk_update, :params => {
  5239. :ids => [1, 2],
  5240. :issue => {
  5241. :priority_id => 6
  5242. }
  5243. }
  5244. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5245. assert_equal 6, Issue.find(1).priority_id
  5246. assert_equal 6, Issue.find(2).priority_id
  5247. end
  5248. def test_bulk_update_with_notes
  5249. @request.session[:user_id] = 2
  5250. post :bulk_update, :params => {
  5251. :ids => [1, 2],
  5252. :notes => 'Moving two issues'
  5253. }
  5254. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5255. assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
  5256. assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
  5257. assert_equal false, Issue.find(1).journals.sort_by(&:id).last.private_notes
  5258. assert_equal false, Issue.find(2).journals.sort_by(&:id).last.private_notes
  5259. end
  5260. def test_bulk_update_with_private_notes
  5261. @request.session[:user_id] = 2
  5262. post :bulk_update, :params => {
  5263. :ids => [1, 2],
  5264. :notes => 'Moving two issues',
  5265. :issue => {:private_notes => 'true'}
  5266. }
  5267. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5268. assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
  5269. assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
  5270. assert_equal true, Issue.find(1).journals.sort_by(&:id).last.private_notes
  5271. assert_equal true, Issue.find(2).journals.sort_by(&:id).last.private_notes
  5272. end
  5273. def test_bulk_update_parent_id
  5274. IssueRelation.delete_all
  5275. @request.session[:user_id] = 2
  5276. post :bulk_update, :params => {
  5277. :ids => [1, 3],
  5278. :notes => 'Bulk editing parent',
  5279. :issue => {
  5280. :priority_id => '',
  5281. :assigned_to_id => '',
  5282. :status_id => '',
  5283. :parent_issue_id => '2'
  5284. }
  5285. }
  5286. assert_response 302
  5287. parent = Issue.find(2)
  5288. assert_equal parent.id, Issue.find(1).parent_id
  5289. assert_equal parent.id, Issue.find(3).parent_id
  5290. assert_equal [1, 3], parent.children.collect(&:id).sort
  5291. end
  5292. def test_bulk_update_estimated_hours
  5293. @request.session[:user_id] = 2
  5294. post :bulk_update, :params => {
  5295. :ids => [1, 2],
  5296. :issue => {
  5297. :estimated_hours => 4.25
  5298. }
  5299. }
  5300. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
  5301. assert_equal 4.25, Issue.find(1).estimated_hours
  5302. assert_equal 4.25, Issue.find(2).estimated_hours
  5303. end
  5304. def test_bulk_update_custom_field
  5305. @request.session[:user_id] = 2
  5306. # update issues priority
  5307. post :bulk_update, :params => {
  5308. :ids => [1, 2],
  5309. :notes => 'Bulk editing custom field',
  5310. :issue => {
  5311. :priority_id => '',
  5312. :assigned_to_id => '',
  5313. :custom_field_values => {
  5314. '2' => '777'}
  5315. }
  5316. }
  5317. assert_response 302
  5318. issue = Issue.find(1)
  5319. journal = issue.journals.reorder('created_on DESC').first
  5320. assert_equal '777', issue.custom_value_for(2).value
  5321. assert_equal 1, journal.details.size
  5322. assert_equal '125', journal.details.first.old_value
  5323. assert_equal '777', journal.details.first.value
  5324. end
  5325. def test_bulk_update_custom_field_to_blank
  5326. @request.session[:user_id] = 2
  5327. post :bulk_update, :params => {
  5328. :ids => [1, 3],
  5329. :notes => 'Bulk editing custom field',
  5330. :issue => {
  5331. :priority_id => '',
  5332. :assigned_to_id => '',
  5333. :custom_field_values => {
  5334. '1' => '__none__'}
  5335. }
  5336. }
  5337. assert_response 302
  5338. assert_equal '', Issue.find(1).custom_field_value(1)
  5339. assert_equal '', Issue.find(3).custom_field_value(1)
  5340. end
  5341. def test_bulk_update_multi_custom_field
  5342. field = CustomField.find(1)
  5343. field.update_attribute :multiple, true
  5344. @request.session[:user_id] = 2
  5345. post :bulk_update, :params => {
  5346. :ids => [1, 2, 3],
  5347. :notes => 'Bulk editing multi custom field',
  5348. :issue => {
  5349. :priority_id => '',
  5350. :assigned_to_id => '',
  5351. :custom_field_values => {
  5352. '1' => ['MySQL', 'Oracle']}
  5353. }
  5354. }
  5355. assert_response 302
  5356. assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
  5357. assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
  5358. # the custom field is not associated with the issue tracker
  5359. assert_nil Issue.find(2).custom_field_value(1)
  5360. end
  5361. def test_bulk_update_multi_custom_field_to_blank
  5362. field = CustomField.find(1)
  5363. field.update_attribute :multiple, true
  5364. @request.session[:user_id] = 2
  5365. post :bulk_update, :params => {
  5366. :ids => [1, 3],
  5367. :notes => 'Bulk editing multi custom field',
  5368. :issue => {
  5369. :priority_id => '',
  5370. :assigned_to_id => '',
  5371. :custom_field_values => {
  5372. '1' => ['__none__']}
  5373. }
  5374. }
  5375. assert_response 302
  5376. assert_equal [''], Issue.find(1).custom_field_value(1)
  5377. assert_equal [''], Issue.find(3).custom_field_value(1)
  5378. end
  5379. def test_bulk_update_unassign
  5380. assert_not_nil Issue.find(2).assigned_to
  5381. @request.session[:user_id] = 2
  5382. # unassign issues
  5383. post :bulk_update, :params => {
  5384. :ids => [1, 2],
  5385. :notes => 'Bulk unassigning',
  5386. :issue => {
  5387. :assigned_to_id => 'none'
  5388. }
  5389. }
  5390. assert_response 302
  5391. # check that the issues were updated
  5392. assert_nil Issue.find(2).assigned_to
  5393. end
  5394. def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
  5395. @request.session[:user_id] = 2
  5396. post :bulk_update, :params => {
  5397. :ids => [1,2],
  5398. :issue => {
  5399. :fixed_version_id => 4
  5400. }
  5401. }
  5402. assert_response :redirect
  5403. issues = Issue.find([1,2])
  5404. issues.each do |issue|
  5405. assert_equal 4, issue.fixed_version_id
  5406. assert_not_equal issue.project_id, issue.fixed_version.project_id
  5407. end
  5408. end
  5409. def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
  5410. @request.session[:user_id] = 2
  5411. post :bulk_update, :params => {
  5412. :ids => [1,2],
  5413. :back_url => '/issues'
  5414. }
  5415. assert_response :redirect
  5416. assert_redirected_to '/issues'
  5417. end
  5418. def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
  5419. @request.session[:user_id] = 2
  5420. post :bulk_update, :params => {
  5421. :ids => [1,2],
  5422. :back_url => 'http://google.com'
  5423. }
  5424. assert_response :redirect
  5425. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
  5426. end
  5427. def test_bulk_update_with_all_failures_should_show_errors
  5428. @request.session[:user_id] = 2
  5429. post :bulk_update, :params => {
  5430. :ids => [1, 2],
  5431. :issue => {
  5432. :start_date => 'foo'
  5433. }
  5434. }
  5435. assert_response :success
  5436. assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
  5437. assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
  5438. end
  5439. def test_bulk_update_with_some_failures_should_show_errors
  5440. issue1 = Issue.generate!(:start_date => '2013-05-12')
  5441. issue2 = Issue.generate!(:start_date => '2013-05-15')
  5442. issue3 = Issue.generate!
  5443. @request.session[:user_id] = 2
  5444. post :bulk_update, :params => {
  5445. :ids => [issue1.id, issue2.id, issue3.id],
  5446. :issue => {
  5447. :due_date => '2013-05-01'
  5448. }
  5449. }
  5450. assert_response :success
  5451. assert_select '#errorExplanation span',
  5452. :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
  5453. assert_select '#errorExplanation ul li',
  5454. :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
  5455. assert_select '#bulk-selection li', 2
  5456. end
  5457. def test_bulk_update_with_failure_should_preserved_form_values
  5458. @request.session[:user_id] = 2
  5459. post :bulk_update, :params => {
  5460. :ids => [1, 2],
  5461. :issue => {
  5462. :tracker_id => '2',
  5463. :start_date => 'foo'
  5464. }
  5465. }
  5466. assert_response :success
  5467. assert_select 'select[name=?]', 'issue[tracker_id]' do
  5468. assert_select 'option[value="2"][selected=selected]'
  5469. end
  5470. assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
  5471. end
  5472. def test_get_bulk_copy
  5473. @request.session[:user_id] = 2
  5474. get :bulk_edit, :params => {
  5475. :ids => [1, 2, 3],
  5476. :copy => '1'
  5477. }
  5478. assert_response :success
  5479. assert_select '#bulk-selection li', 3
  5480. assert_select 'select[name=?]', 'issue[project_id]' do
  5481. assert_select 'option[value=""]'
  5482. end
  5483. assert_select 'input[name=copy_attachments]'
  5484. end
  5485. def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
  5486. user = setup_user_with_copy_but_not_add_permission
  5487. @request.session[:user_id] = user.id
  5488. get :bulk_edit, :params => {
  5489. :ids => [1, 2, 3],
  5490. :copy => '1'
  5491. }
  5492. assert_response :success
  5493. assert_select 'select[name=?]', 'issue[project_id]' do
  5494. assert_select 'option[value=""]', 0
  5495. assert_select 'option[value="2"]'
  5496. end
  5497. end
  5498. def test_bulk_copy_to_another_project
  5499. @request.session[:user_id] = 2
  5500. issue_ids = [1, 2]
  5501. assert_difference 'Issue.count', issue_ids.size do
  5502. assert_no_difference 'Project.find(1).issues.count' do
  5503. post :bulk_update, :params => {
  5504. :ids => issue_ids,
  5505. :issue => {
  5506. :project_id => '2'
  5507. },
  5508. :copy => '1'
  5509. }
  5510. end
  5511. end
  5512. assert_redirected_to '/projects/ecookbook/issues'
  5513. copies = Issue.order('id DESC').limit(issue_ids.size)
  5514. copies.each do |copy|
  5515. assert_equal 2, copy.project_id
  5516. end
  5517. end
  5518. def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
  5519. user = setup_user_with_copy_but_not_add_permission
  5520. @request.session[:user_id] = user.id
  5521. assert_difference 'Issue.count', 3 do
  5522. post :bulk_update, :params => {
  5523. :ids => [1, 2, 3],
  5524. :issue => {
  5525. :project_id => '2'
  5526. },
  5527. :copy => '1'
  5528. }
  5529. assert_response 302
  5530. end
  5531. end
  5532. def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
  5533. user = setup_user_with_copy_but_not_add_permission
  5534. @request.session[:user_id] = user.id
  5535. post :bulk_update, :params => {
  5536. :ids => [1, 2, 3],
  5537. :issue => {
  5538. :project_id => ''
  5539. },
  5540. :copy => '1'
  5541. }
  5542. assert_response 403
  5543. end
  5544. def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
  5545. user = setup_user_with_copy_but_not_add_permission
  5546. @request.session[:user_id] = user.id
  5547. post :bulk_update, :params => {
  5548. :ids => [1, 2, 3],
  5549. :issue => {
  5550. :project_id => '1'
  5551. },
  5552. :copy => '1'
  5553. }
  5554. assert_response 403
  5555. end
  5556. def test_bulk_copy_should_allow_not_changing_the_issue_attributes
  5557. @request.session[:user_id] = 2
  5558. issues = [
  5559. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
  5560. :priority_id => 2, :subject => 'issue 1', :author_id => 1,
  5561. :assigned_to_id => nil),
  5562. Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
  5563. :priority_id => 1, :subject => 'issue 2', :author_id => 2,
  5564. :assigned_to_id => 2)
  5565. ]
  5566. assert_difference 'Issue.count', issues.size do
  5567. post :bulk_update, :params => {
  5568. :ids => issues.map(&:id),
  5569. :copy => '1',
  5570. :issue => {
  5571. :project_id => '',
  5572. :tracker_id => '',
  5573. :assigned_to_id => '',
  5574. :status_id => '',
  5575. :start_date => '',
  5576. :due_date => ''
  5577. }
  5578. }
  5579. end
  5580. copies = Issue.order('id DESC').limit(issues.size)
  5581. issues.each do |orig|
  5582. copy = copies.detect {|c| c.subject == orig.subject}
  5583. assert_not_nil copy
  5584. assert_equal orig.project_id, copy.project_id
  5585. assert_equal orig.tracker_id, copy.tracker_id
  5586. assert_equal 1, copy.status_id
  5587. if orig.assigned_to_id
  5588. assert_equal orig.assigned_to_id, copy.assigned_to_id
  5589. else
  5590. assert_nil copy.assigned_to_id
  5591. end
  5592. assert_equal orig.priority_id, copy.priority_id
  5593. end
  5594. end
  5595. def test_bulk_copy_should_allow_changing_the_issue_attributes
  5596. # Fixes random test failure with Mysql
  5597. # where Issue.where(:project_id => 2).limit(2).order('id desc')
  5598. # doesn't return the expected results
  5599. Issue.where("project_id=2").delete_all
  5600. @request.session[:user_id] = 2
  5601. assert_difference 'Issue.count', 2 do
  5602. assert_no_difference 'Project.find(1).issues.count' do
  5603. post :bulk_update, :params => {
  5604. :ids => [1, 2],
  5605. :copy => '1',
  5606. :issue => {
  5607. :project_id => '2',
  5608. :tracker_id => '',
  5609. :assigned_to_id => '2',
  5610. :status_id => '1',
  5611. :start_date => '2009-12-01',
  5612. :due_date => '2009-12-31'
  5613. }
  5614. }
  5615. end
  5616. end
  5617. copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
  5618. assert_equal 2, copied_issues.size
  5619. copied_issues.each do |issue|
  5620. assert_equal 2, issue.project_id, "Project is incorrect"
  5621. assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect"
  5622. assert_equal 1, issue.status_id, "Status is incorrect"
  5623. assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
  5624. assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
  5625. end
  5626. end
  5627. def test_bulk_copy_should_allow_adding_a_note
  5628. @request.session[:user_id] = 2
  5629. assert_difference 'Issue.count', 1 do
  5630. post :bulk_update, :params => {
  5631. :ids => [1],
  5632. :copy => '1',
  5633. :notes => 'Copying one issue',
  5634. :issue => {
  5635. :project_id => '',
  5636. :tracker_id => '',
  5637. :status_id => '3',
  5638. :start_date => '2009-12-01',
  5639. :due_date => '2009-12-31'
  5640. }
  5641. }
  5642. end
  5643. issue = Issue.order('id DESC').first
  5644. assert_equal 1, issue.journals.size
  5645. journal = issue.journals.first
  5646. assert_equal 'Copying one issue', journal.notes
  5647. end
  5648. def test_bulk_copy_should_allow_not_copying_the_attachments
  5649. attachment_count = Issue.find(3).attachments.size
  5650. assert attachment_count > 0
  5651. @request.session[:user_id] = 2
  5652. assert_difference 'Issue.count', 1 do
  5653. assert_no_difference 'Attachment.count' do
  5654. post :bulk_update, :params => {
  5655. :ids => [3],
  5656. :copy => '1',
  5657. :copy_attachments => '0',
  5658. :issue => {
  5659. :project_id => ''
  5660. }
  5661. }
  5662. end
  5663. end
  5664. end
  5665. def test_bulk_copy_should_allow_copying_the_attachments
  5666. attachment_count = Issue.find(3).attachments.size
  5667. assert attachment_count > 0
  5668. @request.session[:user_id] = 2
  5669. assert_difference 'Issue.count', 1 do
  5670. assert_difference 'Attachment.count', attachment_count do
  5671. post :bulk_update, :params => {
  5672. :ids => [3],
  5673. :copy => '1',
  5674. :copy_attachments => '1',
  5675. :issue => {
  5676. :project_id => ''
  5677. }
  5678. }
  5679. end
  5680. end
  5681. end
  5682. def test_bulk_copy_should_add_relations_with_copied_issues
  5683. @request.session[:user_id] = 2
  5684. assert_difference 'Issue.count', 2 do
  5685. assert_difference 'IssueRelation.count', 2 do
  5686. post :bulk_update, :params => {
  5687. :ids => [1, 3],
  5688. :copy => '1',
  5689. :link_copy => '1',
  5690. :issue => {
  5691. :project_id => '1'
  5692. }
  5693. }
  5694. end
  5695. end
  5696. end
  5697. def test_bulk_copy_should_allow_not_copying_the_subtasks
  5698. issue = Issue.generate_with_descendants!
  5699. @request.session[:user_id] = 2
  5700. assert_difference 'Issue.count', 1 do
  5701. post :bulk_update, :params => {
  5702. :ids => [issue.id],
  5703. :copy => '1',
  5704. :copy_subtasks => '0',
  5705. :issue => {
  5706. :project_id => ''
  5707. }
  5708. }
  5709. end
  5710. end
  5711. def test_bulk_copy_should_allow_copying_the_subtasks
  5712. issue = Issue.generate_with_descendants!
  5713. count = issue.descendants.count
  5714. @request.session[:user_id] = 2
  5715. assert_difference 'Issue.count', count+1 do
  5716. post :bulk_update, :params => {
  5717. :ids => [issue.id],
  5718. :copy => '1',
  5719. :copy_subtasks => '1',
  5720. :issue => {
  5721. :project_id => ''
  5722. }
  5723. }
  5724. end
  5725. copy = Issue.where(:parent_id => nil).order("id DESC").first
  5726. assert_equal count, copy.descendants.count
  5727. end
  5728. def test_bulk_copy_should_allow_copying_the_subtasks
  5729. Watcher.create!(:watchable => Issue.find(1), :user => User.find(3))
  5730. @request.session[:user_id] = 2
  5731. assert_difference 'Issue.count' do
  5732. post :bulk_update, :params => {
  5733. :ids => [1],
  5734. :copy => '1',
  5735. :copy_watchers => '1',
  5736. :issue => {
  5737. :project_id => ''
  5738. }
  5739. }
  5740. end
  5741. copy = Issue.order(:id => :desc).first
  5742. assert_equal 1, copy.watchers.count
  5743. end
  5744. def test_bulk_copy_should_not_copy_selected_subtasks_twice
  5745. issue = Issue.generate_with_descendants!
  5746. count = issue.descendants.count
  5747. @request.session[:user_id] = 2
  5748. assert_difference 'Issue.count', count+1 do
  5749. post :bulk_update, :params => {
  5750. :ids => issue.self_and_descendants.map(&:id),
  5751. :copy => '1',
  5752. :copy_subtasks => '1',
  5753. :issue => {
  5754. :project_id => ''
  5755. }
  5756. }
  5757. end
  5758. copy = Issue.where(:parent_id => nil).order("id DESC").first
  5759. assert_equal count, copy.descendants.count
  5760. end
  5761. def test_bulk_copy_to_another_project_should_follow_when_needed
  5762. @request.session[:user_id] = 2
  5763. post :bulk_update, :params => {
  5764. :ids => [1],
  5765. :copy => '1',
  5766. :issue => {
  5767. :project_id => 2
  5768. },
  5769. :follow => '1'
  5770. }
  5771. issue = Issue.order('id DESC').first
  5772. assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
  5773. end
  5774. def test_bulk_copy_with_all_failures_should_display_errors
  5775. @request.session[:user_id] = 2
  5776. post :bulk_update, :params => {
  5777. :ids => [1, 2],
  5778. :copy => '1',
  5779. :issue => {
  5780. :start_date => 'foo'
  5781. }
  5782. }
  5783. assert_response :success
  5784. end
  5785. def test_destroy_issue_with_no_time_entries_should_delete_the_issues
  5786. assert_nil TimeEntry.find_by_issue_id(2)
  5787. @request.session[:user_id] = 2
  5788. assert_difference 'Issue.count', -1 do
  5789. delete :destroy, :params => {
  5790. :id => 2
  5791. }
  5792. end
  5793. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  5794. assert_nil Issue.find_by_id(2)
  5795. end
  5796. def test_destroy_issues_with_time_entries_should_show_the_reassign_form
  5797. @request.session[:user_id] = 2
  5798. with_settings :timelog_required_fields => [] do
  5799. assert_no_difference 'Issue.count' do
  5800. delete :destroy, :params => {
  5801. :ids => [1, 3]
  5802. }
  5803. end
  5804. end
  5805. assert_response :success
  5806. assert_select 'form' do
  5807. assert_select 'input[name=_method][value=delete]'
  5808. assert_select 'input[name=todo][value=destroy]'
  5809. assert_select 'input[name=todo][value=nullify]'
  5810. assert_select 'input[name=todo][value=reassign]'
  5811. end
  5812. end
  5813. def test_destroy_issues_with_time_entries_should_not_show_the_nullify_option_when_issue_is_required_for_time_entries
  5814. with_settings :timelog_required_fields => ['issue_id'] do
  5815. @request.session[:user_id] = 2
  5816. assert_no_difference 'Issue.count' do
  5817. delete :destroy, :params => {
  5818. :ids => [1, 3]
  5819. }
  5820. end
  5821. assert_response :success
  5822. assert_select 'form' do
  5823. assert_select 'input[name=_method][value=delete]'
  5824. assert_select 'input[name=todo][value=destroy]'
  5825. assert_select 'input[name=todo][value=nullify]', 0
  5826. assert_select 'input[name=todo][value=reassign]'
  5827. end
  5828. end
  5829. end
  5830. def test_destroy_issues_with_time_entries_should_show_hours_on_issues_and_descendants
  5831. parent = Issue.generate_with_child!
  5832. TimeEntry.generate!(:issue => parent)
  5833. TimeEntry.generate!(:issue => parent.children.first)
  5834. leaf = Issue.generate!
  5835. TimeEntry.generate!(:issue => leaf)
  5836. @request.session[:user_id] = 2
  5837. delete :destroy, :params => {
  5838. :ids => [parent.id, leaf.id]
  5839. }
  5840. assert_response :success
  5841. assert_select 'p', :text => /3\.00 hours were reported/
  5842. end
  5843. def test_destroy_issues_and_destroy_time_entries
  5844. @request.session[:user_id] = 2
  5845. assert_difference 'Issue.count', -2 do
  5846. assert_difference 'TimeEntry.count', -3 do
  5847. delete :destroy, :params => {
  5848. :ids => [1, 3],
  5849. :todo => 'destroy'
  5850. }
  5851. end
  5852. end
  5853. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  5854. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  5855. assert_nil TimeEntry.find_by_id([1, 2])
  5856. end
  5857. def test_destroy_issues_and_assign_time_entries_to_project
  5858. @request.session[:user_id] = 2
  5859. with_settings :timelog_required_fields => [] do
  5860. assert_difference 'Issue.count', -2 do
  5861. assert_no_difference 'TimeEntry.count' do
  5862. delete :destroy, :params => {
  5863. :ids => [1, 3],
  5864. :todo => 'nullify'
  5865. }
  5866. end
  5867. end
  5868. end
  5869. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  5870. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  5871. assert_nil TimeEntry.find(1).issue_id
  5872. assert_nil TimeEntry.find(2).issue_id
  5873. end
  5874. def test_destroy_issues_and_reassign_time_entries_to_another_issue
  5875. @request.session[:user_id] = 2
  5876. assert_difference 'Issue.count', -2 do
  5877. assert_no_difference 'TimeEntry.count' do
  5878. delete :destroy, :params => {
  5879. :ids => [1, 3],
  5880. :todo => 'reassign',
  5881. :reassign_to_id => 2
  5882. }
  5883. end
  5884. end
  5885. assert_redirected_to :action => 'index', :project_id => 'ecookbook'
  5886. assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
  5887. assert_equal 2, TimeEntry.find(1).issue_id
  5888. assert_equal 2, TimeEntry.find(2).issue_id
  5889. end
  5890. def test_destroy_issues_with_time_entries_should_reassign_time_entries_of_issues_and_descendants
  5891. parent = Issue.generate_with_child!
  5892. TimeEntry.generate!(:issue => parent)
  5893. TimeEntry.generate!(:issue => parent.children.first)
  5894. leaf = Issue.generate!
  5895. TimeEntry.generate!(:issue => leaf)
  5896. target = Issue.generate!
  5897. @request.session[:user_id] = 2
  5898. assert_difference 'Issue.count', -3 do
  5899. assert_no_difference 'TimeEntry.count' do
  5900. delete :destroy, :params => {
  5901. :ids => [parent.id, leaf.id],
  5902. :todo => 'reassign',
  5903. :reassign_to_id => target.id
  5904. }
  5905. assert_response 302
  5906. end
  5907. end
  5908. assert_equal 3, target.time_entries.count
  5909. end
  5910. def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
  5911. @request.session[:user_id] = 2
  5912. assert_no_difference 'Issue.count' do
  5913. assert_no_difference 'TimeEntry.count' do
  5914. # try to reassign time to an issue of another project
  5915. delete :destroy, :params => {
  5916. :ids => [1, 3],
  5917. :todo => 'reassign',
  5918. :reassign_to_id => 4
  5919. }
  5920. end
  5921. end
  5922. assert_response :success
  5923. end
  5924. def test_destroy_issues_and_reassign_time_entries_to_an_issue_to_delete_should_fail
  5925. @request.session[:user_id] = 2
  5926. assert_no_difference 'Issue.count' do
  5927. assert_no_difference 'TimeEntry.count' do
  5928. delete :destroy, :params => {
  5929. :ids => [1, 3],
  5930. :todo => 'reassign',
  5931. :reassign_to_id => 3
  5932. }
  5933. end
  5934. end
  5935. assert_response :success
  5936. assert_select '#flash_error', :text => I18n.t(:error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted)
  5937. end
  5938. def test_destroy_issues_and_nullify_time_entries_should_fail_when_issue_is_required_for_time_entries
  5939. @request.session[:user_id] = 2
  5940. with_settings :timelog_required_fields => ['issue_id'] do
  5941. assert_no_difference 'Issue.count' do
  5942. assert_no_difference 'TimeEntry.count' do
  5943. delete :destroy, :params => {
  5944. :ids => [1, 3],
  5945. :todo => 'nullify'
  5946. }
  5947. end
  5948. end
  5949. end
  5950. assert_response :success
  5951. assert_select '#flash_error', :text => 'Issue cannot be blank'
  5952. end
  5953. def test_destroy_issues_from_different_projects
  5954. @request.session[:user_id] = 2
  5955. assert_difference 'Issue.count', -3 do
  5956. delete :destroy, :params => {
  5957. :ids => [1, 2, 6],
  5958. :todo => 'destroy'
  5959. }
  5960. end
  5961. assert_redirected_to :controller => 'issues', :action => 'index'
  5962. assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
  5963. end
  5964. def test_destroy_parent_and_child_issues
  5965. parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
  5966. child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
  5967. assert child.is_descendant_of?(parent.reload)
  5968. @request.session[:user_id] = 2
  5969. assert_difference 'Issue.count', -2 do
  5970. delete :destroy, :params => {
  5971. :ids => [parent.id, child.id],
  5972. :todo => 'destroy'
  5973. }
  5974. end
  5975. assert_response 302
  5976. end
  5977. def test_destroy_invalid_should_respond_with_404
  5978. @request.session[:user_id] = 2
  5979. assert_no_difference 'Issue.count' do
  5980. delete :destroy, :params => {
  5981. :id => 999
  5982. }
  5983. end
  5984. assert_response 404
  5985. end
  5986. def test_destroy_with_permission_on_tracker_should_be_allowed
  5987. role = Role.find(1)
  5988. role.set_permission_trackers :delete_issues, [1]
  5989. role.save!
  5990. issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
  5991. @request.session[:user_id] = 2
  5992. assert_difference 'Issue.count', -1 do
  5993. delete :destroy, :params => {
  5994. :id => issue.id
  5995. }
  5996. end
  5997. assert_response 302
  5998. end
  5999. def test_destroy_without_permission_on_tracker_should_be_denied
  6000. role = Role.find(1)
  6001. role.set_permission_trackers :delete_issues, [2]
  6002. role.save!
  6003. issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
  6004. @request.session[:user_id] = 2
  6005. assert_no_difference 'Issue.count' do
  6006. delete :destroy, :params => {
  6007. :id => issue.id
  6008. }
  6009. end
  6010. assert_response 403
  6011. end
  6012. def test_default_search_scope
  6013. get :index
  6014. assert_select 'div#quick-search form' do
  6015. assert_select 'input[name=issues][value="1"][type=hidden]'
  6016. end
  6017. end
  6018. def setup_user_with_copy_but_not_add_permission
  6019. Role.all.each {|r| r.remove_permission! :add_issues}
  6020. Role.find_by_name('Manager').add_permission! :add_issues
  6021. user = User.generate!
  6022. User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
  6023. User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
  6024. user
  6025. end
  6026. def test_cancel_edit_link_for_issue_show_action_should_have_onclick_action
  6027. @request.session[:user_id] = 1
  6028. get :show, :params => {
  6029. :id => 1
  6030. }
  6031. assert_response :success
  6032. assert_select 'a[href=?][onclick=?]', "/issues/1", "$('#update').hide(); return false;", :text => 'Cancel'
  6033. end
  6034. def test_cancel_edit_link_for_issue_edit_action_should_not_have_onclick_action
  6035. @request.session[:user_id] = 1
  6036. get :edit, :params => {
  6037. :id => 1
  6038. }
  6039. assert_response :success
  6040. assert_select 'a[href=?][onclick=?]', "/issues/1", "", :text => 'Cancel'
  6041. end
  6042. def test_show_should_display_author_gravatar_only_when_not_assigned
  6043. issue = Issue.find(1)
  6044. assert_nil issue.assigned_to_id
  6045. @request.session[:user_id] = 1
  6046. with_settings :gravatar_enabled => '1' do
  6047. get :show, :params => {:id => issue.id}
  6048. assert_select 'div.gravatar-with-child' do
  6049. assert_select 'img.gravatar', 1
  6050. end
  6051. end
  6052. end
  6053. def test_show_should_display_author_and_assignee_gravatars_when_assigned
  6054. issue = Issue.find(1)
  6055. issue.assigned_to_id = 2
  6056. issue.save!
  6057. @request.session[:user_id] = 1
  6058. with_settings :gravatar_enabled => '1' do
  6059. get :show, :params => {:id => issue.id}
  6060. assert_select 'div.gravatar-with-child' do
  6061. assert_select 'img.gravatar', 2
  6062. assert_select 'img.gravatar-child', 1
  6063. end
  6064. end
  6065. end
  6066. end