test_pagure_flask_ui_repo.py 258 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals, absolute_import
  8. import datetime
  9. import json
  10. import unittest
  11. import re
  12. import shutil
  13. import sys
  14. import tempfile
  15. import time
  16. import os
  17. import pygit2
  18. import six
  19. from mock import ANY, patch, MagicMock
  20. sys.path.insert(
  21. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  22. )
  23. import pagure.lib.query
  24. import tests
  25. from pagure.lib.repo import PagureRepo
  26. from pagure.utils import __get_file_in_tree as get_file_in_tree
  27. class PagureFlaskRepotests(tests.Modeltests):
  28. """ Tests for flask app controller of pagure """
  29. def setUp(self):
  30. """ Set up the environnment, ran before every tests. """
  31. super(PagureFlaskRepotests, self).setUp()
  32. pagure.config.config["VIRUS_SCAN_ATTACHMENTS"] = False
  33. pagure.config.config["UPLOAD_FOLDER_URL"] = "/releases/"
  34. pagure.config.config["UPLOAD_FOLDER_PATH"] = os.path.join(
  35. self.path, "releases"
  36. )
  37. @patch("pagure.decorators.admin_session_timedout")
  38. def test_add_user_when_user_mngt_off(self, ast):
  39. """ Test the add_user endpoint when user management is turned off
  40. in the pagure instance """
  41. pagure.config.config["ENABLE_USER_MNGT"] = False
  42. ast.return_value = False
  43. # No Git repo
  44. output = self.app.get("/foo/adduser")
  45. self.assertEqual(output.status_code, 404)
  46. tests.create_projects(self.session)
  47. tests.create_projects_git(os.path.join(self.path, "repos"))
  48. # User not logged in
  49. output = self.app.get("/test/adduser")
  50. self.assertEqual(output.status_code, 302)
  51. user = tests.FakeUser(username="pingou")
  52. with tests.user_set(self.app.application, user):
  53. output = self.app.get("/test/adduser")
  54. self.assertEqual(output.status_code, 404)
  55. # just get the csrf token
  56. pagure.config.config["ENABLE_USER_MNGT"] = True
  57. output = self.app.get("/test/adduser")
  58. output_text = output.get_data(as_text=True)
  59. csrf_token = output_text.split(
  60. 'name="csrf_token" type="hidden" value="'
  61. )[1].split('">')[0]
  62. pagure.config.config["ENABLE_USER_MNGT"] = False
  63. data = {"user": "ralph"}
  64. output = self.app.post("/test/adduser", data=data)
  65. self.assertEqual(output.status_code, 404)
  66. data["csrf_token"] = csrf_token
  67. output = self.app.post("/test/adduser", data=data)
  68. self.assertEqual(output.status_code, 404)
  69. data["user"] = "foo"
  70. tests.create_projects_git(os.path.join(self.path, "repos"))
  71. output = self.app.post(
  72. "/test/adduser", data=data, follow_redirects=True
  73. )
  74. self.assertEqual(output.status_code, 404)
  75. pagure.config.config["ENABLE_USER_MNGT"] = True
  76. @patch("pagure.decorators.admin_session_timedout")
  77. def test_add_deploykey(self, ast):
  78. """ Test the add_deploykey endpoint. """
  79. ast.return_value = False
  80. # No git repo
  81. output = self.app.get("/foo/adddeploykey")
  82. self.assertEqual(output.status_code, 404)
  83. tests.create_projects(self.session)
  84. tests.create_projects_git(os.path.join(self.path, "repos"))
  85. # User not logged in
  86. output = self.app.get("/test/adddeploykey")
  87. self.assertEqual(output.status_code, 302)
  88. user = tests.FakeUser()
  89. with tests.user_set(self.app.application, user):
  90. output = self.app.get("/test/adddeploykey")
  91. self.assertEqual(output.status_code, 403)
  92. ast.return_value = True
  93. output = self.app.get("/test/adddeploykey")
  94. self.assertEqual(output.status_code, 302)
  95. # Redirect also happens for POST request
  96. output = self.app.post("/test/adddeploykey")
  97. self.assertEqual(output.status_code, 302)
  98. # Need to do this un-authentified since our fake user isn't in the DB
  99. # Check the message flashed during the redirect
  100. output = self.app.get("/", follow_redirects=True)
  101. self.assertEqual(output.status_code, 200)
  102. output_text = output.get_data(as_text=True)
  103. self.assertIn("Action canceled, try it " "again", output_text)
  104. ast.return_value = False
  105. user.username = "pingou"
  106. with tests.user_set(self.app.application, user):
  107. output = self.app.get("/test/adddeploykey")
  108. self.assertEqual(output.status_code, 200)
  109. output_text = output.get_data(as_text=True)
  110. self.assertIn("<strong>Add deploy key to the", output_text)
  111. csrf_token = output_text.split(
  112. 'name="csrf_token" type="hidden" value="'
  113. )[1].split('">')[0]
  114. data = {"ssh_key": "asdf", "pushaccess": "false"}
  115. # No CSRF token
  116. output = self.app.post("/test/adddeploykey", data=data)
  117. self.assertEqual(output.status_code, 200)
  118. output_text = output.get_data(as_text=True)
  119. self.assertIn("<strong>Add deploy key to the", output_text)
  120. data["csrf_token"] = csrf_token
  121. # First, invalid SSH key
  122. output = self.app.post("/test/adddeploykey", data=data)
  123. self.assertEqual(output.status_code, 200)
  124. output_text = output.get_data(as_text=True)
  125. self.assertIn("<strong>Add deploy key to the", output_text)
  126. self.assertIn("SSH key invalid", output_text)
  127. # Next up, multiple SSH keys
  128. data[
  129. "ssh_key"
  130. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=="
  131. output = self.app.post(
  132. "/test/adddeploykey", data=data, follow_redirects=True
  133. )
  134. self.assertEqual(output.status_code, 200)
  135. output_text = output.get_data(as_text=True)
  136. self.assertIn("Please add single SSH keys.", output_text)
  137. # Now, a valid SSH key
  138. data[
  139. "ssh_key"
  140. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=="
  141. output = self.app.post(
  142. "/test/adddeploykey", data=data, follow_redirects=True
  143. )
  144. self.assertEqual(output.status_code, 200)
  145. output_text = output.get_data(as_text=True)
  146. self.assertIn(
  147. "<title>Settings - test - Pagure</title>", output_text
  148. )
  149. self.assertIn(
  150. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  151. output_text,
  152. )
  153. self.assertIn("SSH key added", output_text)
  154. self.assertNotIn("Push Access", output_text)
  155. # And now, adding the same key
  156. output = self.app.post(
  157. "/test/adddeploykey", data=data, follow_redirects=True
  158. )
  159. self.assertEqual(output.status_code, 200)
  160. output_text = output.get_data(as_text=True)
  161. self.assertIn("SSH key already exists", output_text)
  162. # And next, a key with push access
  163. data[
  164. "ssh_key"
  165. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9Xwc2RDzPBhlEDARfHldGjudIVoa04tqT1JVKGQmyllTFz7Rb8CngQL3e7zyNzotnhwYKHdoiLlPkVEiDee4dWMUe48ilqId+FJZQGhyv8fu4BoFdE1AJUVylzmltbLg14VqG5gjTpXgtlrEva9arKwBMHJjRYc8ScaSn3OgyQw=="
  166. data["pushaccess"] = "true"
  167. output = self.app.post(
  168. "/test/adddeploykey", data=data, follow_redirects=True
  169. )
  170. self.assertEqual(output.status_code, 200)
  171. output_text = output.get_data(as_text=True)
  172. self.assertIn(
  173. "<title>Settings - test - Pagure</title>", output_text
  174. )
  175. self.assertIn(
  176. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  177. output_text,
  178. )
  179. self.assertIn("SSH key added", output_text)
  180. self.assertIn("Push Access", output_text)
  181. @patch("pagure.decorators.admin_session_timedout")
  182. @patch.dict("pagure.config.config", {"DEPLOY_KEY": False})
  183. def test_add_deploykey_disabled(self, ast):
  184. """ Test the add_deploykey endpoint when it's disabled in the config.
  185. """
  186. ast.return_value = False
  187. tests.create_projects(self.session)
  188. tests.create_projects_git(os.path.join(self.path, "repos"))
  189. user = tests.FakeUser(username="pingou")
  190. with tests.user_set(self.app.application, user):
  191. output = self.app.get("/test/adddeploykey")
  192. self.assertEqual(output.status_code, 404)
  193. output = self.app.post("/test/adddeploykey")
  194. self.assertEqual(output.status_code, 404)
  195. @patch("pagure.decorators.admin_session_timedout")
  196. @patch("pagure.lib.notify.log")
  197. def test_add_user(self, mock_log, ast):
  198. """ Test the add_user endpoint. """
  199. ast.return_value = False
  200. # No git repo
  201. output = self.app.get("/foo/adduser")
  202. self.assertEqual(output.status_code, 404)
  203. tests.create_projects(self.session)
  204. tests.create_projects_git(os.path.join(self.path, "repos"))
  205. # User not logged in
  206. output = self.app.get("/test/adduser")
  207. self.assertEqual(output.status_code, 302)
  208. user = tests.FakeUser()
  209. with tests.user_set(self.app.application, user):
  210. output = self.app.get("/test/adduser")
  211. self.assertEqual(output.status_code, 403)
  212. ast.return_value = True
  213. output = self.app.get("/test/adduser")
  214. self.assertEqual(output.status_code, 302)
  215. # Redirect also happens for POST request
  216. output = self.app.post("/test/adduser")
  217. self.assertEqual(output.status_code, 302)
  218. # Need to do this un-authentified since our fake user isn't in the DB
  219. # Check the message flashed during the redirect
  220. output = self.app.get("/", follow_redirects=True)
  221. self.assertEqual(output.status_code, 200)
  222. output_text = output.get_data(as_text=True)
  223. self.assertIn("Action canceled, try it " "again", output_text)
  224. ast.return_value = False
  225. user.username = "pingou"
  226. with tests.user_set(self.app.application, user):
  227. output = self.app.get("/test/adduser")
  228. self.assertEqual(output.status_code, 200)
  229. output_text = output.get_data(as_text=True)
  230. self.assertIn("<strong>Add user to the", output_text)
  231. csrf_token = output_text.split(
  232. 'name="csrf_token" type="hidden" value="'
  233. )[1].split('">')[0]
  234. data = {"user": "ralph"}
  235. # Missing access and no CSRF
  236. output = self.app.post("/test/adduser", data=data)
  237. self.assertEqual(output.status_code, 200)
  238. output_text = output.get_data(as_text=True)
  239. self.assertIn(
  240. "<title>Add user - test - Pagure</title>", output_text
  241. )
  242. self.assertIn("<strong>Add user to the", output_text)
  243. # No CSRF
  244. output = self.app.post("/test/adduser", data=data)
  245. self.assertEqual(output.status_code, 200)
  246. output_text = output.get_data(as_text=True)
  247. self.assertIn(
  248. "<title>Add user - test - Pagure</title>", output_text
  249. )
  250. # Missing access
  251. data["csrf_token"] = csrf_token
  252. output = self.app.post("/test/adduser", data=data)
  253. self.assertEqual(output.status_code, 200)
  254. output_text = output.get_data(as_text=True)
  255. self.assertIn(
  256. "<title>Add user - test - Pagure</title>", output_text
  257. )
  258. self.assertIn("<strong>Add user to the", output_text)
  259. # Unknown user
  260. data["access"] = "commit"
  261. output = self.app.post("/test/adduser", data=data)
  262. self.assertEqual(output.status_code, 200)
  263. output_text = output.get_data(as_text=True)
  264. self.assertIn(
  265. "<title>Add user - test - Pagure</title>", output_text
  266. )
  267. self.assertIn("<strong>Add user to the", output_text)
  268. self.assertIn("No user &#34;ralph&#34; found", output_text)
  269. # All correct
  270. data["user"] = "foo"
  271. output = self.app.post(
  272. "/test/adduser", data=data, follow_redirects=True
  273. )
  274. self.assertEqual(output.status_code, 200)
  275. output_text = output.get_data(as_text=True)
  276. self.assertIn(
  277. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  278. output_text,
  279. )
  280. self.assertIn("User added", output_text)
  281. mock_log.assert_called_with(ANY, topic="project.user.added", msg=ANY)
  282. @patch("pagure.decorators.admin_session_timedout")
  283. def test_add_group_project_when_user_mngt_off(self, ast):
  284. """ Test the add_group_project endpoint when user management is
  285. turned off in the pagure instance"""
  286. pagure.config.config["ENABLE_USER_MNGT"] = False
  287. ast.return_value = False
  288. # No Git repo
  289. output = self.app.get("/foo/addgroup")
  290. self.assertEqual(output.status_code, 404)
  291. tests.create_projects(self.session)
  292. tests.create_projects_git(os.path.join(self.path, "repos"))
  293. # User not logged in
  294. output = self.app.get("/test/addgroup")
  295. self.assertEqual(output.status_code, 302)
  296. msg = pagure.lib.query.add_group(
  297. self.session,
  298. group_name="foo",
  299. group_type="bar",
  300. display_name="foo group",
  301. description=None,
  302. user="pingou",
  303. is_admin=False,
  304. blacklist=pagure.config.config["BLACKLISTED_GROUPS"],
  305. )
  306. self.session.commit()
  307. self.assertEqual(msg, "User `pingou` added to the group `foo`.")
  308. user = tests.FakeUser(username="pingou")
  309. with tests.user_set(self.app.application, user):
  310. # just get the csrf token
  311. pagure.config.config["ENABLE_USER_MNGT"] = True
  312. output = self.app.get("/test/addgroup")
  313. output_text = output.get_data(as_text=True)
  314. csrf_token = output_text.split(
  315. 'name="csrf_token" type="hidden" value="'
  316. )[1].split('">')[0]
  317. pagure.config.config["ENABLE_USER_MNGT"] = False
  318. data = {"group": "ralph"}
  319. output = self.app.post("/test/addgroup", data=data)
  320. self.assertEqual(output.status_code, 404)
  321. data["csrf_token"] = csrf_token
  322. output = self.app.post("/test/addgroup", data=data)
  323. self.assertEqual(output.status_code, 404)
  324. data["group"] = "foo"
  325. output = self.app.post(
  326. "/test/addgroup", data=data, follow_redirects=True
  327. )
  328. self.assertEqual(output.status_code, 404)
  329. pagure.config.config["ENABLE_USER_MNGT"] = True
  330. @patch.dict("pagure.config.config", {"ENABLE_GROUP_MNGT": False})
  331. @patch("pagure.decorators.admin_session_timedout")
  332. def test_add_group_project_grp_mngt_off(self, ast):
  333. """ Test the add_group_project endpoint when group management is
  334. turned off in the pagure instance"""
  335. ast.return_value = False
  336. tests.create_projects(self.session)
  337. tests.create_projects_git(os.path.join(self.path, "repos"))
  338. user = tests.FakeUser(username="pingou")
  339. with tests.user_set(self.app.application, user):
  340. data = {
  341. "group": "ralph",
  342. "access": "ticket",
  343. "csrf_token": self.get_csrf(),
  344. }
  345. output = self.app.post(
  346. "/test/addgroup", data=data, follow_redirects=True
  347. )
  348. self.assertEqual(output.status_code, 200)
  349. output_text = output.get_data(as_text=True)
  350. self.assertIn(
  351. "<title>Add group - test - Pagure</title>", output_text
  352. )
  353. self.assertIn("No group ralph found.", output_text)
  354. @patch("pagure.decorators.admin_session_timedout")
  355. def test_add_group_project(self, ast):
  356. """ Test the add_group_project endpoint. """
  357. ast.return_value = False
  358. # No Git repo
  359. output = self.app.get("/foo/addgroup")
  360. self.assertEqual(output.status_code, 404)
  361. tests.create_projects(self.session)
  362. tests.create_projects_git(os.path.join(self.path, "repos"))
  363. # User not logged in
  364. output = self.app.get("/test/addgroup")
  365. self.assertEqual(output.status_code, 302)
  366. user = tests.FakeUser()
  367. with tests.user_set(self.app.application, user):
  368. output = self.app.get("/test/addgroup")
  369. self.assertEqual(output.status_code, 403)
  370. ast.return_value = True
  371. output = self.app.get("/test/addgroup")
  372. self.assertEqual(output.status_code, 302)
  373. # Redirect also happens for POST request
  374. output = self.app.post("/test/addgroup")
  375. self.assertEqual(output.status_code, 302)
  376. # Need to do this un-authentified since our fake user isn't in the DB
  377. # Check the message flashed during the redirect
  378. output = self.app.get("/", follow_redirects=True)
  379. self.assertEqual(output.status_code, 200)
  380. output_text = output.get_data(as_text=True)
  381. self.assertIn("Action canceled, try it " "again", output_text)
  382. ast.return_value = False
  383. msg = pagure.lib.query.add_group(
  384. self.session,
  385. group_name="foo",
  386. display_name="foo group",
  387. description=None,
  388. group_type="bar",
  389. user="pingou",
  390. is_admin=False,
  391. blacklist=pagure.config.config["BLACKLISTED_GROUPS"],
  392. )
  393. self.session.commit()
  394. self.assertEqual(msg, "User `pingou` added to the group `foo`.")
  395. user.username = "pingou"
  396. with tests.user_set(self.app.application, user):
  397. output = self.app.get("/test/addgroup")
  398. self.assertEqual(output.status_code, 200)
  399. output_text = output.get_data(as_text=True)
  400. self.assertIn("<strong>Add group to the", output_text)
  401. csrf_token = output_text.split(
  402. 'name="csrf_token" type="hidden" value="'
  403. )[1].split('">')[0]
  404. data = {"group": "ralph"}
  405. # Missing CSRF
  406. output = self.app.post("/test/addgroup", data=data)
  407. self.assertEqual(output.status_code, 200)
  408. output_text = output.get_data(as_text=True)
  409. self.assertIn(
  410. "<title>Add group - test - Pagure</title>", output_text
  411. )
  412. self.assertIn("<strong>Add group to the", output_text)
  413. # Missing access
  414. data["csrf_token"] = csrf_token
  415. output = self.app.post("/test/addgroup", data=data)
  416. self.assertEqual(output.status_code, 200)
  417. output_text = output.get_data(as_text=True)
  418. self.assertIn(
  419. "<title>Add group - test - Pagure</title>", output_text
  420. )
  421. self.assertIn("<strong>Add group to the", output_text)
  422. # All good
  423. data["access"] = "ticket"
  424. output = self.app.post(
  425. "/test/addgroup", data=data, follow_redirects=True
  426. )
  427. self.assertEqual(output.status_code, 200)
  428. output_text = output.get_data(as_text=True)
  429. self.assertIn(
  430. "<title>Settings - test - Pagure</title>", output_text
  431. )
  432. self.assertIn(
  433. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  434. output_text,
  435. )
  436. self.assertIn("Group added", output_text)
  437. @patch("pagure.decorators.admin_session_timedout")
  438. def test_remove_user_when_user_mngt_off(self, ast):
  439. """ Test the remove_user endpoint when user management is turned
  440. off in the pagure instance"""
  441. pagure.config.config["ENABLE_USER_MNGT"] = False
  442. ast.return_value = False
  443. # Git repo not found
  444. output = self.app.post("/foo/dropuser/1")
  445. self.assertEqual(output.status_code, 404)
  446. user = tests.FakeUser(username="pingou")
  447. with tests.user_set(self.app.application, user):
  448. tests.create_projects(self.session)
  449. tests.create_projects_git(os.path.join(self.path, "repos"))
  450. output = self.app.post("/test/settings")
  451. output_text = output.get_data(as_text=True)
  452. csrf_token = output_text.split(
  453. 'name="csrf_token" type="hidden" value="'
  454. )[1].split('">')[0]
  455. data = {"csrf_token": csrf_token}
  456. output = self.app.post(
  457. "/test/dropuser/2", data=data, follow_redirects=True
  458. )
  459. self.assertEqual(output.status_code, 404)
  460. # User not logged in
  461. output = self.app.post("/test/dropuser/1")
  462. self.assertEqual(output.status_code, 302)
  463. # Add an user to a project
  464. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  465. msg = pagure.lib.query.add_user_to_project(
  466. session=self.session, project=repo, new_user="foo", user="pingou"
  467. )
  468. self.session.commit()
  469. self.assertEqual(msg, "User added")
  470. with tests.user_set(self.app.application, user):
  471. output = self.app.post("/test/dropuser/2", follow_redirects=True)
  472. self.assertEqual(output.status_code, 404)
  473. data = {"csrf_token": csrf_token}
  474. output = self.app.post(
  475. "/test/dropuser/2", data=data, follow_redirects=True
  476. )
  477. self.assertEqual(output.status_code, 404)
  478. pagure.config.config["ENABLE_USER_MNGT"] = True
  479. @patch("pagure.decorators.admin_session_timedout")
  480. def test_remove_deploykey(self, ast):
  481. """ Test the remove_deploykey endpoint. """
  482. ast.return_value = False
  483. # Git repo not found
  484. output = self.app.post("/foo/dropdeploykey/1")
  485. self.assertEqual(output.status_code, 404)
  486. user = tests.FakeUser()
  487. with tests.user_set(self.app.application, user):
  488. output = self.app.post("/foo/dropdeploykey/1")
  489. self.assertEqual(output.status_code, 404)
  490. tests.create_projects(self.session)
  491. tests.create_projects_git(os.path.join(self.path, "repos"))
  492. output = self.app.post("/test/dropdeploykey/1")
  493. self.assertEqual(output.status_code, 403)
  494. ast.return_value = True
  495. output = self.app.post("/test/dropdeploykey/1")
  496. self.assertEqual(output.status_code, 302)
  497. ast.return_value = False
  498. # User not logged in
  499. output = self.app.post("/test/dropdeploykey/1")
  500. self.assertEqual(output.status_code, 302)
  501. user.username = "pingou"
  502. with tests.user_set(self.app.application, user):
  503. output = self.app.post("/test/settings")
  504. output_text = output.get_data(as_text=True)
  505. csrf_token = output_text.split(
  506. 'name="csrf_token" type="hidden" value="'
  507. )[1].split('">')[0]
  508. data = {"csrf_token": csrf_token}
  509. output = self.app.post(
  510. "/test/dropdeploykey/1", data=data, follow_redirects=True
  511. )
  512. self.assertEqual(output.status_code, 200)
  513. output_text = output.get_data(as_text=True)
  514. self.assertIn(
  515. "<title>Settings - test - Pagure</title>", output_text
  516. )
  517. self.assertIn(
  518. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  519. output_text,
  520. )
  521. self.assertIn("Deploy key does not exist in project", output_text)
  522. # Add a deploy key to a project
  523. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  524. pingou = pagure.lib.query.get_user(self.session, "pingou")
  525. msg = pagure.lib.query.add_sshkey_to_project_or_user(
  526. session=self.session,
  527. project=repo,
  528. ssh_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==",
  529. pushaccess=True,
  530. creator=pingou,
  531. )
  532. self.session.commit()
  533. self.assertEqual(msg, "SSH key added")
  534. with tests.user_set(self.app.application, user):
  535. output = self.app.post(
  536. "/test/dropdeploykey/1", follow_redirects=True
  537. )
  538. self.assertEqual(output.status_code, 200)
  539. output_text = output.get_data(as_text=True)
  540. self.assertIn(
  541. "<title>Settings - test - Pagure</title>", output_text
  542. )
  543. self.assertIn(
  544. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  545. output_text,
  546. )
  547. self.assertNotIn("Deploy key removed", output_text)
  548. data = {"csrf_token": csrf_token}
  549. output = self.app.post(
  550. "/test/dropdeploykey/1", data=data, follow_redirects=True
  551. )
  552. self.assertEqual(output.status_code, 200)
  553. output_text = output.get_data(as_text=True)
  554. self.assertIn(
  555. "<title>Settings - test - Pagure</title>", output_text
  556. )
  557. self.assertIn(
  558. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  559. output_text,
  560. )
  561. self.assertIn("Deploy key removed", output_text)
  562. @patch("pagure.decorators.admin_session_timedout")
  563. @patch.dict("pagure.config.config", {"DEPLOY_KEY": False})
  564. def test_remove_deploykey_disabled(self, ast):
  565. """ Test the remove_deploykey endpoint when it's disabled in the
  566. config.
  567. """
  568. ast.return_value = False
  569. tests.create_projects(self.session)
  570. tests.create_projects_git(os.path.join(self.path, "repos"))
  571. user = tests.FakeUser(username="pingou")
  572. with tests.user_set(self.app.application, user):
  573. output = self.app.post("/test/dropdeploykey/1")
  574. self.assertEqual(output.status_code, 404)
  575. @patch("pagure.decorators.admin_session_timedout")
  576. @patch("pagure.lib.notify.log")
  577. def test_remove_user(self, mock_log, ast):
  578. """ Test the remove_user endpoint. """
  579. ast.return_value = False
  580. # Git repo not found
  581. output = self.app.post("/foo/dropuser/1")
  582. self.assertEqual(output.status_code, 404)
  583. user = tests.FakeUser()
  584. with tests.user_set(self.app.application, user):
  585. output = self.app.post("/foo/dropuser/1")
  586. self.assertEqual(output.status_code, 404)
  587. tests.create_projects(self.session)
  588. tests.create_projects_git(os.path.join(self.path, "repos"))
  589. output = self.app.post("/test/dropuser/1")
  590. self.assertEqual(output.status_code, 403)
  591. ast.return_value = True
  592. output = self.app.post("/test/dropuser/1")
  593. self.assertEqual(output.status_code, 302)
  594. ast.return_value = False
  595. # User not logged in
  596. output = self.app.post("/test/dropuser/1")
  597. self.assertEqual(output.status_code, 302)
  598. user.username = "pingou"
  599. with tests.user_set(self.app.application, user):
  600. output = self.app.post("/test/settings")
  601. output_text = output.get_data(as_text=True)
  602. csrf_token = output_text.split(
  603. 'name="csrf_token" type="hidden" value="'
  604. )[1].split('">')[0]
  605. data = {"csrf_token": csrf_token}
  606. output = self.app.post(
  607. "/test/dropuser/2", data=data, follow_redirects=True
  608. )
  609. self.assertEqual(output.status_code, 200)
  610. output_text = output.get_data(as_text=True)
  611. self.assertIn(
  612. "<title>Settings - test - Pagure</title>", output_text
  613. )
  614. self.assertIn(
  615. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  616. output_text,
  617. )
  618. self.assertIn(
  619. "User does not have any " "access on the repo", output_text
  620. )
  621. # Add an user to a project
  622. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  623. self.assertEqual(len(repo.users), 0)
  624. msg = pagure.lib.query.add_user_to_project(
  625. session=self.session, project=repo, new_user="foo", user="pingou"
  626. )
  627. self.session.commit()
  628. self.assertEqual(msg, "User added")
  629. self.assertEqual(len(repo.users), 1)
  630. with tests.user_set(self.app.application, user):
  631. output = self.app.post("/test/dropuser/2", follow_redirects=True)
  632. self.assertEqual(output.status_code, 200)
  633. output_text = output.get_data(as_text=True)
  634. self.assertIn(
  635. "<title>Settings - test - Pagure</title>", output_text
  636. )
  637. self.assertIn(
  638. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  639. output_text,
  640. )
  641. self.assertNotIn("User removed", output_text)
  642. self.assertIn('action="/test/dropuser/2">', output_text)
  643. repo = pagure.lib.query.get_authorized_project(
  644. self.session, "test"
  645. )
  646. self.assertEqual(len(repo.users), 1)
  647. data = {"csrf_token": csrf_token}
  648. output = self.app.post(
  649. "/test/dropuser/2", data=data, follow_redirects=True
  650. )
  651. self.assertEqual(output.status_code, 200)
  652. output_text = output.get_data(as_text=True)
  653. self.assertIn(
  654. "<title>Settings - test - Pagure</title>", output_text
  655. )
  656. self.assertIn(
  657. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  658. output_text,
  659. )
  660. self.assertIn("User removed", output_text)
  661. self.assertNotIn('action="/test/dropuser/2">', output_text)
  662. self.session.commit()
  663. repo = pagure.lib.query.get_authorized_project(
  664. self.session, "test"
  665. )
  666. self.assertEqual(len(repo.users), 0)
  667. mock_log.assert_called_with(ANY, topic="project.user.removed", msg=ANY)
  668. @patch("pagure.decorators.admin_session_timedout")
  669. @patch("pagure.lib.notify.log")
  670. def test_remove_user_self(self, mock_log, ast):
  671. """ Test the remove_user endpoint when removing themselves. """
  672. ast.return_value = False
  673. tests.create_projects(self.session)
  674. tests.create_projects_git(os.path.join(self.path, "repos"))
  675. # Add an user to a project
  676. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  677. self.assertEqual(len(repo.users), 0)
  678. msg = pagure.lib.query.add_user_to_project(
  679. session=self.session, project=repo, new_user="foo", user="pingou"
  680. )
  681. self.session.commit()
  682. self.assertEqual(msg, "User added")
  683. self.assertEqual(len(repo.users), 1)
  684. # Let user foo remove themselves
  685. user = tests.FakeUser(username="foo")
  686. with tests.user_set(self.app.application, user):
  687. csrf_token = self.get_csrf()
  688. data = {"csrf_token": csrf_token}
  689. output = self.app.post(
  690. "/test/dropuser/2", data=data, follow_redirects=True
  691. )
  692. self.assertEqual(output.status_code, 200)
  693. output_text = output.get_data(as_text=True)
  694. self.assertIn(
  695. "<title>Overview - test - Pagure</title>", output_text
  696. )
  697. self.assertIn(
  698. '<h3 class="mb-0">\n<a href="/test"><strong>test</strong>'
  699. "</a>\n </h3>",
  700. output_text,
  701. )
  702. self.assertIn("User removed", output_text)
  703. self.session.commit()
  704. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  705. self.assertEqual(len(repo.users), 0)
  706. mock_log.assert_called_with(ANY, topic="project.user.removed", msg=ANY)
  707. @patch("pagure.decorators.admin_session_timedout")
  708. def test_remove_group_project_when_user_mngt_off(self, ast):
  709. """ Test the remove_group_project endpoint when user management is
  710. turned off in the pagure instance"""
  711. pagure.config.config["ENABLE_USER_MNGT"] = False
  712. ast.return_value = False
  713. # No Git repo
  714. output = self.app.post("/foo/dropgroup/1")
  715. self.assertEqual(output.status_code, 404)
  716. tests.create_projects(self.session)
  717. tests.create_projects_git(os.path.join(self.path, "repos"))
  718. # User not logged in
  719. output = self.app.post("/test/dropgroup/1")
  720. self.assertEqual(output.status_code, 302)
  721. user = tests.FakeUser()
  722. user.username = "pingou"
  723. with tests.user_set(self.app.application, user):
  724. output = self.app.post("/test/settings")
  725. output_text = output.get_data(as_text=True)
  726. csrf_token = output_text.split(
  727. 'name="csrf_token" type="hidden" value="'
  728. )[1].split('">')[0]
  729. data = {"csrf_token": csrf_token}
  730. output = self.app.post(
  731. "/test/dropgroup/2", data=data, follow_redirects=True
  732. )
  733. self.assertEqual(output.status_code, 404)
  734. # Create the new group
  735. msg = pagure.lib.query.add_group(
  736. session=self.session,
  737. group_name="testgrp",
  738. group_type="user",
  739. display_name="testgrp group",
  740. description=None,
  741. user="pingou",
  742. is_admin=False,
  743. blacklist=[],
  744. )
  745. self.assertEqual(msg, "User `pingou` added to the group `testgrp`.")
  746. self.session.commit()
  747. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  748. # Add the group to a project
  749. msg = pagure.lib.query.add_group_to_project(
  750. session=self.session,
  751. project=repo,
  752. new_group="testgrp",
  753. user="pingou",
  754. )
  755. self.session.commit()
  756. self.assertEqual(msg, "Group added")
  757. with tests.user_set(self.app.application, user):
  758. output = self.app.post("/test/dropgroup/1", follow_redirects=True)
  759. self.assertEqual(output.status_code, 404)
  760. data = {"csrf_token": csrf_token}
  761. output = self.app.post(
  762. "/test/dropgroup/1", data=data, follow_redirects=True
  763. )
  764. self.assertEqual(output.status_code, 404)
  765. pagure.config.config["ENABLE_USER_MNGT"] = True
  766. @patch("pagure.decorators.admin_session_timedout")
  767. def test_remove_group_project(self, ast):
  768. """ Test the remove_group_project endpoint. """
  769. ast.return_value = False
  770. # No Git repo
  771. output = self.app.post("/foo/dropgroup/1")
  772. self.assertEqual(output.status_code, 404)
  773. user = tests.FakeUser()
  774. with tests.user_set(self.app.application, user):
  775. output = self.app.post("/foo/dropgroup/1")
  776. self.assertEqual(output.status_code, 404)
  777. tests.create_projects(self.session)
  778. tests.create_projects_git(os.path.join(self.path, "repos"))
  779. output = self.app.post("/test/dropgroup/1")
  780. self.assertEqual(output.status_code, 403)
  781. ast.return_value = True
  782. output = self.app.post("/test/dropgroup/1")
  783. self.assertEqual(output.status_code, 302)
  784. ast.return_value = False
  785. # User not logged in
  786. output = self.app.post("/test/dropgroup/1")
  787. self.assertEqual(output.status_code, 302)
  788. user.username = "pingou"
  789. with tests.user_set(self.app.application, user):
  790. output = self.app.post("/test/settings")
  791. output_text = output.get_data(as_text=True)
  792. csrf_token = output_text.split(
  793. 'name="csrf_token" type="hidden" value="'
  794. )[1].split('">')[0]
  795. data = {"csrf_token": csrf_token}
  796. output = self.app.post(
  797. "/test/dropgroup/2", data=data, follow_redirects=True
  798. )
  799. self.assertEqual(output.status_code, 200)
  800. output_text = output.get_data(as_text=True)
  801. self.assertIn(
  802. "<title>Settings - test - Pagure</title>", output_text
  803. )
  804. self.assertIn(
  805. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  806. output_text,
  807. )
  808. self.assertIn(
  809. "" "Group does not seem to be part of this project",
  810. output_text,
  811. )
  812. # Create the new group
  813. msg = pagure.lib.query.add_group(
  814. session=self.session,
  815. group_name="testgrp",
  816. group_type="user",
  817. display_name="testgrp group",
  818. description=None,
  819. user="pingou",
  820. is_admin=False,
  821. blacklist=[],
  822. )
  823. self.assertEqual(msg, "User `pingou` added to the group `testgrp`.")
  824. self.session.commit()
  825. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  826. # Add the group to a project
  827. msg = pagure.lib.query.add_group_to_project(
  828. session=self.session,
  829. project=repo,
  830. new_group="testgrp",
  831. user="pingou",
  832. )
  833. self.session.commit()
  834. self.assertEqual(msg, "Group added")
  835. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  836. self.assertEqual(len(repo.groups), 1)
  837. with tests.user_set(self.app.application, user):
  838. output = self.app.post("/test/dropgroup/1", follow_redirects=True)
  839. self.assertEqual(output.status_code, 200)
  840. output_text = output.get_data(as_text=True)
  841. self.assertIn(
  842. "<title>Settings - test - Pagure</title>", output_text
  843. )
  844. self.assertIn(
  845. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  846. output_text,
  847. )
  848. self.assertIn('action="/test/dropgroup/1">', output_text)
  849. self.assertNotIn("Group removed", output_text)
  850. repo = pagure.lib.query.get_authorized_project(
  851. self.session, "test"
  852. )
  853. self.assertEqual(len(repo.groups), 1)
  854. data = {"csrf_token": csrf_token}
  855. output = self.app.post(
  856. "/test/dropgroup/1", data=data, follow_redirects=True
  857. )
  858. self.assertEqual(output.status_code, 200)
  859. output_text = output.get_data(as_text=True)
  860. self.assertIn(
  861. "<title>Settings - test - Pagure</title>", output_text
  862. )
  863. self.assertIn(
  864. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  865. output_text,
  866. )
  867. self.assertIn("Group removed", output_text)
  868. self.assertNotIn('action="/test/dropgroup/1">', output_text)
  869. self.session.commit()
  870. repo = pagure.lib.query.get_authorized_project(
  871. self.session, "test"
  872. )
  873. self.assertEqual(len(repo.groups), 0)
  874. @patch("pagure.decorators.admin_session_timedout")
  875. def test_update_project(self, ast):
  876. """ Test the update_project endpoint. """
  877. ast.return_value = True
  878. # Git repo not found
  879. output = self.app.post("/foo/update")
  880. self.assertEqual(output.status_code, 404)
  881. user = tests.FakeUser()
  882. with tests.user_set(self.app.application, user):
  883. # Project does not exist
  884. output = self.app.post("/foo/update")
  885. self.assertEqual(output.status_code, 404)
  886. tests.create_projects(self.session)
  887. tests.create_projects_git(os.path.join(self.path, "repos"))
  888. # Session timed-out
  889. output = self.app.post("/test/update")
  890. self.assertEqual(output.status_code, 302)
  891. ast.return_value = False
  892. # Not allowed
  893. output = self.app.post("/test/update")
  894. self.assertEqual(output.status_code, 403)
  895. # User not logged in
  896. output = self.app.post("/test/update")
  897. self.assertEqual(output.status_code, 302)
  898. user.username = "pingou"
  899. with tests.user_set(self.app.application, user):
  900. output = self.app.post("/test/update", follow_redirects=True)
  901. self.assertEqual(output.status_code, 200)
  902. output_text = output.get_data(as_text=True)
  903. self.assertIn(
  904. "<title>Settings - test - Pagure</title>", output_text
  905. )
  906. self.assertIn(
  907. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  908. output_text,
  909. )
  910. csrf_token = output_text.split(
  911. 'name="csrf_token" type="hidden" value="'
  912. )[1].split('">')[0]
  913. data = {
  914. "description": "new description for test project #1",
  915. "csrf_token": csrf_token,
  916. }
  917. output = self.app.post(
  918. "/test/update", data=data, follow_redirects=True
  919. )
  920. self.assertEqual(output.status_code, 200)
  921. output_text = output.get_data(as_text=True)
  922. self.assertIn(
  923. "<title>Settings - test - Pagure</title>", output_text
  924. )
  925. self.assertIn(
  926. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  927. output_text,
  928. )
  929. self.assertIn(
  930. '<input class="form-control" name="avatar_email" value="" />',
  931. output_text,
  932. )
  933. self.assertIn("Project updated", output_text)
  934. # Edit the avatar_email
  935. data = {
  936. "description": "new description for test project #1",
  937. "avatar_email": "pingou@fp.o",
  938. "csrf_token": csrf_token,
  939. }
  940. output = self.app.post(
  941. "/test/update", data=data, follow_redirects=True
  942. )
  943. self.assertEqual(output.status_code, 200)
  944. output_text = output.get_data(as_text=True)
  945. self.assertIn(
  946. "<title>Settings - test - Pagure</title>", output_text
  947. )
  948. self.assertIn(
  949. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  950. output_text,
  951. )
  952. self.assertIn(
  953. '<input class="form-control" name="avatar_email" value="pingou@fp.o" />',
  954. output_text,
  955. )
  956. self.assertIn("Project updated", output_text)
  957. # Reset the avatar_email
  958. data = {
  959. "description": "new description for test project #1",
  960. "avatar_email": "",
  961. "csrf_token": csrf_token,
  962. }
  963. output = self.app.post(
  964. "/test/update", data=data, follow_redirects=True
  965. )
  966. self.assertEqual(output.status_code, 200)
  967. output_text = output.get_data(as_text=True)
  968. self.assertIn(
  969. "<title>Settings - test - Pagure</title>", output_text
  970. )
  971. self.assertIn(
  972. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  973. output_text,
  974. )
  975. self.assertIn(
  976. '<input class="form-control" name="avatar_email" value="" />',
  977. output_text,
  978. )
  979. self.assertIn("Project updated", output_text)
  980. @patch("pagure.decorators.admin_session_timedout")
  981. def test_update_project_update_tag(self, ast):
  982. """ Test the view_settings endpoint when updating the project's tags.
  983. We had an issue where when you add an existing tag to a project we
  984. were querying the wrong table in the database. It would thus not find
  985. the tag, would try to add it, and (rightfully) complain about duplicated
  986. content.
  987. This test ensure we are behaving properly.
  988. """
  989. ast.return_value = False
  990. tests.create_projects(self.session)
  991. tests.create_projects_git(os.path.join(self.path, "repos"))
  992. user = tests.FakeUser(username="pingou")
  993. with tests.user_set(self.app.application, user):
  994. output = self.app.get("/test/settings")
  995. self.assertEqual(output.status_code, 200)
  996. output_text = output.get_data(as_text=True)
  997. self.assertIn(
  998. "<title>Settings - test - Pagure</title>", output_text
  999. )
  1000. self.assertIn(
  1001. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1002. output_text,
  1003. )
  1004. csrf_token = output_text.split(
  1005. 'name="csrf_token" type="hidden" value="'
  1006. )[1].split('">')[0]
  1007. # Add tag to a project so that they are added to the database
  1008. data = {
  1009. "csrf_token": csrf_token,
  1010. "description": "Test project",
  1011. "tags": "test,pagure,tag",
  1012. }
  1013. output = self.app.post(
  1014. "/test/update", data=data, follow_redirects=True
  1015. )
  1016. self.assertEqual(output.status_code, 200)
  1017. output_text = output.get_data(as_text=True)
  1018. self.assertIn(
  1019. "<title>Settings - test - Pagure</title>", output_text
  1020. )
  1021. self.assertIn(
  1022. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1023. output_text,
  1024. )
  1025. self.assertIn("Project updated", output_text)
  1026. # Remove two of the tags of the project, they will still be in
  1027. # the DB but not associated to this project
  1028. data = {
  1029. "csrf_token": csrf_token,
  1030. "description": "Test project",
  1031. "tags": "tag",
  1032. }
  1033. output = self.app.post(
  1034. "/test/update", data=data, follow_redirects=True
  1035. )
  1036. self.assertEqual(output.status_code, 200)
  1037. output_text = output.get_data(as_text=True)
  1038. self.assertIn(
  1039. "<title>Settings - test - Pagure</title>", output_text
  1040. )
  1041. self.assertIn(
  1042. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1043. output_text,
  1044. )
  1045. self.assertIn("Project updated", output_text)
  1046. # Try re-adding the two tags, this used to fail before we fixed
  1047. # it
  1048. data = {
  1049. "csrf_token": csrf_token,
  1050. "description": "Test project",
  1051. "tags": "test,pagure,tag",
  1052. }
  1053. output = self.app.post(
  1054. "/test/update", data=data, follow_redirects=True
  1055. )
  1056. self.assertEqual(output.status_code, 200)
  1057. output_text = output.get_data(as_text=True)
  1058. self.assertIn(
  1059. "<title>Settings - test - Pagure</title>", output_text
  1060. )
  1061. self.assertIn(
  1062. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1063. output_text,
  1064. )
  1065. self.assertIn("Project updated", output_text)
  1066. @patch("pagure.decorators.admin_session_timedout")
  1067. def test_view_settings(self, ast):
  1068. """ Test the view_settings endpoint. """
  1069. ast.return_value = False
  1070. # No Git repo
  1071. output = self.app.get("/foo/settings")
  1072. self.assertEqual(output.status_code, 404)
  1073. user = tests.FakeUser()
  1074. with tests.user_set(self.app.application, user):
  1075. output = self.app.get("/foo/settings")
  1076. self.assertEqual(output.status_code, 404)
  1077. tests.create_projects(self.session)
  1078. tests.create_projects_git(os.path.join(self.path, "repos"))
  1079. output = self.app.get("/test/settings")
  1080. self.assertEqual(output.status_code, 403)
  1081. # User not logged in
  1082. output = self.app.get("/test/settings")
  1083. self.assertEqual(output.status_code, 302)
  1084. user.username = "pingou"
  1085. with tests.user_set(self.app.application, user):
  1086. ast.return_value = True
  1087. output = self.app.get("/test/settings")
  1088. self.assertEqual(output.status_code, 302)
  1089. ast.return_value = False
  1090. output = self.app.get("/test/settings")
  1091. self.assertEqual(output.status_code, 200)
  1092. output_text = output.get_data(as_text=True)
  1093. self.assertIn(
  1094. "<title>Settings - test - Pagure</title>", output_text
  1095. )
  1096. self.assertIn(
  1097. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1098. output_text,
  1099. )
  1100. # Both checkbox checked before
  1101. self.assertIn(
  1102. '<input id="pull_requests" type="checkbox" value="y" '
  1103. 'name="pull_requests" checked=""/>',
  1104. output_text,
  1105. )
  1106. self.assertIn(
  1107. '<input id="issue_tracker" type="checkbox" value="y" '
  1108. 'name="issue_tracker" checked=""/>',
  1109. output_text,
  1110. )
  1111. csrf_token = output_text.split(
  1112. 'name="csrf_token" type="hidden" value="'
  1113. )[1].split('">')[0]
  1114. data = {}
  1115. output = self.app.post(
  1116. "/test/settings", data=data, follow_redirects=True
  1117. )
  1118. self.assertEqual(output.status_code, 200)
  1119. output_text = output.get_data(as_text=True)
  1120. self.assertIn(
  1121. "<title>Settings - test - Pagure</title>", output_text
  1122. )
  1123. self.assertIn(
  1124. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1125. output_text,
  1126. )
  1127. # Both checkbox are still checked
  1128. output = self.app.get("/test/settings", follow_redirects=True)
  1129. self.assertEqual(output.status_code, 200)
  1130. output_text = output.get_data(as_text=True)
  1131. self.assertIn(
  1132. "<title>Settings - test - Pagure</title>", output_text
  1133. )
  1134. self.assertIn(
  1135. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1136. output_text,
  1137. )
  1138. self.assertIn(
  1139. '<input id="pull_requests" type="checkbox" value="y" '
  1140. 'name="pull_requests" checked=""/>',
  1141. output_text,
  1142. )
  1143. self.assertIn(
  1144. '<input id="issue_tracker" type="checkbox" value="y" '
  1145. 'name="issue_tracker" checked=""/>',
  1146. output_text,
  1147. )
  1148. data = {"csrf_token": csrf_token}
  1149. output = self.app.post(
  1150. "/test/settings", data=data, follow_redirects=True
  1151. )
  1152. self.assertEqual(output.status_code, 200)
  1153. output_text = output.get_data(as_text=True)
  1154. self.assertIn(
  1155. "<title>Overview - test - Pagure</title>", output_text
  1156. )
  1157. self.assertIn(
  1158. "Edited successfully " "settings of repo: test", output_text
  1159. )
  1160. # Both checkbox are now un-checked
  1161. output = self.app.get("/test/settings", follow_redirects=True)
  1162. self.assertEqual(output.status_code, 200)
  1163. output_text = output.get_data(as_text=True)
  1164. self.assertIn(
  1165. "<title>Settings - test - Pagure</title>", output_text
  1166. )
  1167. self.assertIn(
  1168. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1169. output_text,
  1170. )
  1171. self.assertIn(
  1172. '<input id="pull_requests" type="checkbox" value="y" '
  1173. 'name="pull_requests" />',
  1174. output_text,
  1175. )
  1176. self.assertIn(
  1177. '<input id="issue_tracker" type="checkbox" value="y" '
  1178. 'name="issue_tracker" />',
  1179. output_text,
  1180. )
  1181. data = {
  1182. "csrf_token": csrf_token,
  1183. "pull_requests": "y",
  1184. "issue_tracker": "y",
  1185. }
  1186. output = self.app.post(
  1187. "/test/settings", data=data, follow_redirects=True
  1188. )
  1189. self.assertEqual(output.status_code, 200)
  1190. output_text = output.get_data(as_text=True)
  1191. self.assertIn(
  1192. "<title>Overview - test - Pagure</title>", output_text
  1193. )
  1194. self.assertIn(
  1195. "Edited successfully " "settings of repo: test", output_text
  1196. )
  1197. # Both checkbox are again checked
  1198. output = self.app.get("/test/settings", follow_redirects=True)
  1199. self.assertEqual(output.status_code, 200)
  1200. output_text = output.get_data(as_text=True)
  1201. self.assertIn(
  1202. "<title>Settings - test - Pagure</title>", output_text
  1203. )
  1204. self.assertIn(
  1205. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1206. output_text,
  1207. )
  1208. self.assertIn(
  1209. '<input id="pull_requests" type="checkbox" value="y" '
  1210. 'name="pull_requests" checked=""/>',
  1211. output_text,
  1212. )
  1213. self.assertIn(
  1214. '<input id="issue_tracker" type="checkbox" value="y" '
  1215. 'name="issue_tracker" checked=""/>',
  1216. output_text,
  1217. )
  1218. @patch(
  1219. "pagure.decorators.admin_session_timedout",
  1220. MagicMock(return_value=False),
  1221. )
  1222. def test_view_settings_custom_fields(self):
  1223. """ Test the view_settings endpoint when the project has some custom
  1224. field for issues. """
  1225. tests.create_projects(self.session)
  1226. tests.create_projects_git(os.path.join(self.path, "repos"))
  1227. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1228. msg = pagure.lib.query.set_custom_key_fields(
  1229. self.session,
  1230. repo,
  1231. ["bugzilla", "upstream", "reviewstatus"],
  1232. ["link", "boolean", "list"],
  1233. [
  1234. "unused data for non-list type",
  1235. "",
  1236. "ack",
  1237. "nack",
  1238. "needs review",
  1239. ],
  1240. [None, None, None],
  1241. )
  1242. self.session.commit()
  1243. self.assertEqual(msg, "List of custom fields updated")
  1244. self.assertIsNotNone(repo.issue_keys)
  1245. user = tests.FakeUser(username="pingou")
  1246. with tests.user_set(self.app.application, user):
  1247. output = self.app.get("/test/settings")
  1248. self.assertEqual(output.status_code, 200)
  1249. @patch("pagure.lib.git.generate_gitolite_acls")
  1250. @patch("pagure.decorators.admin_session_timedout")
  1251. def test_view_settings_pr_only(self, ast, gen_acl):
  1252. """ Test the view_settings endpoint when turning on PR only. """
  1253. ast.return_value = False
  1254. tests.create_projects(self.session)
  1255. tests.create_projects_git(os.path.join(self.path, "repos"))
  1256. user = tests.FakeUser(username="pingou")
  1257. with tests.user_set(self.app.application, user):
  1258. output = self.app.get("/test/settings")
  1259. self.assertEqual(output.status_code, 200)
  1260. output_text = output.get_data(as_text=True)
  1261. self.assertIn(
  1262. "<title>Settings - test - Pagure</title>", output_text
  1263. )
  1264. self.assertIn(
  1265. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1266. output_text,
  1267. )
  1268. csrf_token = self.get_csrf(output=output)
  1269. data = {
  1270. "csrf_token": csrf_token,
  1271. "pull_requests": "y",
  1272. "issue_tracker": "y",
  1273. "pull_request_access_only": "y",
  1274. }
  1275. output = self.app.post(
  1276. "/test/settings", data=data, follow_redirects=True
  1277. )
  1278. self.assertEqual(output.status_code, 200)
  1279. output_text = output.get_data(as_text=True)
  1280. self.assertIn(
  1281. "<title>Overview - test - Pagure</title>", output_text
  1282. )
  1283. self.assertIn(
  1284. "Edited successfully " "settings of repo: test", output_text
  1285. )
  1286. # Both checkbox are again checked
  1287. output = self.app.get("/test/settings", follow_redirects=True)
  1288. self.assertEqual(output.status_code, 200)
  1289. output_text = output.get_data(as_text=True)
  1290. self.assertIn(
  1291. "<title>Settings - test - Pagure</title>", output_text
  1292. )
  1293. self.assertIn(
  1294. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1295. output_text,
  1296. )
  1297. self.assertIn(
  1298. '<input id="pull_requests" type="checkbox" value="y" '
  1299. 'name="pull_requests" checked=""/>',
  1300. output_text,
  1301. )
  1302. self.assertIn(
  1303. '<input id="issue_tracker" type="checkbox" value="y" '
  1304. 'name="issue_tracker" checked=""/>',
  1305. output_text,
  1306. )
  1307. self.assertIn(
  1308. '<input id="pull_request_access_only" type="checkbox" '
  1309. 'value="y" name="pull_request_access_only" checked=""/>',
  1310. output_text,
  1311. )
  1312. repo = pagure.lib.query.get_authorized_project(
  1313. self.session, "test"
  1314. )
  1315. self.assertEqual(gen_acl.call_count, 1)
  1316. args = gen_acl.call_args
  1317. self.assertEqual(args[0], tuple())
  1318. self.assertListEqual(list(args[1]), ["project"])
  1319. self.assertEqual(args[1]["project"].fullname, "test")
  1320. @patch("pagure.decorators.admin_session_timedout")
  1321. def test_fields_in_view_settings(self, ast):
  1322. """ Test the default fields in view_settings endpoint. """
  1323. ast.return_value = False
  1324. # No Git repo
  1325. output = self.app.get("/foo/settings")
  1326. self.assertEqual(output.status_code, 404)
  1327. user = tests.FakeUser()
  1328. with tests.user_set(self.app.application, user):
  1329. output = self.app.get("/foo/settings")
  1330. self.assertEqual(output.status_code, 404)
  1331. item = pagure.lib.model.Project(
  1332. user_id=1, # pingou
  1333. name="test",
  1334. description="test project #1",
  1335. hook_token="aaabbbccc",
  1336. )
  1337. self.session.add(item)
  1338. self.session.commit()
  1339. tests.create_projects_git(os.path.join(self.path, "repos"))
  1340. output = self.app.get("/test/settings")
  1341. self.assertEqual(output.status_code, 403)
  1342. # User not logged in
  1343. output = self.app.get("/test/settings")
  1344. self.assertEqual(output.status_code, 302)
  1345. user.username = "pingou"
  1346. with tests.user_set(self.app.application, user):
  1347. ast.return_value = True
  1348. output = self.app.get("/test/settings")
  1349. self.assertEqual(output.status_code, 302)
  1350. ast.return_value = False
  1351. output = self.app.get("/test/settings")
  1352. self.assertEqual(output.status_code, 200)
  1353. output_text = output.get_data(as_text=True)
  1354. self.assertIn(
  1355. "<title>Settings - test - Pagure</title>", output_text
  1356. )
  1357. self.assertIn(
  1358. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  1359. output_text,
  1360. )
  1361. # Check that the priorities have their empty fields
  1362. self.assertIn(
  1363. """<div class="form-group settings-field-rows" id="priorities-list">
  1364. <div class="row hidden blank-field">
  1365. <div class="col-sm-2" >
  1366. <input type="text" name="priority_weigth"
  1367. value="" size="3" class="form-control"/>
  1368. </div>
  1369. <div class="col-sm-9">
  1370. <input type="text" name="priority_title"
  1371. value="" class="form-control"/>
  1372. </div>""",
  1373. output_text,
  1374. )
  1375. # Check that the milestones have their empty fields
  1376. self.assertIn(
  1377. """<div id="milestones">
  1378. <div class="row p-t-1 milestone" id="milestone_1">
  1379. <input type="hidden" name="milestones" value="1">
  1380. <div class="col-sm-4 p-r-0">
  1381. <input type="text" name="milestone_1_name"
  1382. value="" size="3" class="form-control"/>
  1383. </div>
  1384. <div class="col-sm-4 p-r-0">
  1385. <input type="text" name="milestone_1_date"
  1386. value="" class="form-control"/>
  1387. </div>
  1388. <div class="col-sm-2 p-r-0" >
  1389. <span class="fa fa-long-arrow-up milestone_order_up"
  1390. data-stone="1"></span>
  1391. <span class="fa fa-long-arrow-down milestone_order_bottom"
  1392. data-stone="1"></span>
  1393. </div>
  1394. <div class="col-sm-1 p-r-0" >
  1395. <input type="checkbox" name="milestone_1_active" />
  1396. </div>
  1397. </div>""",
  1398. output_text,
  1399. )
  1400. # Check that the close_status have its empty field
  1401. self.assertIn(
  1402. """<div class="form-group settings-field-rows" id="status-list">
  1403. <div class="row hidden blank-field">
  1404. <div class="col-sm-11" >
  1405. <input type="text" name="close_status"
  1406. value="" class="form-control"/>
  1407. </div>""",
  1408. output_text,
  1409. )
  1410. # Check that the custom fields have their empty fields
  1411. self.assertIn(
  1412. """<div class="form-group settings-field-rows" id="customfields-list">
  1413. <div class="row hidden blank-field">
  1414. <div class="col-sm-2 pr-0">
  1415. <input type="text" name="custom_keys"
  1416. value="" class="form-control"/>
  1417. </div>
  1418. <div class="col-sm-2 pr-0">
  1419. <select name="custom_keys_type" class="form-control custom-keys">
  1420. <option value="text">Text</option>
  1421. <option value="boolean">Boolean</option>
  1422. <option value="link">Link</option>
  1423. <option value="list">List</option>
  1424. <option value="date">Date</option>
  1425. </select>
  1426. </div>
  1427. <div class="col-sm-6 pr-0">
  1428. <input title="Comma separated list items" type="text" name="custom_keys_data" value="" class="form-control custom-keys-list hidden" id="custom_keys_list"/>
  1429. </div>
  1430. <div class="col-sm-1 pr-0">
  1431. <input type="checkbox" name="custom_keys_notify" title="Trigger email notification when updated" class="form-control"/>
  1432. </div>""",
  1433. output_text,
  1434. )
  1435. def test_view_forks(self):
  1436. """ Test the view_forks endpoint. """
  1437. output = self.app.get("/foo/forks", follow_redirects=True)
  1438. self.assertEqual(output.status_code, 404)
  1439. tests.create_projects(self.session)
  1440. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1441. output = self.app.get("/test/forks", follow_redirects=True)
  1442. self.assertEqual(output.status_code, 200)
  1443. output_text = output.get_data(as_text=True)
  1444. self.assertIn("This project has not been forked.", output_text)
  1445. @patch.dict("pagure.config.config", {"CASE_SENSITIVE": True})
  1446. def test_view_repo_case_sensitive(self):
  1447. """ Test the view_repo endpoint. """
  1448. tests.create_projects(self.session)
  1449. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1450. output = self.app.get("/test")
  1451. self.assertEqual(output.status_code, 200)
  1452. output_text = output.get_data(as_text=True)
  1453. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1454. output = self.app.get("/TEST")
  1455. self.assertEqual(output.status_code, 404)
  1456. def test_view_repo_more_button_absent_no_auth(self):
  1457. """ Test the view_repo endpoint and check if the "more" button is
  1458. absent when not logged in. """
  1459. tests.create_projects(self.session)
  1460. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1461. output = self.app.get("/test")
  1462. self.assertEqual(output.status_code, 200)
  1463. output_text = output.get_data(as_text=True)
  1464. self.assertNotIn(
  1465. '<span class="pull-xs-right"><a data-toggle="collapse" '
  1466. 'href="#moregiturls"',
  1467. output_text,
  1468. )
  1469. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1470. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1471. self.assertIn(
  1472. '<span class="d-none d-md-inline">Stats</span>', output_text
  1473. )
  1474. self.perfMaxWalks(0, 0)
  1475. self.perfReset()
  1476. def test_view_repo_more_button_present(self):
  1477. """ Test the view_repo endpoint and check if the "more" button is
  1478. present when it should be. """
  1479. tests.create_projects(self.session)
  1480. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1481. pingou = pagure.lib.query.get_user(self.session, "pingou")
  1482. pagure.lib.query.add_sshkey_to_project_or_user(
  1483. session=self.session,
  1484. user=pingou,
  1485. ssh_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==",
  1486. pushaccess=True,
  1487. creator=pingou,
  1488. )
  1489. self.session.commit()
  1490. repo = pagure.lib.query._get_project(self.session, "test")
  1491. pagure.lib.query.update_read_only_mode(
  1492. self.session, repo, read_only=False
  1493. )
  1494. self.session.commit()
  1495. user = tests.FakeUser(username="pingou")
  1496. with tests.user_set(self.app.application, user):
  1497. output = self.app.get("/test")
  1498. self.assertEqual(output.status_code, 200)
  1499. output_text = output.get_data(as_text=True)
  1500. self.assertIn(
  1501. '<input class="form-control bg-white select-on-focus" type="text" '
  1502. 'value="ssh://git@localhost.localdomain/tickets/test.git" readonly>',
  1503. output_text,
  1504. )
  1505. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1506. self.assertIn(
  1507. "<title>Overview - test - Pagure</title>", output_text
  1508. )
  1509. self.assertIn(
  1510. '<span class="d-none d-md-inline">Stats</span>', output_text
  1511. )
  1512. self.perfMaxWalks(0, 0)
  1513. self.perfReset()
  1514. def test_view_repo_more_button_absent_no_access(self):
  1515. """ Test the view_repo endpoint and check if the "more" button is
  1516. absent if the user doesn't have access to the project. """
  1517. tests.create_projects(self.session)
  1518. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1519. user = tests.FakeUser(username="foo")
  1520. with tests.user_set(self.app.application, user):
  1521. output = self.app.get("/test")
  1522. self.assertEqual(output.status_code, 200)
  1523. output_text = output.get_data(as_text=True)
  1524. self.assertNotIn(
  1525. '<input class="form-control bg-white select-on-focus" type="text" '
  1526. 'value="ssh://git@localhost.localdomain/tickets/test.git" readonly>',
  1527. output_text,
  1528. )
  1529. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1530. self.assertIn(
  1531. "<title>Overview - test - Pagure</title>", output_text
  1532. )
  1533. self.assertIn(
  1534. '<span class="d-none d-md-inline">Stats</span>', output_text
  1535. )
  1536. self.perfMaxWalks(0, 0)
  1537. self.perfReset()
  1538. def test_view_repo_ssh_key_not_uploaded_no_ssh_url(self):
  1539. """ Test viewing repo when user hasn't uploaded SSH key yet
  1540. and thus should see a message instead of url for SSH cloning. """
  1541. tests.create_projects(self.session)
  1542. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1543. user = tests.FakeUser(username="pingou")
  1544. with tests.user_set(self.app.application, user):
  1545. output = self.app.get("/test")
  1546. self.assertEqual(output.status_code, 200)
  1547. output_text = output.get_data(as_text=True)
  1548. self.assertIn(
  1549. "You need to upload SSH key to be able to clone over SSH",
  1550. output_text,
  1551. )
  1552. def test_view_repo_read_only_no_ssh_url(self):
  1553. """ Test viewing repo that is still readonly and thus user
  1554. should see a message instead of url for SSH cloning. """
  1555. tests.create_projects(self.session)
  1556. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1557. repo = pagure.lib.query._get_project(self.session, "test")
  1558. pagure.lib.query.update_read_only_mode(
  1559. self.session, repo, read_only=True
  1560. )
  1561. pingou = pagure.lib.query.get_user(self.session, "pingou")
  1562. pagure.lib.query.add_sshkey_to_project_or_user(
  1563. session=self.session,
  1564. user=pingou,
  1565. ssh_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==",
  1566. pushaccess=True,
  1567. creator=pingou,
  1568. )
  1569. self.session.commit()
  1570. user = tests.FakeUser(username="pingou")
  1571. with tests.user_set(self.app.application, user):
  1572. output = self.app.get("/test")
  1573. self.assertEqual(output.status_code, 200)
  1574. output_text = output.get_data(as_text=True)
  1575. self.assertIn("Cloning over SSH is disabled.", output_text)
  1576. def test_view_repo(self):
  1577. """ Test the view_repo endpoint. """
  1578. output = self.app.get("/foo")
  1579. # No project registered in the DB
  1580. self.assertEqual(output.status_code, 404)
  1581. tests.create_projects(self.session)
  1582. output = self.app.get("/test")
  1583. # No git repo associated
  1584. self.assertEqual(output.status_code, 404)
  1585. self.perfMaxWalks(0, 0)
  1586. self.perfReset()
  1587. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1588. output = self.app.get("/test")
  1589. self.assertEqual(output.status_code, 200)
  1590. output_text = output.get_data(as_text=True)
  1591. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1592. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1593. self.assertIn(
  1594. '<a class="nav-link" href="/test/stats">\n '
  1595. '<i class="fa fa-line-chart fa-fw text-muted"></i>\n '
  1596. '<span class="d-none d-md-inline">Stats</span>\n </a>',
  1597. output_text,
  1598. )
  1599. self.perfMaxWalks(0, 0)
  1600. self.perfReset()
  1601. output = self.app.get("/test/")
  1602. self.assertEqual(output.status_code, 200)
  1603. output_text = output.get_data(as_text=True)
  1604. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1605. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1606. self.perfMaxWalks(0, 0)
  1607. self.perfReset()
  1608. # Add some content to the git repo
  1609. tests.add_content_git_repo(
  1610. os.path.join(self.path, "repos", "test.git")
  1611. )
  1612. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1613. tests.add_readme_git_repo(
  1614. os.path.join(self.path, "repos", "test.git"), "README.txt"
  1615. )
  1616. tests.add_readme_git_repo(
  1617. os.path.join(self.path, "repos", "test.git"), "README.dummy"
  1618. )
  1619. self.perfReset()
  1620. # Authenticated, the Fork button appears
  1621. user = tests.FakeUser(username="pingou")
  1622. with tests.user_set(self.app.application, user):
  1623. output = self.app.get("/test")
  1624. self.assertEqual(output.status_code, 200)
  1625. output_text = output.get_data(as_text=True)
  1626. self.assertIn(
  1627. '<i class="fa fa-code-fork fa-fw"></i> Fork</button>',
  1628. output_text,
  1629. )
  1630. self.assertFalse("<p>This repo is brand new!</p>" in output_text)
  1631. self.assertNotIn("Forked from", output_text)
  1632. self.assertNotIn("README.txt", output_text)
  1633. self.assertNotIn("README.dummy", output_text)
  1634. self.assertIn(
  1635. "<title>Overview - test - Pagure</title>", output_text
  1636. )
  1637. self.perfMaxWalks(3, 8) # Target: (1, 3)
  1638. self.perfReset()
  1639. # Non-authenticated, the Fork button does not appear
  1640. output = self.app.get("/test")
  1641. self.assertEqual(output.status_code, 200)
  1642. output_text = output.get_data(as_text=True)
  1643. self.assertNotIn(
  1644. '<i class="fa fa-code-fork"></i>Fork</button>', output_text
  1645. )
  1646. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1647. self.assertNotIn("Forked from", output_text)
  1648. self.assertNotIn("README.txt", output_text)
  1649. self.assertNotIn("README.dummy", output_text)
  1650. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1651. self.perfMaxWalks(3, 8) # Target: (1, 3)
  1652. self.perfReset()
  1653. # Turn that repo into a fork
  1654. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1655. repo.parent_id = 2
  1656. repo.is_fork = True
  1657. self.session.add(repo)
  1658. self.session.commit()
  1659. # View the repo in the UI
  1660. output = self.app.get("/test")
  1661. self.assertEqual(output.status_code, 404)
  1662. # Add some content to the git repo
  1663. tests.add_content_git_repo(
  1664. os.path.join(self.path, "repos", "forks", "pingou", "test.git")
  1665. )
  1666. tests.add_readme_git_repo(
  1667. os.path.join(self.path, "repos", "forks", "pingou", "test.git")
  1668. )
  1669. # Authenticated and already have a fork, the View Fork button appears
  1670. user = tests.FakeUser(username="pingou")
  1671. with tests.user_set(self.app.application, user):
  1672. output = self.app.get("/fork/pingou/test")
  1673. self.assertEqual(output.status_code, 200)
  1674. output_text = output.get_data(as_text=True)
  1675. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1676. self.assertIn(
  1677. "<title>Overview - test - Pagure</title>", output_text
  1678. )
  1679. self.assertIn("Forked from", output_text)
  1680. self.assertNotIn(
  1681. '<i class="fa fa-code-fork fa-fw"></i> Fork</button>',
  1682. output_text,
  1683. )
  1684. self.assertIn(
  1685. '<i class="fa fa-code-fork fa-fw"></i> View Upstream',
  1686. output_text,
  1687. )
  1688. self.perfMaxWalks(1, 3)
  1689. self.perfReset()
  1690. # Authenticated, the Fork button appears
  1691. user = tests.FakeUser(username="foo")
  1692. with tests.user_set(self.app.application, user):
  1693. output = self.app.get("/fork/pingou/test")
  1694. self.assertEqual(output.status_code, 200)
  1695. output_text = output.get_data(as_text=True)
  1696. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1697. self.assertIn(
  1698. "<title>Overview - test - Pagure</title>", output_text
  1699. )
  1700. self.assertIn("Forked from", output_text)
  1701. self.assertNotIn(
  1702. '<i class="fa fa-code-fork fa-fw"></i> View Upstream',
  1703. output_text,
  1704. )
  1705. self.assertIn(
  1706. '<i class="fa fa-code-fork fa-fw"></i> Fork</button>',
  1707. output_text,
  1708. )
  1709. self.perfMaxWalks(1, 3)
  1710. self.perfReset()
  1711. # Non-authenticated, the Fork button does not appear
  1712. output = self.app.get("/fork/pingou/test")
  1713. self.assertEqual(output.status_code, 200)
  1714. output_text = output.get_data(as_text=True)
  1715. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1716. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1717. self.assertIn("Forked from", output_text)
  1718. self.assertNotIn(
  1719. '<i class="fa fa-code-fork"></i> View Fork', output_text
  1720. )
  1721. self.assertNotIn(
  1722. '<i class="fa fa-code-fork"></i>Fork</button>', output_text
  1723. )
  1724. self.perfMaxWalks(1, 3)
  1725. self.perfReset()
  1726. # Add a fork of a fork
  1727. item = pagure.lib.model.Project(
  1728. user_id=1, # pingou
  1729. name="test3",
  1730. description="test project #3",
  1731. is_fork=True,
  1732. parent_id=1,
  1733. hook_token="aaabbbmmm",
  1734. )
  1735. self.session.add(item)
  1736. self.session.commit()
  1737. tests.add_content_git_repo(
  1738. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  1739. )
  1740. tests.add_readme_git_repo(
  1741. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  1742. )
  1743. tests.add_commit_git_repo(
  1744. os.path.join(self.path, "repos", "forks", "pingou", "test3.git"),
  1745. ncommits=10,
  1746. )
  1747. output = self.app.get("/fork/pingou/test3")
  1748. self.assertEqual(output.status_code, 200)
  1749. output_text = output.get_data(as_text=True)
  1750. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1751. self.assertIn("<title>Overview - test3 - Pagure</title>", output_text)
  1752. self.assertIn("Forked from", output_text)
  1753. self.perfMaxWalks(3, 18) # Ideal: (1, 3)
  1754. self.perfReset()
  1755. def test_view_repo_empty(self):
  1756. """ Test the view_repo endpoint on a repo w/o master branch. """
  1757. tests.create_projects(self.session)
  1758. # Create a git repo to play with
  1759. gitrepo = os.path.join(self.path, "repos", "test.git")
  1760. pygit2.init_repository(gitrepo, bare=True)
  1761. # Create a fork of this repo
  1762. newpath = tempfile.mkdtemp(prefix="pagure-viewrepo-test")
  1763. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1764. # Edit the sources file again
  1765. with open(os.path.join(newpath, "sources"), "w") as stream:
  1766. stream.write("foo\n bar\nbaz\n boose")
  1767. new_repo.index.add("sources")
  1768. new_repo.index.write()
  1769. # Commits the files added
  1770. tree = new_repo.index.write_tree()
  1771. author = pygit2.Signature("Alice Author", "alice@authors.tld")
  1772. committer = pygit2.Signature("Cecil Committer", "cecil@committers.tld")
  1773. new_repo.create_commit(
  1774. "refs/heads/feature",
  1775. author,
  1776. committer,
  1777. "A commit on branch feature",
  1778. tree,
  1779. [],
  1780. )
  1781. refname = "refs/heads/feature"
  1782. ori_remote = new_repo.remotes[0]
  1783. PagureRepo.push(ori_remote, refname)
  1784. output = self.app.get("/test")
  1785. self.assertEqual(output.status_code, 200)
  1786. output_text = output.get_data(as_text=True)
  1787. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1788. self.assertNotIn("Forked from", output_text)
  1789. self.assertIn("<title>Overview - test - Pagure</title>", output_text)
  1790. self.assertEqual(output_text.count('<span class="commitid">'), 0)
  1791. shutil.rmtree(newpath)
  1792. '''
  1793. def test_view_repo_branch(self):
  1794. """ Test the view_repo_branch endpoint. """
  1795. output = self.app.get('/foo/branch/master')
  1796. # No project registered in the DB
  1797. self.assertEqual(output.status_code, 404)
  1798. tests.create_projects(self.session)
  1799. output = self.app.get('/test/branch/master')
  1800. # No git repo associated
  1801. self.assertEqual(output.status_code, 404)
  1802. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  1803. output = self.app.get('/test/branch/master')
  1804. self.assertEqual(output.status_code, 404)
  1805. # Add some content to the git repo
  1806. tests.add_content_git_repo(os.path.join(self.path, 'repos',
  1807. 'test.git'))
  1808. tests.add_readme_git_repo(os.path.join(self.path, 'repos', 'test.git'))
  1809. # Turn that repo into a fork
  1810. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  1811. repo.parent_id = 2
  1812. repo.is_fork = True
  1813. self.session.add(repo)
  1814. self.session.commit()
  1815. # Add some content to the git repo
  1816. tests.add_content_git_repo(
  1817. os.path.join(self.path, 'repos', 'forks', 'pingou', 'test.git'))
  1818. tests.add_readme_git_repo(
  1819. os.path.join(self.path, 'repos', 'forks', 'pingou', 'test.git'))
  1820. output = self.app.get('/fork/pingou/test/')
  1821. self.assertEqual(output.status_code, 200)
  1822. output_text = output.get_data(as_text=True)
  1823. self.assertNotIn('<p>This repo is brand new!</p>', output_text)
  1824. self.assertIn('Forked from', output_text)
  1825. # Add a fork of a fork
  1826. item = pagure.lib.model.Project(
  1827. user_id=1, # pingou
  1828. name='test3',
  1829. description='test project #3',
  1830. is_fork=True,
  1831. parent_id=1,
  1832. hook_token='aaabbbnnn',
  1833. )
  1834. self.session.add(item)
  1835. self.session.commit()
  1836. tests.add_content_git_repo(
  1837. os.path.join(self.path, 'repos', 'forks', 'pingou', 'test3.git'))
  1838. tests.add_readme_git_repo(
  1839. os.path.join(self.path, 'repos', 'forks', 'pingou', 'test3.git'))
  1840. tests.add_commit_git_repo(
  1841. os.path.join(self.path, 'repos', 'forks', 'pingou', 'test3.git'),
  1842. ncommits=10)
  1843. output = self.app.get('/fork/pingou/test3/')
  1844. self.assertEqual(output.status_code, 200)
  1845. output_text = output.get_data(as_text=True)
  1846. self.assertNotIn('<p>This repo is brand new!</p>', output_text)
  1847. self.assertIn('Forked from', output_text)
  1848. '''
  1849. def test_view_commits(self):
  1850. """ Test the view_commits endpoint. """
  1851. output = self.app.get("/foo/commits")
  1852. # No project registered in the DB
  1853. self.assertEqual(output.status_code, 404)
  1854. tests.create_projects(self.session)
  1855. output = self.app.get("/test/commits")
  1856. # No git repo associated
  1857. self.assertEqual(output.status_code, 404)
  1858. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1859. output = self.app.get("/test/commits")
  1860. self.assertEqual(output.status_code, 200)
  1861. output_text = output.get_data(as_text=True)
  1862. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1863. self.assertIn("<title>Commits - test - Pagure</title>", output_text)
  1864. # Add some content to the git repo
  1865. tests.add_content_git_repo(
  1866. os.path.join(self.path, "repos", "test.git")
  1867. )
  1868. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1869. output = self.app.get("/test/commits")
  1870. self.assertEqual(output.status_code, 200)
  1871. output_text = output.get_data(as_text=True)
  1872. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1873. self.assertNotIn("Forked from", output_text)
  1874. self.assertIn("<title>Commits - test - Pagure</title>", output_text)
  1875. output = self.app.get("/test/commits/master")
  1876. self.assertEqual(output.status_code, 200)
  1877. output_text = output.get_data(as_text=True)
  1878. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1879. self.assertNotIn("Forked from", output_text)
  1880. self.assertIn("<title>Commits - test - Pagure</title>", output_text)
  1881. # Turn that repo into a fork
  1882. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1883. repo.parent_id = 2
  1884. repo.is_fork = True
  1885. self.session.add(repo)
  1886. self.session.commit()
  1887. # View the repo in the UI
  1888. output = self.app.get("/test/commits")
  1889. self.assertEqual(output.status_code, 404)
  1890. # Add some content to the git repo
  1891. tests.add_content_git_repo(
  1892. os.path.join(self.path, "repos", "forks", "pingou", "test.git")
  1893. )
  1894. tests.add_readme_git_repo(
  1895. os.path.join(self.path, "repos", "forks", "pingou", "test.git")
  1896. )
  1897. output = self.app.get("/fork/pingou/test/commits?page=abc")
  1898. self.assertEqual(output.status_code, 200)
  1899. output_text = output.get_data(as_text=True)
  1900. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1901. self.assertIn("<title>Commits - test - Pagure</title>", output_text)
  1902. self.assertIn("Forked from", output_text)
  1903. # Add a fork of a fork
  1904. item = pagure.lib.model.Project(
  1905. user_id=1, # pingou
  1906. name="test3",
  1907. description="test project #3",
  1908. is_fork=True,
  1909. parent_id=1,
  1910. hook_token="aaabbbooo",
  1911. )
  1912. self.session.add(item)
  1913. self.session.commit()
  1914. tests.add_content_git_repo(
  1915. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  1916. )
  1917. tests.add_readme_git_repo(
  1918. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  1919. )
  1920. tests.add_commit_git_repo(
  1921. os.path.join(self.path, "repos", "forks", "pingou", "test3.git"),
  1922. ncommits=10,
  1923. )
  1924. # list is empty
  1925. output = self.app.get("/fork/pingou/test3/commits/fobranch")
  1926. self.assertEqual(output.status_code, 200)
  1927. output_text = output.get_data(as_text=True)
  1928. self.assertIn(
  1929. '<div class="list-group my-2">\n\n\n </div>', output_text
  1930. )
  1931. self.assertIn(
  1932. 'Commits <span class="badge badge-secondary"> 0</span>',
  1933. output_text,
  1934. )
  1935. output = self.app.get("/fork/pingou/test3/commits")
  1936. self.assertEqual(output.status_code, 200)
  1937. output_text = output.get_data(as_text=True)
  1938. self.assertNotIn("<p>This repo is brand new!</p>", output_text)
  1939. self.assertIn("<title>Commits - test3 - Pagure</title>", output_text)
  1940. self.assertIn("Forked from", output_text)
  1941. def test_view_commits_from_tag(self):
  1942. """ Test the view_commits endpoint given a tag. """
  1943. tests.create_projects(self.session)
  1944. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1945. # Add a README to the git repo - First commit
  1946. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1947. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  1948. first_commit = repo.revparse_single("HEAD")
  1949. tagger = pygit2.Signature("Alice Doe", "adoe@example.com", 12347, 0)
  1950. repo.create_tag(
  1951. "0.0.1",
  1952. first_commit.oid.hex,
  1953. pygit2.GIT_OBJ_COMMIT,
  1954. tagger,
  1955. "Release 0.0.1",
  1956. )
  1957. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1958. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  1959. latest_commit = repo.revparse_single("HEAD")
  1960. output = self.app.get("/test/commits/0.0.1")
  1961. self.assertEqual(output.status_code, 200)
  1962. output_text = output.get_data(as_text=True)
  1963. self.assertIn(first_commit.oid.hex, output_text)
  1964. self.assertNotIn(latest_commit.oid.hex, output_text)
  1965. self.assertIn("<title>Commits - test - Pagure</title>", output_text)
  1966. self.assertEqual(output_text.count('<span id="commit-actions">'), 1)
  1967. def test_view_commits_from_blob(self):
  1968. """ Test the view_commits endpoint given a blob. """
  1969. tests.create_projects(self.session)
  1970. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1971. tests.add_content_to_git(os.path.join(self.path, "repos", "test.git"))
  1972. # Retrieve the blob of the `sources` file in head
  1973. repo_obj = pygit2.Repository(
  1974. os.path.join(self.path, "repos", "test.git")
  1975. )
  1976. commit = repo_obj[repo_obj.head.target]
  1977. content = get_file_in_tree(
  1978. repo_obj, commit.tree, ["sources"], bail_on_tree=True
  1979. )
  1980. output = self.app.get("/test/commits/%s" % content.oid.hex)
  1981. self.assertEqual(output.status_code, 404)
  1982. output_text = output.get_data(as_text=True)
  1983. self.assertIn("Invalid branch/identifier provided", output_text)
  1984. def test_view_commit_from_tag(self):
  1985. """ Test the view_commit endpoint given a tag. """
  1986. tests.create_projects(self.session)
  1987. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1988. # Add a README to the git repo - First commit
  1989. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1990. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  1991. first_commit = repo.revparse_single("HEAD")
  1992. tagger = pygit2.Signature("Alice Doe", "adoe@example.com", 12347, 0)
  1993. repo.create_tag(
  1994. "0.0.1",
  1995. first_commit.oid.hex,
  1996. pygit2.GIT_OBJ_COMMIT,
  1997. tagger,
  1998. "Release 0.0.1",
  1999. )
  2000. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2001. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2002. project = pagure.lib.query.get_authorized_project(self.session, "test")
  2003. tags = pagure.lib.git.get_git_tags_objects(project)
  2004. tag_id = tags[0]["object"].oid
  2005. commit_id = tags[0]["object"].peel(pygit2.Commit).hex
  2006. output = self.app.get("/test/c/%s" % tag_id)
  2007. self.assertEqual(output.status_code, 302)
  2008. output = self.app.get("/test/c/%s" % tag_id, follow_redirects=True)
  2009. self.assertEqual(output.status_code, 200)
  2010. output_text = output.get_data(as_text=True)
  2011. self.assertIn(first_commit.oid.hex, output_text)
  2012. self.assertIn(
  2013. "<title>Commit - test - %s - Pagure</title>" % commit_id,
  2014. output_text,
  2015. )
  2016. def test_compare_commits(self):
  2017. """ Test the compare_commits endpoint. """
  2018. # First two commits comparison
  2019. def compare_first_two(c1, c2):
  2020. # View commits comparison
  2021. output = self.app.get("/test/c/%s..%s" % (c2.oid.hex, c1.oid.hex))
  2022. self.assertEqual(output.status_code, 200)
  2023. output_text = output.get_data(as_text=True)
  2024. self.assertIn(
  2025. "<title>Diff from %s to %s - test\n - Pagure</title>"
  2026. % (c2.oid.hex, c1.oid.hex),
  2027. output_text,
  2028. )
  2029. self.assertIn(
  2030. ' <span class="badge-light border border-secondary badge">%s</span>\n ..\n <span class="badge-light border border-secondary badge">%s</span>\n'
  2031. % (c2.oid.hex, c1.oid.hex),
  2032. output_text,
  2033. )
  2034. self.assertNotIn('id="show_hidden_commits"', output_text)
  2035. self.assertIn(
  2036. '<pre class="alert-danger"><code>- Row 0</code></pre>',
  2037. output_text,
  2038. )
  2039. # View inverse commits comparison
  2040. output = self.app.get("/test/c/%s..%s" % (c1.oid.hex, c2.oid.hex))
  2041. self.assertEqual(output.status_code, 200)
  2042. output_text = output.get_data(as_text=True)
  2043. self.assertIn(
  2044. "<title>Diff from %s to %s - test\n - Pagure</title>"
  2045. % (c1.oid.hex, c2.oid.hex),
  2046. output_text,
  2047. )
  2048. self.assertNotIn('id="show_hidden_commits"', output_text)
  2049. self.assertIn(
  2050. ' <span class="badge-light border border-secondary badge">%s</span>\n ..\n <span class="badge-light border border-secondary badge">%s</span>\n'
  2051. % (c1.oid.hex, c2.oid.hex),
  2052. output_text,
  2053. )
  2054. self.assertIn(
  2055. '<pre class="alert-success"><code>+ Row 0</code></pre>',
  2056. output_text,
  2057. )
  2058. def compare_all(c1, c3):
  2059. # View commits comparison
  2060. output = self.app.get("/test/c/%s..%s" % (c1.oid.hex, c3.oid.hex))
  2061. self.assertEqual(output.status_code, 200)
  2062. output_text = output.get_data(as_text=True)
  2063. self.assertIn(
  2064. "<title>Diff from %s to %s - test\n - Pagure</title>"
  2065. % (c1.oid.hex, c3.oid.hex),
  2066. output_text,
  2067. )
  2068. self.assertIn(
  2069. ' <span class="badge-light border border-secondary badge">%s</span>\n ..\n <span class="badge-light border border-secondary badge">%s</span>\n'
  2070. % (c1.oid.hex, c3.oid.hex),
  2071. output_text,
  2072. )
  2073. self.assertIn(
  2074. '<pre class="alert-success"><code>+ Row 0</code></pre>',
  2075. output_text,
  2076. )
  2077. self.assertEqual(
  2078. output_text.count(
  2079. '<pre class="alert-success"><code>+ Row 0</code></pre>'
  2080. ),
  2081. 2,
  2082. )
  2083. self.assertIn('<a class="pointer">1 more commits...', output_text)
  2084. self.assertIn(
  2085. 'title="View file as of 4829cf">Šource</a>', output_text
  2086. )
  2087. self.assertIn(
  2088. '<div class="btn btn-outline-success disabled opacity-100 border-0 font-weight-bold">\n'
  2089. " file added\n",
  2090. output_text,
  2091. )
  2092. # View inverse commits comparison
  2093. output = self.app.get("/test/c/%s..%s" % (c3.oid.hex, c1.oid.hex))
  2094. self.assertEqual(output.status_code, 200)
  2095. output_text = output.get_data(as_text=True)
  2096. self.assertIn(
  2097. "<title>Diff from %s to %s - test\n - Pagure</title>"
  2098. % (c3.oid.hex, c1.oid.hex),
  2099. output_text,
  2100. )
  2101. self.assertIn(
  2102. ' <span class="badge-light border border-secondary badge">%s</span>\n ..\n <span class="badge-light border border-secondary badge">%s</span>\n'
  2103. % (c3.oid.hex, c1.oid.hex),
  2104. output_text,
  2105. )
  2106. self.assertIn(
  2107. '<pre class="text-muted"><code>@@ -1,2 +1,1 @@</code></pre>',
  2108. output_text,
  2109. )
  2110. self.assertIn(
  2111. '<pre class="alert-danger"><code>- Row 0</code></pre>',
  2112. output_text,
  2113. )
  2114. self.assertIn('<a class="pointer">1 more commits...', output_text)
  2115. self.assertIn(
  2116. 'title="View file as of 000000">Šource</a>', output_text
  2117. )
  2118. self.assertIn(
  2119. '<div class="btn btn-outline-danger disabled opacity-100 border-0 font-weight-bold">\n'
  2120. " file removed\n",
  2121. output_text,
  2122. )
  2123. def compare_with_symlink(c3, c4):
  2124. # View comparison of commits with symlink
  2125. # we only test that the patch itself renders correctly,
  2126. # the rest of the logic is already tested in the other functions
  2127. output = self.app.get("/test/c/%s..%s" % (c3.oid.hex, c4.oid.hex))
  2128. self.assertEqual(output.status_code, 200)
  2129. output_text = output.get_data(as_text=True)
  2130. print(output_text)
  2131. self.assertIn(
  2132. "<title>Diff from %s to %s - test\n - Pagure</title>"
  2133. % (c3.oid.hex, c4.oid.hex),
  2134. output_text,
  2135. )
  2136. self.assertIn(
  2137. '<pre class="alert-success"><code>+ Source </code></pre>',
  2138. output_text,
  2139. )
  2140. output = self.app.get("/foo/bar")
  2141. # No project registered in the DB
  2142. self.assertEqual(output.status_code, 404)
  2143. tests.create_projects(self.session)
  2144. output = self.app.get("/test/bar")
  2145. # No git repo associated
  2146. self.assertEqual(output.status_code, 404)
  2147. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2148. output = self.app.get("/test/bar")
  2149. self.assertEqual(output.status_code, 404)
  2150. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2151. # Add one commit to git repo
  2152. tests.add_commit_git_repo(
  2153. os.path.join(self.path, "repos", "test.git"), ncommits=1
  2154. )
  2155. c1 = repo.revparse_single("HEAD")
  2156. # Add another commit to git repo
  2157. tests.add_commit_git_repo(
  2158. os.path.join(self.path, "repos", "test.git"), ncommits=1
  2159. )
  2160. c2 = repo.revparse_single("HEAD")
  2161. # Add one more commit to git repo
  2162. tests.add_commit_git_repo(
  2163. os.path.join(self.path, "repos", "test.git"),
  2164. ncommits=1,
  2165. filename="Šource",
  2166. )
  2167. c3 = repo.revparse_single("HEAD")
  2168. tests.add_commit_git_repo(
  2169. os.path.join(self.path, "repos", "test.git"),
  2170. ncommits=1,
  2171. filename="Source-sl",
  2172. symlink_to="Source",
  2173. )
  2174. c4 = repo.revparse_single("HEAD")
  2175. compare_first_two(c1, c2)
  2176. compare_all(c1, c3)
  2177. compare_with_symlink(c3, c4)
  2178. user = tests.FakeUser()
  2179. # Set user logged in
  2180. with tests.user_set(self.app.application, user):
  2181. compare_first_two(c1, c2)
  2182. compare_all(c1, c3)
  2183. compare_with_symlink(c3, c4)
  2184. def test_view_file(self):
  2185. """ Test the view_file endpoint. """
  2186. output = self.app.get("/foo/blob/foo/f/sources")
  2187. # No project registered in the DB
  2188. self.assertEqual(output.status_code, 404)
  2189. tests.create_projects(self.session)
  2190. output = self.app.get("/test/blob/foo/f/sources")
  2191. # No git repo associated
  2192. self.assertEqual(output.status_code, 404)
  2193. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2194. output = self.app.get("/test/blob/foo/f/sources")
  2195. self.assertEqual(output.status_code, 404)
  2196. # Add some content to the git repo
  2197. tests.add_content_git_repo(
  2198. os.path.join(self.path, "repos", "test.git")
  2199. )
  2200. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2201. tests.add_binary_git_repo(
  2202. os.path.join(self.path, "repos", "test.git"), "test.jpg"
  2203. )
  2204. tests.add_binary_git_repo(
  2205. os.path.join(self.path, "repos", "test.git"), "test_binary"
  2206. )
  2207. output = self.app.get("/test/blob/master/foofile")
  2208. self.assertEqual(output.status_code, 404)
  2209. # View in a branch
  2210. output = self.app.get("/test/blob/master/f/sources")
  2211. self.assertEqual(output.status_code, 200)
  2212. output_text = output.get_data(as_text=True)
  2213. self.assertIn(
  2214. '<pre class="syntaxhighlightblock">'
  2215. '<code class="lang-plaintext">foo\n bar</code></pre>',
  2216. output_text,
  2217. )
  2218. # Empty files should also be displayed
  2219. tests.add_content_to_git(
  2220. os.path.join(self.path, "repos", "test.git"),
  2221. filename="emptyfile.md",
  2222. content="",
  2223. )
  2224. output = self.app.get("/test/blob/master/f/emptyfile.md")
  2225. self.assertEqual(output.status_code, 200)
  2226. output_text = output.get_data(as_text=True)
  2227. self.assertIn(
  2228. '<a class="btn btn-secondary btn-sm" '
  2229. 'href="/test/raw/master/f/emptyfile.md" '
  2230. 'title="View as raw">Raw</a>',
  2231. output_text,
  2232. )
  2233. self.assertIn(
  2234. '<div class="m-2">\n' " \n </div>", output_text
  2235. )
  2236. # View what's supposed to be an image
  2237. output = self.app.get("/test/blob/master/f/test.jpg")
  2238. self.assertEqual(output.status_code, 200)
  2239. output_text = output.get_data(as_text=True)
  2240. self.assertIn("Binary files cannot be rendered.<br/>", output_text)
  2241. self.assertIn(
  2242. '<a href="/test/raw/master/f/test.jpg">view the raw version',
  2243. output_text,
  2244. )
  2245. # View by commit id
  2246. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2247. commit = repo.revparse_single("HEAD")
  2248. output = self.app.get("/test/blob/%s/f/test.jpg" % commit.oid.hex)
  2249. self.assertEqual(output.status_code, 200)
  2250. output_text = output.get_data(as_text=True)
  2251. self.assertIn("Binary files cannot be rendered.<br/>", output_text)
  2252. self.assertIn('/f/test.jpg">view the raw version', output_text)
  2253. # View by image name -- somehow we support this
  2254. output = self.app.get("/test/blob/sources/f/test.jpg")
  2255. self.assertEqual(output.status_code, 200)
  2256. output_text = output.get_data(as_text=True)
  2257. self.assertIn("Binary files cannot be rendered.<br/>", output_text)
  2258. self.assertIn('/f/test.jpg">view the raw version', output_text)
  2259. # View binary file
  2260. output = self.app.get("/test/blob/sources/f/test_binary")
  2261. self.assertEqual(output.status_code, 200)
  2262. output_text = output.get_data(as_text=True)
  2263. self.assertIn('/f/test_binary">view the raw version', output_text)
  2264. self.assertIn("Binary files cannot be rendered.<br/>", output_text)
  2265. # View folder
  2266. output = self.app.get("/test/blob/master/f/folder1")
  2267. self.assertEqual(output.status_code, 200)
  2268. output_text = output.get_data(as_text=True)
  2269. self.assertIn(
  2270. '<li class="active breadcrumb-item">\n '
  2271. '<span class="fa fa-folder" data-glyph="">\n '
  2272. "</span>&nbsp; folder1\n </li>",
  2273. output_text,
  2274. )
  2275. self.assertIn("<title>Tree - test - Pagure</title>", output_text)
  2276. self.assertIn(
  2277. '<a href="/test/blob/master/f/folder1/folder2">', output_text
  2278. )
  2279. # Verify the nav links correctly when viewing a nested folder/file.
  2280. output = self.app.get("/test/blob/master/f/folder1/folder2/file")
  2281. self.assertEqual(output.status_code, 200)
  2282. output_text = output.get_data(as_text=True)
  2283. self.assertIn(
  2284. '<li class="breadcrumb-item"><a href="/test/blob/master/f/folder1/folder2">'
  2285. '\n <span class="fa fa-folder"></span>&nbsp; folder2</a>\n'
  2286. " </li>",
  2287. output_text,
  2288. )
  2289. # View by image name -- with a non-existant file
  2290. output = self.app.get("/test/blob/sources/f/testfoo.jpg")
  2291. self.assertEqual(output.status_code, 404)
  2292. output = self.app.get("/test/blob/master/f/folder1/testfoo.jpg")
  2293. self.assertEqual(output.status_code, 404)
  2294. # View file with a non-ascii name
  2295. tests.add_commit_git_repo(
  2296. os.path.join(self.path, "repos", "test.git"),
  2297. ncommits=1,
  2298. filename="Šource",
  2299. )
  2300. output = self.app.get("/test/blob/master/f/Šource")
  2301. self.assertEqual(output.status_code, 200)
  2302. output_text = output.get_data(as_text=True)
  2303. self.assertEqual(
  2304. output.headers["Content-Type"].lower(), "text/html; charset=utf-8"
  2305. )
  2306. self.assertIn("</span>&nbsp; Šource", output_text)
  2307. self.assertIn(
  2308. '<pre class="syntaxhighlightblock">'
  2309. '<code class="lang-plaintext">Row 0\n</code></pre>',
  2310. output_text,
  2311. )
  2312. # Add a fork of a fork
  2313. item = pagure.lib.model.Project(
  2314. user_id=1, # pingou
  2315. name="test3",
  2316. description="test project #3",
  2317. is_fork=True,
  2318. parent_id=1,
  2319. hook_token="aaabbbppp",
  2320. )
  2321. self.session.add(item)
  2322. self.session.commit()
  2323. tests.add_content_git_repo(
  2324. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  2325. )
  2326. tests.add_readme_git_repo(
  2327. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  2328. )
  2329. tests.add_commit_git_repo(
  2330. os.path.join(self.path, "repos", "forks", "pingou", "test3.git"),
  2331. ncommits=10,
  2332. )
  2333. # Verify the nav links correctly when viewing a file/folder in a fork.
  2334. output = self.app.get(
  2335. "/fork/pingou/test3/blob/master/f/folder1/folder2/file"
  2336. )
  2337. self.assertEqual(output.status_code, 200)
  2338. output_text = output.get_data(as_text=True)
  2339. self.assertIn(
  2340. '<li class="breadcrumb-item">'
  2341. '<a href="/fork/pingou/test3/blob/master/f/folder1/folder2">'
  2342. '\n <span class="fa fa-folder"></span>'
  2343. "&nbsp; folder2</a>\n </li>",
  2344. output_text,
  2345. )
  2346. output = self.app.get("/fork/pingou/test3/blob/master/f/sources")
  2347. self.assertEqual(output.status_code, 200)
  2348. output_text = output.get_data(as_text=True)
  2349. self.assertIn(
  2350. '<pre class="syntaxhighlightblock">'
  2351. '<code class="lang-plaintext">foo\n barRow 0\n'
  2352. "Row 1\nRow 2\nRow 3\nRow 4\nRow 5\nRow 6\nRow 7\nRow 8\n"
  2353. "Row 9\n</code></pre>",
  2354. output_text,
  2355. )
  2356. @patch(
  2357. "pagure.lib.encoding_utils.decode",
  2358. MagicMock(side_effect=pagure.exceptions.PagureException),
  2359. )
  2360. def test_view_file_with_wrong_encoding(self):
  2361. """ Test the view_file endpoint. """
  2362. tests.create_projects(self.session)
  2363. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2364. # Add some content to the git repo
  2365. tests.add_content_git_repo(
  2366. os.path.join(self.path, "repos", "test.git")
  2367. )
  2368. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2369. tests.add_binary_git_repo(
  2370. os.path.join(self.path, "repos", "test.git"), "test.jpg"
  2371. )
  2372. tests.add_binary_git_repo(
  2373. os.path.join(self.path, "repos", "test.git"), "test_binary"
  2374. )
  2375. # View file
  2376. output = self.app.get("/test/blob/master/f/sources")
  2377. self.assertEqual(output.status_code, 200)
  2378. output_text = output.get_data(as_text=True)
  2379. self.assertIn("Binary files cannot be rendered.<br/>", output_text)
  2380. def test_view_raw_file(self):
  2381. """ Test the view_raw_file endpoint. """
  2382. output = self.app.get("/foo/raw/foo/sources")
  2383. # No project registered in the DB
  2384. self.assertEqual(output.status_code, 404)
  2385. tests.create_projects(self.session)
  2386. output = self.app.get("/test/raw/foo/sources")
  2387. # No git repo associated
  2388. self.assertEqual(output.status_code, 404)
  2389. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2390. output = self.app.get("/test/raw/foo/sources")
  2391. self.assertEqual(output.status_code, 404)
  2392. # Add some content to the git repo
  2393. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2394. # View first commit
  2395. output = self.app.get("/test/raw/master")
  2396. self.assertEqual(output.status_code, 200)
  2397. output_text = output.get_data(as_text=True)
  2398. self.assertEqual(
  2399. output.headers["Content-Type"].lower(), "text/plain; charset=ascii"
  2400. )
  2401. self.assertIn(":Author: Pierre-Yves Chibon", output_text)
  2402. # Add some more content to the repo
  2403. tests.add_content_git_repo(
  2404. os.path.join(self.path, "repos", "test.git")
  2405. )
  2406. tests.add_binary_git_repo(
  2407. os.path.join(self.path, "repos", "test.git"), "test.jpg"
  2408. )
  2409. tests.add_binary_git_repo(
  2410. os.path.join(self.path, "repos", "test.git"), "test_binary"
  2411. )
  2412. output = self.app.get("/test/raw/master/f/foofile")
  2413. self.assertEqual(output.status_code, 404)
  2414. # View in a branch
  2415. output = self.app.get("/test/raw/master/f/sources")
  2416. self.assertEqual(
  2417. output.headers["Content-Type"].lower(), "text/plain; charset=ascii"
  2418. )
  2419. self.assertEqual(output.status_code, 200)
  2420. output_text = output.get_data(as_text=True)
  2421. self.assertIn("foo\n bar", output_text)
  2422. # View what's supposed to be an image
  2423. output = self.app.get("/test/raw/master/f/test.jpg")
  2424. self.assertEqual(output.status_code, 200)
  2425. output_text = output.get_data()
  2426. self.assertTrue(output_text.startswith(b"\x00\x00\x01\x00"))
  2427. # View by commit id
  2428. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2429. commit = repo.revparse_single("HEAD")
  2430. output = self.app.get("/test/raw/%s/f/test.jpg" % commit.oid.hex)
  2431. self.assertEqual(output.status_code, 200)
  2432. output_text = output.get_data()
  2433. self.assertTrue(output_text.startswith(b"\x00\x00\x01\x00"))
  2434. # View by image name -- somehow we support this
  2435. output = self.app.get("/test/raw/sources/f/test.jpg")
  2436. self.assertEqual(output.status_code, 200)
  2437. output_text = output.get_data()
  2438. self.assertTrue(output_text.startswith(b"\x00\x00\x01\x00"))
  2439. # View binary file
  2440. output = self.app.get("/test/raw/sources/f/test_binary")
  2441. self.assertEqual(output.status_code, 200)
  2442. output_text = output.get_data()
  2443. self.assertEqual(
  2444. output.headers["Content-Type"].lower(), "application/octet-stream"
  2445. )
  2446. self.assertTrue(output_text.startswith(b"\x00\x00\x01\x00"))
  2447. # View folder
  2448. output = self.app.get("/test/raw/master/f/folder1")
  2449. self.assertEqual(output.status_code, 404)
  2450. # View by image name -- with a non-existant file
  2451. output = self.app.get("/test/raw/sources/f/testfoo.jpg")
  2452. self.assertEqual(output.status_code, 404)
  2453. output = self.app.get("/test/raw/master/f/folder1/testfoo.jpg")
  2454. self.assertEqual(output.status_code, 404)
  2455. output = self.app.get("/test/raw/master/f/")
  2456. self.assertEqual(output.status_code, 404)
  2457. output = self.app.get("/test/raw/master")
  2458. self.assertEqual(output.status_code, 200)
  2459. output_text = output.get_data(as_text=True)
  2460. self.assertEqual(
  2461. output.headers["Content-Type"].lower(), "text/plain; charset=ascii"
  2462. )
  2463. self.assertTrue(
  2464. output_text.startswith("diff --git a/test_binary b/test_binary\n")
  2465. )
  2466. output = self.app.get("/test/raw/%s" % commit.oid.hex)
  2467. self.assertEqual(output.status_code, 200)
  2468. output_text = output.get_data(as_text=True)
  2469. self.assertTrue(
  2470. output_text.startswith("diff --git a/test_binary b/test_binary\n")
  2471. )
  2472. # Add a fork of a fork
  2473. item = pagure.lib.model.Project(
  2474. user_id=1, # pingou
  2475. name="test3",
  2476. description="test project #3",
  2477. is_fork=True,
  2478. parent_id=1,
  2479. hook_token="aaabbbqqq",
  2480. )
  2481. self.session.add(item)
  2482. self.session.commit()
  2483. tests.add_content_git_repo(
  2484. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  2485. )
  2486. tests.add_readme_git_repo(
  2487. os.path.join(self.path, "repos", "forks", "pingou", "test3.git")
  2488. )
  2489. tests.add_commit_git_repo(
  2490. os.path.join(self.path, "repos", "forks", "pingou", "test3.git"),
  2491. ncommits=10,
  2492. )
  2493. output = self.app.get("/fork/pingou/test3/raw/master/f/sources")
  2494. self.assertEqual(output.status_code, 200)
  2495. output_text = output.get_data(as_text=True)
  2496. self.assertEqual(
  2497. output.headers["Content-Type"].lower(), "text/plain; charset=ascii"
  2498. )
  2499. self.assertIn("foo\n bar", output_text)
  2500. def test_view_commit(self):
  2501. """ Test the view_commit endpoint. """
  2502. output = self.app.get("/foo/c/bar")
  2503. # No project registered in the DB
  2504. self.assertEqual(output.status_code, 404)
  2505. tests.create_projects(self.session)
  2506. output = self.app.get("/test/c/bar")
  2507. # No git repo associated
  2508. self.assertEqual(output.status_code, 404)
  2509. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2510. output = self.app.get("/test/c/bar")
  2511. self.assertEqual(output.status_code, 404)
  2512. # Add a README to the git repo - First commit
  2513. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2514. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2515. commit = repo.revparse_single("HEAD")
  2516. # View first commit
  2517. output = self.app.get("/test/c/%s" % commit.oid.hex)
  2518. self.assertEqual(output.status_code, 200)
  2519. output_text = output.get_data(as_text=True)
  2520. self.assertIn("#commit-overview-collapse", output_text)
  2521. self.assertIn("Merged by Alice Author", output_text)
  2522. self.assertIn("Committed by Cecil Committer", output_text)
  2523. self.assertIn(
  2524. '<div class="btn btn-outline-success disabled opacity-100 '
  2525. 'border-0 font-weight-bold">file added</div>',
  2526. output_text,
  2527. )
  2528. # View first commit - with the old URL scheme disabled - default
  2529. output = self.app.get(
  2530. "/test/%s" % commit.oid.hex, follow_redirects=True
  2531. )
  2532. self.assertEqual(output.status_code, 404)
  2533. output_text = output.get_data(as_text=True)
  2534. self.assertIn("<p>Project not found</p>", output_text)
  2535. # Add some content to the git repo
  2536. tests.add_content_git_repo(
  2537. os.path.join(self.path, "repos", "test.git")
  2538. )
  2539. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2540. commit = repo.revparse_single("HEAD")
  2541. # Add a symlink to test that it displays correctly
  2542. tests.add_commit_git_repo(
  2543. os.path.join(self.path, "repos", "test.git"),
  2544. ncommits=1,
  2545. filename="sources-sl",
  2546. symlink_to="sources",
  2547. )
  2548. commit_sl = repo.revparse_single("HEAD")
  2549. # View another commit
  2550. output = self.app.get("/test/c/%s" % commit.oid.hex)
  2551. self.assertEqual(output.status_code, 200)
  2552. output_text = output.get_data(as_text=True)
  2553. self.assertIn("#commit-overview-collapse", output_text)
  2554. self.assertIn("Authored by Alice Author", output_text)
  2555. self.assertIn("Committed by Cecil Committer", output_text)
  2556. # Make sure that diff containing symlink displays the header correctly
  2557. output = self.app.get("/test/c/%s" % commit_sl.oid.hex)
  2558. self.assertEqual(output.status_code, 200)
  2559. output_text = output.get_data(as_text=True)
  2560. # check the link to the file
  2561. self.assertIn(">sources-sl</a>", output_text)
  2562. # check that the header contains "file added" and a +1 for one added line
  2563. self.assertIn(">file added</span>", output_text)
  2564. self.assertIn(">+1</span>", output_text)
  2565. # View the commit when branch name is provided
  2566. output = self.app.get("/test/c/%s?branch=master" % commit.oid.hex)
  2567. self.assertEqual(output.status_code, 200)
  2568. output_text = output.get_data(as_text=True)
  2569. self.assertIn(
  2570. '<a class=\n "nav-link nowrap\n active"\n '
  2571. 'href="/test/commits/master">\n <i class="fa fa-list-alt '
  2572. 'text-muted fa-fw" data-glyph="spreadsheet"></i>&nbsp;Commits'
  2573. "\n </a>",
  2574. output_text,
  2575. )
  2576. # View the commit when branch name is wrong, show the commit
  2577. output = self.app.get("/test/c/%s?branch=abcxyz" % commit.oid.hex)
  2578. self.assertEqual(output.status_code, 200)
  2579. output_text = output.get_data(as_text=True)
  2580. self.assertIn(
  2581. '<a class=\n "nav-link nowrap\n active"\n '
  2582. 'href="/test/commits">\n <i class="fa fa-list-alt '
  2583. 'text-muted fa-fw" data-glyph="spreadsheet"></i>&nbsp;Commits'
  2584. "\n </a>\n",
  2585. output_text,
  2586. )
  2587. # Add a fork of a fork
  2588. item = pagure.lib.model.Project(
  2589. user_id=1, # pingou
  2590. name="test3",
  2591. description="test project #3",
  2592. is_fork=True,
  2593. parent_id=1,
  2594. hook_token="aaabbbkkk",
  2595. )
  2596. self.session.add(item)
  2597. self.session.commit()
  2598. forkedgit = os.path.join(
  2599. self.path, "repos", "forks", "pingou", "test3.git"
  2600. )
  2601. tests.add_content_git_repo(forkedgit)
  2602. tests.add_readme_git_repo(forkedgit)
  2603. repo = pygit2.Repository(forkedgit)
  2604. commit = repo.revparse_single("HEAD")
  2605. # Commit does not exist in anothe repo :)
  2606. output = self.app.get("/test/c/%s" % commit.oid.hex)
  2607. self.assertEqual(output.status_code, 404)
  2608. # View commit of fork
  2609. output = self.app.get("/fork/pingou/test3/c/%s" % commit.oid.hex)
  2610. self.assertEqual(output.status_code, 200)
  2611. output_text = output.get_data(as_text=True)
  2612. self.assertIn("#commit-overview-collapse", output_text)
  2613. self.assertIn("Authored by Alice Author", output_text)
  2614. self.assertIn("Committed by Cecil Committer", output_text)
  2615. # Try the old URL scheme with a short hash
  2616. output = self.app.get(
  2617. "/fork/pingou/test3/%s" % commit.oid.hex[:10],
  2618. follow_redirects=True,
  2619. )
  2620. self.assertEqual(output.status_code, 404)
  2621. output_text = output.get_data(as_text=True)
  2622. self.assertIn("<p>Project not found</p>", output_text)
  2623. # View the commit of the fork when branch name is provided
  2624. output = self.app.get(
  2625. "/fork/pingou/test3/c/%s?branch=master" % commit.oid.hex
  2626. )
  2627. self.assertEqual(output.status_code, 200)
  2628. output_text = output.get_data(as_text=True)
  2629. self.assertIn(
  2630. '<a class=\n "nav-link nowrap\n active"\n '
  2631. 'href="/fork/pingou/test3/commits/master">\n '
  2632. '<i class="fa fa-list-alt '
  2633. 'text-muted fa-fw" data-glyph="spreadsheet"></i>&nbsp;Commits'
  2634. "\n </a>\n",
  2635. output_text,
  2636. )
  2637. # View the commit of the fork when branch name is wrong
  2638. output = self.app.get(
  2639. "/fork/pingou/test3/c/%s?branch=abcxyz" % commit.oid.hex
  2640. )
  2641. self.assertEqual(output.status_code, 200)
  2642. output_text = output.get_data(as_text=True)
  2643. self.assertIn(
  2644. '<a class=\n "nav-link nowrap\n active"\n '
  2645. 'href="/fork/pingou/test3/commits">\n <i class="fa fa-list-alt '
  2646. 'text-muted fa-fw" data-glyph="spreadsheet"></i>&nbsp;Commits'
  2647. "\n </a>",
  2648. output_text,
  2649. )
  2650. def test_view_commit_with_full_link(self):
  2651. """ Test the view_commit endpoint when the commit message includes
  2652. an url. """
  2653. tests.create_projects(self.session)
  2654. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2655. folder = os.path.join(self.path, "repos", "test.git")
  2656. # Add a README to the git repo - First commit
  2657. tests.add_readme_git_repo(folder)
  2658. tests.create_projects_git(folder, bare=True)
  2659. # Add a commit with an url in the commit message
  2660. tests.add_content_to_git(
  2661. folder,
  2662. branch="master",
  2663. filename="sources",
  2664. content="foo",
  2665. message="Test commit message\n\n"
  2666. "Fixes http://example.com/pagure/issue/2",
  2667. )
  2668. # Add a README to the git repo - First commit
  2669. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2670. commit = repo.revparse_single("HEAD")
  2671. # View first commit
  2672. output = self.app.get("/test/c/%s" % commit.oid.hex)
  2673. self.assertEqual(output.status_code, 200)
  2674. output_text = output.get_data(as_text=True)
  2675. self.assertIn("#commit-overview-collapse", output_text)
  2676. self.assertIn(
  2677. '<pre class="commit_message_body">\n '
  2678. "Test commit message\n \n "
  2679. 'Fixes <a href="http://example.com/pagure/issue/2" '
  2680. 'rel="nofollow">http://example.com/pagure/issue/2</a>\n '
  2681. "</pre>",
  2682. output_text,
  2683. )
  2684. self.assertIn(
  2685. '<div class="btn btn-outline-success disabled opacity-100 '
  2686. 'border-0 font-weight-bold">file added</div>',
  2687. output_text,
  2688. )
  2689. def test_view_commit_with_short_link(self):
  2690. """ Test the view_commit endpoint when the commit message includes
  2691. an url. """
  2692. tests.create_projects(self.session)
  2693. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2694. folder = os.path.join(self.path, "repos", "test.git")
  2695. # Add a README to the git repo - First commit
  2696. tests.add_readme_git_repo(folder)
  2697. tests.create_projects_git(folder, bare=True)
  2698. # Add a commit with an url in the commit message
  2699. tests.add_content_to_git(
  2700. folder,
  2701. branch="master",
  2702. filename="sources",
  2703. content="foo",
  2704. message="Test commit message\n\nFixes #2",
  2705. )
  2706. # Add a README to the git repo - First commit
  2707. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2708. commit = repo.revparse_single("HEAD")
  2709. # View first commit
  2710. output = self.app.get("/test/c/%s" % commit.oid.hex)
  2711. self.assertEqual(output.status_code, 200)
  2712. output_text = output.get_data(as_text=True)
  2713. self.assertIn("#commit-overview-collapse", output_text)
  2714. self.assertIn(
  2715. '<pre class="commit_message_body">\n '
  2716. "Test commit message\n \n "
  2717. "Fixes #2\n </pre>",
  2718. output_text,
  2719. )
  2720. self.assertIn(
  2721. '<div class="btn btn-outline-success disabled opacity-100 '
  2722. 'border-0 font-weight-bold">file added</div>',
  2723. output_text,
  2724. )
  2725. def test_view_commit_patch(self):
  2726. """ Test the view_commit_patch endpoint. """
  2727. # No project registered in the DB
  2728. output = self.app.get("/foo/c/bar.patch")
  2729. self.assertEqual(output.status_code, 404)
  2730. tests.create_projects(self.session)
  2731. output = self.app.get("/test/c/bar.patch")
  2732. # No git repo associated
  2733. self.assertEqual(output.status_code, 404)
  2734. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2735. output = self.app.get("/test/c/bar.patch")
  2736. self.assertEqual(output.status_code, 404)
  2737. # Add a README to the git repo - First commit
  2738. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2739. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2740. commit = repo.revparse_single("HEAD")
  2741. # View first commit
  2742. output = self.app.get("/test/c/%s.patch" % commit.oid.hex)
  2743. self.assertEqual(output.status_code, 200)
  2744. output_text = output.get_data(as_text=True)
  2745. self.assertIn(
  2746. r"""diff --git a/README.rst b/README.rst
  2747. new file mode 100644
  2748. index 0000000..fb7093d
  2749. --- /dev/null
  2750. +++ b/README.rst
  2751. @@ -0,0 +1,16 @@
  2752. +Pagure
  2753. +======
  2754. +
  2755. +:Author: Pierre-Yves Chibon <pingou@pingoured.fr>
  2756. +
  2757. +
  2758. +Pagure is a light-weight git-centered forge based on pygit2.
  2759. +
  2760. +Currently, Pagure offers a web-interface for git repositories, a ticket
  2761. +system and possibilities to create new projects, fork existing ones and
  2762. +create/merge pull-requests across or within projects.
  2763. +
  2764. +
  2765. +Homepage: https://github.com/pypingou/pagure
  2766. +
  2767. +Dev instance: http://209.132.184.222/ (/!\ May change unexpectedly, it's a dev instance ;-))
  2768. """,
  2769. output_text,
  2770. )
  2771. self.assertIn("Subject: Add a README file", output_text)
  2772. # Add some content to the git repo
  2773. tests.add_content_git_repo(
  2774. os.path.join(self.path, "repos", "test.git")
  2775. )
  2776. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2777. commit = repo.revparse_single("HEAD")
  2778. # View another commit
  2779. output = self.app.get("/test/c/%s.patch" % commit.oid.hex)
  2780. self.assertEqual(output.status_code, 200)
  2781. output_text = output.get_data(as_text=True)
  2782. self.assertIn(
  2783. "Subject: Add some directory and a file for more testing",
  2784. output_text,
  2785. )
  2786. self.assertIn(
  2787. r"""diff --git a/folder1/folder2/file b/folder1/folder2/file
  2788. new file mode 100644
  2789. index 0000000..11980b1
  2790. --- /dev/null
  2791. +++ b/folder1/folder2/file
  2792. @@ -0,0 +1,3 @@
  2793. +foo
  2794. + bar
  2795. +baz
  2796. \ No newline at end of file
  2797. """,
  2798. output_text,
  2799. )
  2800. # Add a fork of a fork
  2801. item = pagure.lib.model.Project(
  2802. user_id=1, # pingou
  2803. name="test3",
  2804. description="test project #3",
  2805. is_fork=True,
  2806. parent_id=1,
  2807. hook_token="aaabbblll",
  2808. )
  2809. self.session.add(item)
  2810. self.session.commit()
  2811. forkedgit = os.path.join(
  2812. self.path, "repos", "forks", "pingou", "test3.git"
  2813. )
  2814. tests.add_content_git_repo(forkedgit)
  2815. tests.add_readme_git_repo(forkedgit)
  2816. repo = pygit2.Repository(forkedgit)
  2817. commit = repo.revparse_single("HEAD")
  2818. # Commit does not exist in anothe repo :)
  2819. output = self.app.get("/test/c/%s.patch" % commit.oid.hex)
  2820. self.assertEqual(output.status_code, 404)
  2821. # View commit of fork
  2822. output = self.app.get("/fork/pingou/test3/c/%s.patch" % commit.oid.hex)
  2823. self.assertEqual(output.status_code, 200)
  2824. output_text = output.get_data(as_text=True)
  2825. self.assertIn(
  2826. r"""diff --git a/README.rst b/README.rst
  2827. new file mode 100644
  2828. index 0000000..fb7093d
  2829. --- /dev/null
  2830. +++ b/README.rst
  2831. @@ -0,0 +1,16 @@
  2832. +Pagure
  2833. +======
  2834. +
  2835. +:Author: Pierre-Yves Chibon <pingou@pingoured.fr>
  2836. +
  2837. +
  2838. +Pagure is a light-weight git-centered forge based on pygit2.
  2839. +
  2840. +Currently, Pagure offers a web-interface for git repositories, a ticket
  2841. +system and possibilities to create new projects, fork existing ones and
  2842. +create/merge pull-requests across or within projects.
  2843. +
  2844. +
  2845. +Homepage: https://github.com/pypingou/pagure
  2846. +
  2847. +Dev instance: http://209.132.184.222/ (/!\ May change unexpectedly, it's a dev instance ;-))
  2848. """,
  2849. output_text,
  2850. )
  2851. def test_view_commit_diff(self):
  2852. """ Test the view_commit_diff endpoint. """
  2853. # No project registered in the DB
  2854. output = self.app.get("/foo/c/bar.diff")
  2855. self.assertEqual(output.status_code, 404)
  2856. tests.create_projects(self.session)
  2857. output = self.app.get("/test/c/bar.diff")
  2858. # No git repo associated
  2859. self.assertEqual(output.status_code, 404)
  2860. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2861. output = self.app.get("/test/c/bar.diff")
  2862. self.assertEqual(output.status_code, 404)
  2863. # Add a README to the git repo - First commit
  2864. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2865. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2866. commit = repo.revparse_single("HEAD")
  2867. # View first commit
  2868. output = self.app.get("/test/c/%s.diff" % commit.oid.hex)
  2869. self.assertEqual(output.status_code, 200)
  2870. output_text = output.get_data(as_text=True)
  2871. self.assertEqual(
  2872. r"""diff --git a/README.rst b/README.rst
  2873. new file mode 100644
  2874. index 0000000..fb7093d
  2875. --- /dev/null
  2876. +++ b/README.rst
  2877. @@ -0,0 +1,16 @@
  2878. +Pagure
  2879. +======
  2880. +
  2881. +:Author: Pierre-Yves Chibon <pingou@pingoured.fr>
  2882. +
  2883. +
  2884. +Pagure is a light-weight git-centered forge based on pygit2.
  2885. +
  2886. +Currently, Pagure offers a web-interface for git repositories, a ticket
  2887. +system and possibilities to create new projects, fork existing ones and
  2888. +create/merge pull-requests across or within projects.
  2889. +
  2890. +
  2891. +Homepage: https://github.com/pypingou/pagure
  2892. +
  2893. +Dev instance: http://209.132.184.222/ (/!\ May change unexpectedly, it's a dev instance ;-))
  2894. """,
  2895. output_text,
  2896. )
  2897. def test_view_tree(self):
  2898. """ Test the view_tree endpoint. """
  2899. output = self.app.get("/foo/tree/")
  2900. # No project registered in the DB
  2901. self.assertEqual(output.status_code, 404)
  2902. tests.create_projects(self.session)
  2903. output = self.app.get("/test/tree/")
  2904. # No git repo associated
  2905. self.assertEqual(output.status_code, 404)
  2906. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2907. output = self.app.get("/test/tree/")
  2908. self.assertEqual(output.status_code, 200)
  2909. output_text = output.get_data(as_text=True)
  2910. self.assertIn(
  2911. """<ol class="breadcrumb p-0 bg-transparent mb-0">
  2912. <li class="breadcrumb-item">
  2913. <a href="/test/tree">
  2914. <span class="fa fa-random">
  2915. </span>&nbsp; None
  2916. </a>
  2917. </li>
  2918. </ol>""",
  2919. output_text,
  2920. )
  2921. self.assertIn("No content found in this repository", output_text)
  2922. # Add a README to the git repo - First commit
  2923. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2924. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  2925. commit = repo.revparse_single("HEAD")
  2926. # View first commit
  2927. output = self.app.get("/test/tree/%s" % commit.oid.hex)
  2928. self.assertEqual(output.status_code, 200)
  2929. output_text = output.get_data(as_text=True)
  2930. self.assertIn("<title>Tree - test - Pagure</title>", output_text)
  2931. self.assertIn("README.rst", output_text)
  2932. self.assertFalse("No content found in this repository" in output_text)
  2933. # View tree, no identifier:
  2934. output = self.app.get("/test/tree/")
  2935. self.assertEqual(output.status_code, 200)
  2936. output_text = output.get_data(as_text=True)
  2937. self.assertIn("<title>Tree - test - Pagure</title>", output_text)
  2938. self.assertIn("README.rst", output_text)
  2939. self.assertNotIn("No content found in this repository", output_text)
  2940. self.assertNotIn(
  2941. "&#39;None&#39; not found in the git repository, going back to: "
  2942. "master",
  2943. output_text,
  2944. )
  2945. # View tree, invalid identifier:
  2946. output = self.app.get("/test/tree/invalid")
  2947. self.assertEqual(output.status_code, 200)
  2948. output_text = output.get_data(as_text=True)
  2949. self.assertIn("<title>Tree - test - Pagure</title>", output_text)
  2950. self.assertIn("README.rst", output_text)
  2951. self.assertNotIn("No content found in this repository", output_text)
  2952. self.assertIn(
  2953. "&#39;invalid&#39; not found in the git repository, going back "
  2954. "to: master",
  2955. output_text,
  2956. )
  2957. # View tree by branch
  2958. output = self.app.get("/test/tree/master")
  2959. self.assertEqual(output.status_code, 200)
  2960. output_text = output.get_data(as_text=True)
  2961. self.assertIn("<title>Tree - test - Pagure</title>", output_text)
  2962. self.assertIn("README.rst", output_text)
  2963. self.assertNotIn("No content found in this repository", output_text)
  2964. # Add a fork of a fork
  2965. item = pagure.lib.model.Project(
  2966. user_id=1, # pingou
  2967. name="test3",
  2968. description="test project #3",
  2969. is_fork=True,
  2970. parent_id=1,
  2971. hook_token="aaabbbfff",
  2972. )
  2973. self.session.add(item)
  2974. self.session.commit()
  2975. forkedgit = os.path.join(
  2976. self.path, "repos", "forks", "pingou", "test3.git"
  2977. )
  2978. tests.add_content_git_repo(forkedgit)
  2979. output = self.app.get("/fork/pingou/test3/tree/")
  2980. self.assertEqual(output.status_code, 200)
  2981. output_text = output.get_data(as_text=True)
  2982. self.assertIn("<title>Tree - test3 - Pagure</title>", output_text)
  2983. self.assertIn(
  2984. '<a href="/fork/pingou/test3/blob/master/f/folder1">', output_text
  2985. )
  2986. self.assertIn(
  2987. '<a href="/fork/pingou/test3/blob/master/f/sources">', output_text
  2988. )
  2989. self.assertNotIn("No content found in this repository", output_text)
  2990. output = self.app.get(
  2991. "/fork/pingou/test3/blob/master/f/folder1/folder2"
  2992. )
  2993. self.assertEqual(output.status_code, 200)
  2994. output_text = output.get_data(as_text=True)
  2995. self.assertIn(
  2996. '<a href="/fork/pingou/test3/blob/master/'
  2997. 'f/folder1/folder2/file%C5%A0">',
  2998. output_text,
  2999. )
  3000. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  3001. @patch("pagure.lib.notify.send_email")
  3002. @patch("pagure.decorators.admin_session_timedout")
  3003. def test_delete_repo_when_turned_off(self, ast, send_email):
  3004. """ Test the delete_repo endpoint when deletion of a repo is
  3005. turned off in the pagure instance """
  3006. ast.return_value = False
  3007. send_email.return_value = True
  3008. # No Git repo
  3009. output = self.app.post("/foo/delete")
  3010. self.assertEqual(output.status_code, 404)
  3011. user = tests.FakeUser(username="pingou")
  3012. with tests.user_set(self.app.application, user):
  3013. tests.create_projects(self.session)
  3014. tests.create_projects_git(os.path.join(self.path, "repos"))
  3015. output = self.app.post("/test/delete", follow_redirects=True)
  3016. self.assertEqual(output.status_code, 404)
  3017. # User not logged in
  3018. output = self.app.post("/test/delete")
  3019. self.assertEqual(output.status_code, 302)
  3020. # Ensure the project isn't read-only
  3021. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  3022. repo.read_only = False
  3023. self.session.add(repo)
  3024. self.session.commit()
  3025. with tests.user_set(self.app.application, user):
  3026. # Only git repo
  3027. output = self.app.post("/test/delete", follow_redirects=True)
  3028. self.assertEqual(output.status_code, 404)
  3029. # Only git and doc repo
  3030. tests.create_projects_git(os.path.join(self.path, "repos"))
  3031. tests.create_projects_git(os.path.join(self.path, "docs"))
  3032. output = self.app.post("/test/delete", follow_redirects=True)
  3033. self.assertEqual(output.status_code, 404)
  3034. # Create all the git repos
  3035. tests.create_projects_git(os.path.join(self.path, "repos"))
  3036. tests.create_projects_git(os.path.join(self.path, "docs"))
  3037. tests.create_projects_git(
  3038. os.path.join(self.path, "tickets"), bare=True
  3039. )
  3040. tests.create_projects_git(
  3041. os.path.join(self.path, "requests"), bare=True
  3042. )
  3043. # Check repo was created
  3044. output = self.app.get("/", follow_redirects=True)
  3045. self.assertEqual(output.status_code, 200)
  3046. output_text = output.get_data(as_text=True)
  3047. self.assertIn(
  3048. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3049. 'border-0 ml-auto font-weight-bold">3 Projects</span>',
  3050. output_text,
  3051. )
  3052. self.assertNotIn(
  3053. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3054. output_text,
  3055. )
  3056. # add issues
  3057. repo = pagure.lib.query.get_authorized_project(
  3058. self.session, "test"
  3059. )
  3060. msg = pagure.lib.query.new_issue(
  3061. session=self.session,
  3062. repo=repo,
  3063. title="Test issue",
  3064. content="We should work on this",
  3065. user="pingou",
  3066. )
  3067. self.session.commit()
  3068. self.assertEqual(msg.title, "Test issue")
  3069. msg = pagure.lib.query.new_issue(
  3070. session=self.session,
  3071. repo=repo,
  3072. title="Test issue #2",
  3073. content="We should work on this, really",
  3074. user="pingou",
  3075. )
  3076. self.session.commit()
  3077. self.assertEqual(msg.title, "Test issue #2")
  3078. # Add a comment to an issue
  3079. issue = pagure.lib.query.search_issues(
  3080. self.session, repo, issueid=1
  3081. )
  3082. msg = pagure.lib.query.add_issue_comment(
  3083. session=self.session,
  3084. issue=issue,
  3085. comment="Hey look a comment!",
  3086. user="foo",
  3087. )
  3088. self.session.commit()
  3089. self.assertEqual(msg, "Comment added")
  3090. # add pull-requests
  3091. req = pagure.lib.query.new_pull_request(
  3092. session=self.session,
  3093. repo_from=repo,
  3094. branch_from="feature",
  3095. repo_to=repo,
  3096. branch_to="master",
  3097. title="test pull-request",
  3098. user="pingou",
  3099. )
  3100. self.session.commit()
  3101. self.assertEqual(req.id, 3)
  3102. self.assertEqual(req.title, "test pull-request")
  3103. req = pagure.lib.query.new_pull_request(
  3104. session=self.session,
  3105. repo_from=repo,
  3106. branch_from="feature2",
  3107. repo_to=repo,
  3108. branch_to="master",
  3109. title="test pull-request",
  3110. user="pingou",
  3111. )
  3112. self.session.commit()
  3113. self.assertEqual(req.id, 4)
  3114. self.assertEqual(req.title, "test pull-request")
  3115. # Add comment on a pull-request
  3116. request = pagure.lib.query.search_pull_requests(
  3117. self.session, requestid=3
  3118. )
  3119. msg = pagure.lib.query.add_pull_request_comment(
  3120. session=self.session,
  3121. request=request,
  3122. commit="commithash",
  3123. tree_id=None,
  3124. filename="file",
  3125. row=None,
  3126. comment="This is awesome, I got to remember it!",
  3127. user="foo",
  3128. )
  3129. self.assertEqual(msg, "Comment added")
  3130. # Check before deleting the project
  3131. output = self.app.get("/", follow_redirects=True)
  3132. self.assertEqual(output.status_code, 200)
  3133. output_text = output.get_data(as_text=True)
  3134. self.assertIn(
  3135. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3136. 'border-0 ml-auto font-weight-bold">3 Projects</span>',
  3137. output_text,
  3138. )
  3139. self.assertNotIn(
  3140. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3141. output_text,
  3142. )
  3143. output = self.app.post("/test/delete", follow_redirects=True)
  3144. self.assertEqual(output.status_code, 404)
  3145. repo = pagure.lib.query.get_authorized_project(
  3146. self.session, "test"
  3147. )
  3148. self.assertNotEqual(repo, None)
  3149. repo = pagure.lib.query.get_authorized_project(
  3150. self.session, "test2"
  3151. )
  3152. self.assertNotEqual(repo, None)
  3153. # Add a fork of a fork
  3154. item = pagure.lib.model.Project(
  3155. user_id=1, # pingou
  3156. name="test3",
  3157. description="test project #3",
  3158. is_fork=True,
  3159. parent_id=2,
  3160. hook_token="aaabbbjjj",
  3161. )
  3162. self.session.add(item)
  3163. self.session.commit()
  3164. tests.add_content_git_repo(
  3165. os.path.join(
  3166. self.path, "repos", "forks", "pingou", "test3.git"
  3167. )
  3168. )
  3169. tests.add_content_git_repo(
  3170. os.path.join(self.path, "docs", "pingou", "test3.git")
  3171. )
  3172. tests.add_content_git_repo(
  3173. os.path.join(self.path, "tickets", "pingou", "test3.git")
  3174. )
  3175. # Check before deleting the fork
  3176. output = self.app.get("/", follow_redirects=True)
  3177. self.assertEqual(output.status_code, 200)
  3178. output_text = output.get_data(as_text=True)
  3179. self.assertIn(
  3180. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3181. 'border-0 ml-auto font-weight-bold">3 Projects</span>',
  3182. output_text,
  3183. )
  3184. self.assertIn(
  3185. """<span>
  3186. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3187. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3188. </span>
  3189. <div class="ml-auto">
  3190. <span class="badge badge-secondary">
  3191. 1
  3192. </span>
  3193. </div>""",
  3194. output_text,
  3195. )
  3196. output = self.app.post(
  3197. "/fork/pingou/test3/delete", follow_redirects=True
  3198. )
  3199. self.assertEqual(output.status_code, 404)
  3200. @patch("pagure.lib.notify.send_email")
  3201. @patch("pagure.decorators.admin_session_timedout")
  3202. def test_delete_read_only_repo(self, ast, send_email):
  3203. """ Test the delete_repo endpoint when the repo is read_only """
  3204. ast.return_value = False
  3205. send_email.return_value = True
  3206. tests.create_projects(self.session)
  3207. tests.create_projects_git(os.path.join(self.path, "repos"))
  3208. # Create all the git repos
  3209. tests.create_projects_git(os.path.join(self.path, "repos"))
  3210. tests.create_projects_git(os.path.join(self.path, "docs"))
  3211. tests.create_projects_git(
  3212. os.path.join(self.path, "tickets"), bare=True
  3213. )
  3214. tests.create_projects_git(
  3215. os.path.join(self.path, "requests"), bare=True
  3216. )
  3217. user = tests.FakeUser(username="pingou")
  3218. with tests.user_set(self.app.application, user):
  3219. repo = pagure.lib.query.get_authorized_project(
  3220. self.session, "test"
  3221. )
  3222. self.assertNotEqual(repo, None)
  3223. repo.read_only = True
  3224. self.session.add(repo)
  3225. self.session.commit()
  3226. output = self.app.post("/test/delete", follow_redirects=True)
  3227. self.assertEqual(output.status_code, 200)
  3228. output_text = output.get_data(as_text=True)
  3229. self.assertIn(
  3230. "<title>Settings - test - Pagure</title>", output_text
  3231. )
  3232. self.assertIn(
  3233. "The ACLs of this project are being refreshed in the "
  3234. "backend this prevents the project from being deleted. "
  3235. "Please wait for this task to finish before trying again. "
  3236. "Thanks!",
  3237. output_text,
  3238. )
  3239. self.assertIn(
  3240. 'title="Action disabled while project\'s ACLs are being refreshed">',
  3241. output_text,
  3242. )
  3243. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  3244. @patch("pagure.decorators.admin_session_timedout")
  3245. def test_delete_repo(self, ast):
  3246. """ Test the delete_repo endpoint. """
  3247. ast.return_value = False
  3248. # No Git repo
  3249. output = self.app.post("/foo/delete")
  3250. self.assertEqual(output.status_code, 404)
  3251. user = tests.FakeUser()
  3252. with tests.user_set(self.app.application, user):
  3253. tests.create_projects(self.session)
  3254. tests.create_projects_git(os.path.join(self.path, "repos"))
  3255. # No project registered in the DB (no git repo)
  3256. output = self.app.post("/foo/delete")
  3257. self.assertEqual(output.status_code, 404)
  3258. # User not allowed
  3259. output = self.app.post("/test/delete")
  3260. self.assertEqual(output.status_code, 403)
  3261. # User not logged in
  3262. output = self.app.post("/test/delete")
  3263. self.assertEqual(output.status_code, 302)
  3264. # Ensure the project isn't read-only
  3265. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  3266. repo.read_only = False
  3267. self.session.add(repo)
  3268. self.session.commit()
  3269. user = tests.FakeUser(username="pingou")
  3270. with tests.user_set(self.app.application, user):
  3271. tests.create_projects_git(os.path.join(self.path, "repos"))
  3272. ast.return_value = True
  3273. output = self.app.post("/test/delete")
  3274. self.assertEqual(output.status_code, 302)
  3275. ast.return_value = False
  3276. output = self.app.post("/test/delete", follow_redirects=True)
  3277. self.assertEqual(output.status_code, 200)
  3278. output_text = output.get_data(as_text=True)
  3279. self.assertIn(
  3280. """<span>
  3281. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3282. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3283. </span>
  3284. <div class="ml-auto">
  3285. <span class="badge badge-secondary">
  3286. 2
  3287. </span>
  3288. </div>""",
  3289. output_text,
  3290. )
  3291. self.assertIn(
  3292. """<span>
  3293. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3294. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3295. </span>
  3296. <div class="ml-auto">
  3297. <span class="badge badge-secondary">
  3298. 0
  3299. </span>
  3300. </div>""",
  3301. output_text,
  3302. )
  3303. # Only git repo
  3304. item = pagure.lib.model.Project(
  3305. user_id=1, # pingou
  3306. name="test",
  3307. description="test project #1",
  3308. hook_token="aaabbbggg",
  3309. read_only=False,
  3310. )
  3311. self.session.add(item)
  3312. self.session.commit()
  3313. tests.create_projects_git(os.path.join(self.path, "repos"))
  3314. output = self.app.post("/test/delete", follow_redirects=True)
  3315. self.assertEqual(output.status_code, 200)
  3316. output_text = output.get_data(as_text=True)
  3317. self.assertIn(
  3318. """<span>
  3319. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3320. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3321. </span>
  3322. <div class="ml-auto">
  3323. <span class="badge badge-secondary">
  3324. 2
  3325. </span>
  3326. </div>""",
  3327. output_text,
  3328. )
  3329. self.assertIn(
  3330. """<span>
  3331. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3332. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3333. </span>
  3334. <div class="ml-auto">
  3335. <span class="badge badge-secondary">
  3336. 0
  3337. </span>
  3338. </div>""",
  3339. output_text,
  3340. )
  3341. # Only git and doc repo
  3342. item = pagure.lib.model.Project(
  3343. user_id=1, # pingou
  3344. name="test",
  3345. description="test project #1",
  3346. hook_token="aaabbbhhh",
  3347. read_only=False,
  3348. )
  3349. self.session.add(item)
  3350. self.session.commit()
  3351. tests.create_projects_git(os.path.join(self.path, "repos"))
  3352. tests.create_projects_git(os.path.join(self.path, "docs"))
  3353. output = self.app.post("/test/delete", follow_redirects=True)
  3354. self.assertEqual(output.status_code, 200)
  3355. output_text = output.get_data(as_text=True)
  3356. self.assertIn(
  3357. """<span>
  3358. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3359. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3360. </span>
  3361. <div class="ml-auto">
  3362. <span class="badge badge-secondary">
  3363. 2
  3364. </span>
  3365. </div>""",
  3366. output_text,
  3367. )
  3368. self.assertIn(
  3369. """<span>
  3370. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3371. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3372. </span>
  3373. <div class="ml-auto">
  3374. <span class="badge badge-secondary">
  3375. 0
  3376. </span>
  3377. </div>""",
  3378. output_text,
  3379. )
  3380. # All repo there
  3381. item = pagure.lib.model.Project(
  3382. user_id=1, # pingou
  3383. name="test",
  3384. description="test project #1",
  3385. hook_token="aaabbbiii",
  3386. read_only=False,
  3387. )
  3388. self.session.add(item)
  3389. self.session.commit()
  3390. # Create all the git repos
  3391. tests.create_projects_git(os.path.join(self.path, "repos"))
  3392. tests.create_projects_git(os.path.join(self.path, "docs"))
  3393. tests.create_projects_git(
  3394. os.path.join(self.path, "tickets"), bare=True
  3395. )
  3396. tests.create_projects_git(
  3397. os.path.join(self.path, "requests"), bare=True
  3398. )
  3399. # Check repo was created
  3400. output = self.app.get("/", follow_redirects=True)
  3401. self.assertEqual(output.status_code, 200)
  3402. output_text = output.get_data(as_text=True)
  3403. self.assertIn(
  3404. """<span>
  3405. <i class="fa fa-calendar-o fa-rotate-270 fa-fw text-muted"></i>
  3406. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3407. </span>
  3408. <div class="ml-auto">
  3409. <span class="badge badge-secondary">
  3410. 3
  3411. </span>
  3412. </div>""",
  3413. output_text,
  3414. )
  3415. self.assertNotIn(
  3416. """<span class="d-none d-md-inline">Forks&nbsp;</span>""",
  3417. output_text,
  3418. )
  3419. # add issues
  3420. repo = pagure.lib.query.get_authorized_project(
  3421. self.session, "test"
  3422. )
  3423. msg = pagure.lib.query.new_issue(
  3424. session=self.session,
  3425. repo=repo,
  3426. title="Test issue",
  3427. content="We should work on this",
  3428. user="pingou",
  3429. )
  3430. self.session.commit()
  3431. self.assertEqual(msg.title, "Test issue")
  3432. msg = pagure.lib.query.new_issue(
  3433. session=self.session,
  3434. repo=repo,
  3435. title="Test issue #2",
  3436. content="We should work on this, really",
  3437. user="pingou",
  3438. )
  3439. self.session.commit()
  3440. self.assertEqual(msg.title, "Test issue #2")
  3441. # Add a comment to an issue
  3442. issue = pagure.lib.query.search_issues(
  3443. self.session, repo, issueid=1
  3444. )
  3445. msg = pagure.lib.query.add_issue_comment(
  3446. session=self.session,
  3447. issue=issue,
  3448. comment="Hey look a comment!",
  3449. user="foo",
  3450. )
  3451. self.session.commit()
  3452. self.assertEqual(msg, "Comment added")
  3453. # add pull-requests
  3454. req = pagure.lib.query.new_pull_request(
  3455. session=self.session,
  3456. repo_from=repo,
  3457. branch_from="feature",
  3458. repo_to=repo,
  3459. branch_to="master",
  3460. title="test pull-request",
  3461. user="pingou",
  3462. )
  3463. self.session.commit()
  3464. self.assertEqual(req.id, 3)
  3465. self.assertEqual(req.title, "test pull-request")
  3466. req = pagure.lib.query.new_pull_request(
  3467. session=self.session,
  3468. repo_from=repo,
  3469. branch_from="feature2",
  3470. repo_to=repo,
  3471. branch_to="master",
  3472. title="test pull-request",
  3473. user="pingou",
  3474. )
  3475. self.session.commit()
  3476. self.assertEqual(req.id, 4)
  3477. self.assertEqual(req.title, "test pull-request")
  3478. # Add comment on a pull-request
  3479. request = pagure.lib.query.search_pull_requests(
  3480. self.session, requestid=3
  3481. )
  3482. msg = pagure.lib.query.add_pull_request_comment(
  3483. session=self.session,
  3484. request=request,
  3485. commit="commithash",
  3486. tree_id=None,
  3487. filename="file",
  3488. row=None,
  3489. comment="This is awesome, I got to remember it!",
  3490. user="foo",
  3491. )
  3492. self.assertEqual(msg, "Comment added")
  3493. # Check before deleting the project
  3494. output = self.app.get("/", follow_redirects=True)
  3495. self.assertEqual(output.status_code, 200)
  3496. output_text = output.get_data(as_text=True)
  3497. self.assertIn(
  3498. """<span>
  3499. <i class="fa fa-calendar-o fa-rotate-270 fa-fw text-muted"></i>
  3500. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3501. </span>
  3502. <div class="ml-auto">
  3503. <span class="badge badge-secondary">
  3504. 3
  3505. </span>
  3506. </div>""",
  3507. output_text,
  3508. )
  3509. self.assertNotIn(
  3510. """<span class="d-none d-md-inline">Forks&nbsp;</span>""",
  3511. output_text,
  3512. )
  3513. output = self.app.post("/test/delete", follow_redirects=True)
  3514. self.assertEqual(output.status_code, 200)
  3515. output_text = output.get_data(as_text=True)
  3516. self.assertIn(
  3517. """<span>
  3518. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3519. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3520. </span>
  3521. <div class="ml-auto">
  3522. <span class="badge badge-secondary">
  3523. 2
  3524. </span>
  3525. </div>""",
  3526. output_text,
  3527. )
  3528. self.assertIn(
  3529. """<span>
  3530. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3531. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3532. </span>
  3533. <div class="ml-auto">
  3534. <span class="badge badge-secondary">
  3535. 0
  3536. </span>
  3537. </div>""",
  3538. output_text,
  3539. )
  3540. repo = pagure.lib.query.get_authorized_project(
  3541. self.session, "test"
  3542. )
  3543. self.assertEqual(repo, None)
  3544. repo = pagure.lib.query.get_authorized_project(
  3545. self.session, "test2"
  3546. )
  3547. self.assertNotEqual(repo, None)
  3548. # Add a fork of a fork
  3549. item = pagure.lib.model.Project(
  3550. user_id=1, # pingou
  3551. name="test3",
  3552. description="test project #3",
  3553. is_fork=True,
  3554. parent_id=2,
  3555. hook_token="aaabbbjjj",
  3556. read_only=False,
  3557. )
  3558. self.session.add(item)
  3559. self.session.commit()
  3560. tests.add_content_git_repo(
  3561. os.path.join(
  3562. self.path, "repos", "forks", "pingou", "test3.git"
  3563. )
  3564. )
  3565. tests.add_content_git_repo(
  3566. os.path.join(self.path, "docs", "pingou", "test3.git")
  3567. )
  3568. tests.add_content_git_repo(
  3569. os.path.join(self.path, "tickets", "pingou", "test3.git")
  3570. )
  3571. # Check before deleting the fork
  3572. output = self.app.get("/", follow_redirects=True)
  3573. self.assertEqual(output.status_code, 200)
  3574. output_text = output.get_data(as_text=True)
  3575. self.assertIn(
  3576. """<span>
  3577. <i class="fa fa-calendar-o fa-rotate-270 fa-fw text-muted"></i>
  3578. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3579. </span>
  3580. <div class="ml-auto">
  3581. <span class="badge badge-secondary">
  3582. 2
  3583. </span>
  3584. </div>""",
  3585. output_text,
  3586. )
  3587. self.assertIn(
  3588. """<span>
  3589. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3590. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3591. </span>
  3592. <div class="ml-auto">
  3593. <span class="badge badge-secondary">
  3594. 1
  3595. </span>
  3596. </div>""",
  3597. output_text,
  3598. )
  3599. output = self.app.post(
  3600. "/fork/pingou/test3/delete", follow_redirects=True
  3601. )
  3602. self.assertEqual(output.status_code, 200)
  3603. output_text = output.get_data(as_text=True)
  3604. self.assertIn(
  3605. """<span>
  3606. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3607. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3608. </span>
  3609. <div class="ml-auto">
  3610. <span class="badge badge-secondary">
  3611. 2
  3612. </span>
  3613. </div>""",
  3614. output_text,
  3615. )
  3616. self.assertIn(
  3617. """<span>
  3618. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3619. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3620. </span>
  3621. <div class="ml-auto">
  3622. <span class="badge badge-secondary">
  3623. 0
  3624. </span>
  3625. </div>""",
  3626. output_text,
  3627. )
  3628. @patch.dict("pagure.config.config", {"TICKETS_FOLDER": None})
  3629. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  3630. @patch(
  3631. "pagure.decorators.admin_session_timedout",
  3632. MagicMock(return_value=False),
  3633. )
  3634. def test_delete_repo_no_ticket(self):
  3635. """ Test the delete_repo endpoint when tickets aren't enabled in
  3636. this pagure instance. """
  3637. tests.create_projects(self.session)
  3638. tests.create_projects_git(os.path.join(self.path, "repos"))
  3639. # Ensure the project isn't read-only
  3640. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  3641. repo.read_only = False
  3642. self.session.add(repo)
  3643. self.session.commit()
  3644. user = tests.FakeUser(username="pingou")
  3645. with tests.user_set(self.app.application, user):
  3646. # Check before deleting the project
  3647. output = self.app.get("/", follow_redirects=True)
  3648. self.assertEqual(output.status_code, 200)
  3649. output_text = output.get_data(as_text=True)
  3650. self.assertIn(
  3651. """<span>
  3652. <i class="fa fa-calendar-o fa-rotate-270 fa-fw text-muted"></i>
  3653. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3654. </span>
  3655. <div class="ml-auto">
  3656. <span class="badge badge-secondary">
  3657. 3
  3658. </span>
  3659. </div>""",
  3660. output_text,
  3661. )
  3662. self.assertNotIn(
  3663. """<span class="d-none d-md-inline">Forks&nbsp;</span>""",
  3664. output_text,
  3665. )
  3666. # Delete the project
  3667. output = self.app.post("/test/delete", follow_redirects=True)
  3668. self.assertEqual(output.status_code, 200)
  3669. output_text = output.get_data(as_text=True)
  3670. # Check deletion worked
  3671. self.assertIn(
  3672. """<span>
  3673. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3674. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3675. </span>
  3676. <div class="ml-auto">
  3677. <span class="badge badge-secondary">
  3678. 2
  3679. </span>
  3680. </div>""",
  3681. output_text,
  3682. )
  3683. self.assertIn(
  3684. """<span>
  3685. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3686. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3687. </span>
  3688. <div class="ml-auto">
  3689. <span class="badge badge-secondary">
  3690. 0
  3691. </span>
  3692. </div>""",
  3693. output_text,
  3694. )
  3695. @patch("pagure.lib.notify.send_email")
  3696. @patch("pagure.decorators.admin_session_timedout")
  3697. def test_delete_repo_with_users(self, ast, send_email):
  3698. """ Test the delete_repo endpoint. """
  3699. ast.return_value = False
  3700. send_email.return_value = True
  3701. user = tests.FakeUser()
  3702. user = tests.FakeUser(username="pingou")
  3703. with tests.user_set(self.app.application, user):
  3704. # Create new project
  3705. item = pagure.lib.model.Project(
  3706. user_id=1, # pingou
  3707. name="test",
  3708. description="test project #1",
  3709. hook_token="aaabbbiii",
  3710. read_only=False,
  3711. )
  3712. self.session.add(item)
  3713. self.session.commit()
  3714. # Create all the git repos
  3715. tests.create_projects_git(os.path.join(self.path, "repos"))
  3716. tests.create_projects_git(
  3717. os.path.join(self.path, "docs"), bare=True
  3718. )
  3719. tests.create_projects_git(
  3720. os.path.join(self.path, "tickets"), bare=True
  3721. )
  3722. tests.create_projects_git(
  3723. os.path.join(self.path, "requests"), bare=True
  3724. )
  3725. # Check repo was created
  3726. output = self.app.get("/", follow_redirects=True)
  3727. self.assertEqual(output.status_code, 200)
  3728. output_text = output.get_data(as_text=True)
  3729. self.assertIn(
  3730. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3731. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  3732. output_text,
  3733. )
  3734. self.assertNotIn(
  3735. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3736. output_text,
  3737. )
  3738. # add user
  3739. repo = pagure.lib.query.get_authorized_project(
  3740. self.session, "test"
  3741. )
  3742. msg = pagure.lib.query.add_user_to_project(
  3743. session=self.session,
  3744. project=repo,
  3745. new_user="foo",
  3746. user="pingou",
  3747. )
  3748. self.session.commit()
  3749. self.assertEqual(msg, "User added")
  3750. # Ensure the project isn't read-only (because adding an user
  3751. # will trigger an ACL refresh, thus read-only)
  3752. repo = pagure.lib.query.get_authorized_project(
  3753. self.session, "test"
  3754. )
  3755. repo.read_only = False
  3756. self.session.add(repo)
  3757. self.session.commit()
  3758. # Check before deleting the project
  3759. output = self.app.get("/", follow_redirects=True)
  3760. self.assertEqual(output.status_code, 200)
  3761. output_text = output.get_data(as_text=True)
  3762. self.assertIn(
  3763. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3764. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  3765. output_text,
  3766. )
  3767. self.assertNotIn(
  3768. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3769. output_text,
  3770. )
  3771. repo = pagure.lib.query.get_authorized_project(
  3772. self.session, "test"
  3773. )
  3774. self.assertNotEqual(repo, None)
  3775. repo = pagure.lib.query.get_authorized_project(
  3776. self.session, "test2"
  3777. )
  3778. self.assertEqual(repo, None)
  3779. # Delete the project
  3780. output = self.app.post("/test/delete", follow_redirects=True)
  3781. self.assertEqual(output.status_code, 200)
  3782. output_text = output.get_data(as_text=True)
  3783. self.assertIn(
  3784. """<span>
  3785. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3786. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3787. </span>
  3788. <div class="ml-auto">
  3789. <span class="badge badge-secondary">
  3790. 0
  3791. </span>
  3792. </div>""",
  3793. output_text,
  3794. )
  3795. self.assertIn(
  3796. """<span>
  3797. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3798. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3799. </span>
  3800. <div class="ml-auto">
  3801. <span class="badge badge-secondary">
  3802. 0
  3803. </span>
  3804. </div>""",
  3805. output_text,
  3806. )
  3807. # Check after
  3808. repo = pagure.lib.query.get_authorized_project(
  3809. self.session, "test"
  3810. )
  3811. self.assertEqual(repo, None)
  3812. repo = pagure.lib.query.get_authorized_project(
  3813. self.session, "test2"
  3814. )
  3815. self.assertEqual(repo, None)
  3816. @patch("pagure.lib.notify.send_email")
  3817. @patch("pagure.decorators.admin_session_timedout")
  3818. def test_delete_repo_with_group(self, ast, send_email):
  3819. """ Test the delete_repo endpoint. """
  3820. ast.return_value = False
  3821. send_email.return_value = True
  3822. user = tests.FakeUser()
  3823. user = tests.FakeUser(username="pingou")
  3824. with tests.user_set(self.app.application, user):
  3825. # Create new project
  3826. item = pagure.lib.model.Project(
  3827. user_id=1, # pingou
  3828. name="test",
  3829. description="test project #1",
  3830. hook_token="aaabbbiii",
  3831. read_only=False,
  3832. )
  3833. self.session.add(item)
  3834. self.session.commit()
  3835. # Create all the git repos
  3836. tests.create_projects_git(os.path.join(self.path, "repos"))
  3837. tests.create_projects_git(
  3838. os.path.join(self.path, "docs"), bare=True
  3839. )
  3840. tests.create_projects_git(
  3841. os.path.join(self.path, "tickets"), bare=True
  3842. )
  3843. tests.create_projects_git(
  3844. os.path.join(self.path, "requests"), bare=True
  3845. )
  3846. # Check repo was created
  3847. output = self.app.get("/", follow_redirects=True)
  3848. self.assertEqual(output.status_code, 200)
  3849. output_text = output.get_data(as_text=True)
  3850. self.assertIn(
  3851. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3852. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  3853. output_text,
  3854. )
  3855. self.assertNotIn(
  3856. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3857. output_text,
  3858. )
  3859. # Create group
  3860. msg = pagure.lib.query.add_group(
  3861. self.session,
  3862. group_name="foo",
  3863. display_name="foo group",
  3864. description=None,
  3865. group_type="bar",
  3866. user="pingou",
  3867. is_admin=False,
  3868. blacklist=[],
  3869. )
  3870. self.session.commit()
  3871. self.assertEqual(msg, "User `pingou` added to the group `foo`.")
  3872. # Add group to the project
  3873. repo = pagure.lib.query.get_authorized_project(
  3874. self.session, "test"
  3875. )
  3876. msg = pagure.lib.query.add_group_to_project(
  3877. session=self.session,
  3878. project=repo,
  3879. new_group="foo",
  3880. user="pingou",
  3881. )
  3882. self.session.commit()
  3883. self.assertEqual(msg, "Group added")
  3884. # Ensure the project isn't read-only (because adding a group
  3885. # will trigger an ACL refresh, thus read-only)
  3886. repo = pagure.lib.query.get_authorized_project(
  3887. self.session, "test"
  3888. )
  3889. repo.read_only = False
  3890. self.session.add(repo)
  3891. self.session.commit()
  3892. # check if group where we expect it
  3893. repo = pagure.lib.query.get_authorized_project(
  3894. self.session, "test"
  3895. )
  3896. self.assertEqual(len(repo.projects_groups), 1)
  3897. # Check before deleting the project
  3898. output = self.app.get("/", follow_redirects=True)
  3899. self.assertEqual(output.status_code, 200)
  3900. output_text = output.get_data(as_text=True)
  3901. self.assertIn(
  3902. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3903. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  3904. output_text,
  3905. )
  3906. self.assertNotIn(
  3907. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3908. output_text,
  3909. )
  3910. repo = pagure.lib.query.get_authorized_project(
  3911. self.session, "test"
  3912. )
  3913. self.assertNotEqual(repo, None)
  3914. # Delete the project
  3915. output = self.app.post("/test/delete", follow_redirects=True)
  3916. self.assertEqual(output.status_code, 200)
  3917. output_text = output.get_data(as_text=True)
  3918. self.assertIn(
  3919. """<span>
  3920. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  3921. <span class="d-none d-md-inline">Projects&nbsp;</span>
  3922. </span>
  3923. <div class="ml-auto">
  3924. <span class="badge badge-secondary">
  3925. 0
  3926. </span>
  3927. </div>""",
  3928. output_text,
  3929. )
  3930. self.assertIn(
  3931. """<span>
  3932. <i class="fa fa-fw text-muted fa-code-fork"></i>
  3933. <span class="d-none d-md-inline">Forks&nbsp;</span>
  3934. </span>
  3935. <div class="ml-auto">
  3936. <span class="badge badge-secondary">
  3937. 0
  3938. </span>
  3939. </div>""",
  3940. output_text,
  3941. )
  3942. # Check after
  3943. repo = pagure.lib.query.get_authorized_project(
  3944. self.session, "test"
  3945. )
  3946. self.assertEqual(repo, None)
  3947. @patch("pagure.lib.notify.send_email")
  3948. @patch("pagure.decorators.admin_session_timedout")
  3949. def test_delete_repo_with_coloredtag(self, ast, send_email):
  3950. """ Test the delete_repo endpoint. """
  3951. ast.return_value = False
  3952. send_email.return_value = True
  3953. user = tests.FakeUser()
  3954. user = tests.FakeUser(username="pingou")
  3955. with tests.user_set(self.app.application, user):
  3956. # Create new project
  3957. item = pagure.lib.model.Project(
  3958. user_id=1, # pingou
  3959. name="test",
  3960. description="test project #1",
  3961. hook_token="aaabbbiii",
  3962. read_only=False,
  3963. )
  3964. self.session.add(item)
  3965. self.session.commit()
  3966. # Create all the git repos
  3967. tests.create_projects_git(os.path.join(self.path, "repos"))
  3968. tests.create_projects_git(
  3969. os.path.join(self.path, "docs"), bare=True
  3970. )
  3971. tests.create_projects_git(
  3972. os.path.join(self.path, "tickets"), bare=True
  3973. )
  3974. tests.create_projects_git(
  3975. os.path.join(self.path, "requests"), bare=True
  3976. )
  3977. # Check repo was created
  3978. output = self.app.get("/", follow_redirects=True)
  3979. self.assertEqual(output.status_code, 200)
  3980. output_text = output.get_data(as_text=True)
  3981. self.assertIn(
  3982. '<span class="btn btn-outline-secondary disabled opacity-100 '
  3983. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  3984. output_text,
  3985. )
  3986. self.assertNotIn(
  3987. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  3988. output_text,
  3989. )
  3990. # Create the issue
  3991. repo = pagure.lib.query.get_authorized_project(
  3992. self.session, "test"
  3993. )
  3994. msg = pagure.lib.query.new_issue(
  3995. session=self.session,
  3996. repo=repo,
  3997. title="Test issue",
  3998. content="We should work on this",
  3999. user="pingou",
  4000. )
  4001. self.session.commit()
  4002. self.assertEqual(msg.title, "Test issue")
  4003. # Add a tag to the issue
  4004. repo = pagure.lib.query.get_authorized_project(
  4005. self.session, "test"
  4006. )
  4007. issue = pagure.lib.query.search_issues(
  4008. self.session, repo, issueid=1
  4009. )
  4010. msg = pagure.lib.query.add_tag_obj(
  4011. session=self.session, obj=issue, tags="tag1", user="pingou"
  4012. )
  4013. self.session.commit()
  4014. self.assertEqual(msg, "Issue tagged with: tag1")
  4015. # Check before deleting the project
  4016. output = self.app.get("/", follow_redirects=True)
  4017. self.assertEqual(output.status_code, 200)
  4018. output_text = output.get_data(as_text=True)
  4019. self.assertIn(
  4020. '<span class="btn btn-outline-secondary disabled opacity-100 '
  4021. 'border-0 ml-auto font-weight-bold">1 Projects</span>',
  4022. output_text,
  4023. )
  4024. self.assertNotIn(
  4025. '<span class="d-none d-md-inline">Forks&nbsp;</span>',
  4026. output_text,
  4027. )
  4028. repo = pagure.lib.query.get_authorized_project(
  4029. self.session, "test"
  4030. )
  4031. self.assertNotEqual(repo, None)
  4032. repo = pagure.lib.query.get_authorized_project(
  4033. self.session, "test2"
  4034. )
  4035. self.assertEqual(repo, None)
  4036. # Delete the project
  4037. output = self.app.post("/test/delete", follow_redirects=True)
  4038. self.assertEqual(output.status_code, 200)
  4039. output_text = output.get_data(as_text=True)
  4040. self.assertIn(
  4041. """<span>
  4042. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  4043. <span class="d-none d-md-inline">Projects&nbsp;</span>
  4044. </span>
  4045. <div class="ml-auto">
  4046. <span class="badge badge-secondary">
  4047. 0
  4048. </span>
  4049. </div>""",
  4050. output_text,
  4051. )
  4052. self.assertIn(
  4053. """<span>
  4054. <i class="fa fa-fw text-muted fa-code-fork"></i>
  4055. <span class="d-none d-md-inline">Forks&nbsp;</span>
  4056. </span>
  4057. <div class="ml-auto">
  4058. <span class="badge badge-secondary">
  4059. 0
  4060. </span>
  4061. </div>""",
  4062. output_text,
  4063. )
  4064. # Check after
  4065. repo = pagure.lib.query.get_authorized_project(
  4066. self.session, "test"
  4067. )
  4068. self.assertEqual(repo, None)
  4069. repo = pagure.lib.query.get_authorized_project(
  4070. self.session, "test2"
  4071. )
  4072. self.assertEqual(repo, None)
  4073. @patch("pagure.decorators.admin_session_timedout")
  4074. def test_new_repo_hook_token(self, ast):
  4075. """ Test the new_repo_hook_token endpoint. """
  4076. ast.return_value = False
  4077. tests.create_projects(self.session)
  4078. tests.create_projects_git(os.path.join(self.path, "repos"))
  4079. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  4080. self.assertEqual(repo.hook_token, "aaabbbccc")
  4081. user = tests.FakeUser()
  4082. with tests.user_set(self.app.application, user):
  4083. pagure.config.config["WEBHOOK"] = True
  4084. output = self.app.get("/new/")
  4085. self.assertEqual(output.status_code, 200)
  4086. output_text = output.get_data(as_text=True)
  4087. self.assertIn("<strong>Create new Project</strong>", output_text)
  4088. csrf_token = output_text.split(
  4089. 'name="csrf_token" type="hidden" value="'
  4090. )[1].split('">')[0]
  4091. output = self.app.post("/foo/hook_token")
  4092. self.assertEqual(output.status_code, 404)
  4093. output = self.app.post("/test/hook_token")
  4094. self.assertEqual(output.status_code, 403)
  4095. ast.return_value = True
  4096. output = self.app.post("/test/hook_token")
  4097. self.assertEqual(output.status_code, 302)
  4098. ast.return_value = False
  4099. pagure.config.config["WEBHOOK"] = False
  4100. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  4101. self.assertEqual(repo.hook_token, "aaabbbccc")
  4102. user.username = "pingou"
  4103. with tests.user_set(self.app.application, user):
  4104. pagure.config.config["WEBHOOK"] = True
  4105. output = self.app.post("/test/hook_token")
  4106. self.assertEqual(output.status_code, 400)
  4107. data = {"csrf_token": csrf_token}
  4108. repo = pagure.lib.query.get_authorized_project(
  4109. self.session, "test"
  4110. )
  4111. self.assertEqual(repo.hook_token, "aaabbbccc")
  4112. output = self.app.post(
  4113. "/test/hook_token", data=data, follow_redirects=True
  4114. )
  4115. self.assertEqual(output.status_code, 200)
  4116. output_text = output.get_data(as_text=True)
  4117. self.assertIn("New hook token generated", output_text)
  4118. pagure.config.config["WEBHOOK"] = False
  4119. self.session.commit()
  4120. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  4121. self.assertNotEqual(repo.hook_token, "aaabbbccc")
  4122. def test_view_tags(self):
  4123. """ Test the view_tags endpoint. """
  4124. output = self.app.get("/foo/releases")
  4125. # No project registered in the DB
  4126. self.assertEqual(output.status_code, 404)
  4127. tests.create_projects(self.session)
  4128. output = self.app.get("/test/releases")
  4129. # No git repo associated
  4130. self.assertEqual(output.status_code, 404)
  4131. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4132. output = self.app.get("/test/releases")
  4133. self.assertEqual(output.status_code, 200)
  4134. output_text = output.get_data(as_text=True)
  4135. self.assertIn("This project has not been tagged.", output_text)
  4136. # Add a README to the git repo - First commit
  4137. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  4138. repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git"))
  4139. first_commit = repo.revparse_single("HEAD")
  4140. tagger = pygit2.Signature("Alice Doe", "adoe@example.com", 12347, 0)
  4141. repo.create_tag(
  4142. "0.0.1",
  4143. first_commit.oid.hex,
  4144. pygit2.GIT_OBJ_COMMIT,
  4145. tagger,
  4146. "Release 0.0.1",
  4147. )
  4148. output = self.app.get("/test/releases")
  4149. self.assertEqual(output.status_code, 200)
  4150. output_text = output.get_data(as_text=True)
  4151. self.assertIn("0.0.1", output_text)
  4152. self.assertIn('<section class="tag_list">', output_text)
  4153. self.assertEqual(
  4154. output_text.count(
  4155. '<i class="fa fa-calendar-o fa-rotate-270 text-muted"></i>'
  4156. ),
  4157. 1,
  4158. )
  4159. def test_edit_file_no_signed_off(self):
  4160. """ Test the edit_file endpoint when signed-off isn't enforced. """
  4161. tests.create_projects(self.session)
  4162. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4163. user = tests.FakeUser()
  4164. user.username = "pingou"
  4165. with tests.user_set(self.app.application, user):
  4166. # Add some content to the git repo
  4167. tests.add_content_git_repo(
  4168. os.path.join(self.path, "repos", "test.git")
  4169. )
  4170. output = self.app.get("/test/edit/master/f/sources")
  4171. self.assertEqual(output.status_code, 200)
  4172. output_text = output.get_data(as_text=True)
  4173. self.assertIn(
  4174. '<li><a href="/test/tree/master"><span class="fa fa-random">'
  4175. '</span>&nbsp; master</a></li><li class="active">'
  4176. '<span class="fa fa-file"></span>&nbsp; sources</li>',
  4177. output_text,
  4178. )
  4179. self.assertIn(
  4180. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  4181. output_text,
  4182. )
  4183. self.assertIn(
  4184. '<textarea rows="5" class="form-control" type="text" '
  4185. 'id="commit_message"\n name="commit_message" '
  4186. 'placeholder="An optional description of the change">'
  4187. "</textarea>",
  4188. output_text,
  4189. )
  4190. def test_edit_file_signed_off(self):
  4191. """ Test the edit_file endpoint when signed-off is enforced. """
  4192. tests.create_projects(self.session)
  4193. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4194. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  4195. settings = repo.settings
  4196. settings["Enforce_signed-off_commits_in_pull-request"] = True
  4197. repo.settings = settings
  4198. self.session.add(repo)
  4199. self.session.commit()
  4200. user = tests.FakeUser()
  4201. user.username = "pingou"
  4202. with tests.user_set(self.app.application, user):
  4203. # Add some content to the git repo
  4204. tests.add_content_git_repo(
  4205. os.path.join(self.path, "repos", "test.git")
  4206. )
  4207. output = self.app.get("/test/edit/master/f/sources")
  4208. self.assertEqual(output.status_code, 200)
  4209. output_text = output.get_data(as_text=True)
  4210. self.assertIn(
  4211. '<li><a href="/test/tree/master"><span class="fa fa-random">'
  4212. '</span>&nbsp; master</a></li><li class="active">'
  4213. '<span class="fa fa-file"></span>&nbsp; sources</li>',
  4214. output_text,
  4215. )
  4216. self.assertIn(
  4217. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  4218. output_text,
  4219. )
  4220. self.assertIn(
  4221. '<textarea rows="5" class="form-control" type="text" '
  4222. 'id="commit_message"\n name="commit_message" '
  4223. 'placeholder="An optional description of the change">'
  4224. "Signed-off-by: pingou <bar@pingou.com></textarea>",
  4225. output_text,
  4226. )
  4227. def test_edit_file(self):
  4228. """ Test the edit_file endpoint. """
  4229. # No Git repo
  4230. output = self.app.get("/foo/edit/foo/f/sources")
  4231. self.assertEqual(output.status_code, 404)
  4232. user = tests.FakeUser()
  4233. with tests.user_set(self.app.application, user):
  4234. # No project registered in the DB
  4235. output = self.app.get("/foo/edit/foo/f/sources")
  4236. self.assertEqual(output.status_code, 404)
  4237. tests.create_projects(self.session)
  4238. tests.create_projects_git(
  4239. os.path.join(self.path, "repos"), bare=True
  4240. )
  4241. # No a repo admin
  4242. output = self.app.get("/test/edit/foo/f/sources")
  4243. self.assertEqual(output.status_code, 403)
  4244. # User not logged in
  4245. output = self.app.get("/test/edit/foo/f/sources")
  4246. self.assertEqual(output.status_code, 302)
  4247. user.username = "pingou"
  4248. with tests.user_set(self.app.application, user):
  4249. # No such file
  4250. output = self.app.get("/test/edit/foo/f/sources")
  4251. self.assertEqual(output.status_code, 404)
  4252. # Add some content to the git repo
  4253. tests.add_content_git_repo(
  4254. os.path.join(self.path, "repos", "test.git")
  4255. )
  4256. tests.add_readme_git_repo(
  4257. os.path.join(self.path, "repos", "test.git")
  4258. )
  4259. tests.add_binary_git_repo(
  4260. os.path.join(self.path, "repos", "test.git"), "test.jpg"
  4261. )
  4262. tests.add_binary_git_repo(
  4263. os.path.join(self.path, "repos", "test.git"), "test_binary"
  4264. )
  4265. output = self.app.get("/test/edit/master/foofile")
  4266. self.assertEqual(output.status_code, 404)
  4267. # Edit page
  4268. output = self.app.get("/test/edit/master/f/sources")
  4269. self.assertEqual(output.status_code, 200)
  4270. output_text = output.get_data(as_text=True)
  4271. self.assertIn(
  4272. '<li><a href="/test/tree/master"><span class="fa fa-random">'
  4273. '</span>&nbsp; master</a></li><li class="active">'
  4274. '<span class="fa fa-file"></span>&nbsp; sources</li>',
  4275. output_text,
  4276. )
  4277. self.assertIn(
  4278. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  4279. output_text,
  4280. )
  4281. # Verify the nav links correctly when editing a file.
  4282. output = self.app.get("/test/blob/master/f/folder1/folder2/file")
  4283. self.assertEqual(output.status_code, 200)
  4284. output_text = output.get_data(as_text=True)
  4285. self.assertIn(
  4286. '<li class="breadcrumb-item"><a href="/test/blob/master/f/folder1/folder2">'
  4287. '\n <span class="fa fa-folder"></span>&nbsp; folder2</a>\n'
  4288. " </li>",
  4289. output_text,
  4290. )
  4291. csrf_token = output_text.split(
  4292. 'name="csrf_token" type="hidden" value="'
  4293. )[1].split('">')[0]
  4294. # View what's supposed to be an image
  4295. output = self.app.get("/test/edit/master/f/test.jpg")
  4296. self.assertEqual(output.status_code, 400)
  4297. output_text = output.get_data(as_text=True)
  4298. self.assertIn("<p>Cannot edit binary files</p>", output_text)
  4299. # Check file before the commit:
  4300. output = self.app.get("/test/raw/master/f/sources")
  4301. self.assertEqual(output.status_code, 200)
  4302. output_text = output.get_data(as_text=True)
  4303. self.assertEqual(output_text, "foo\n bar")
  4304. # No CSRF Token
  4305. data = {
  4306. "content": "foo\n bar\n baz",
  4307. "commit_title": "test commit",
  4308. "commit_message": "Online commits from the gure.lib.get",
  4309. }
  4310. output = self.app.post("/test/edit/master/f/sources", data=data)
  4311. self.assertEqual(output.status_code, 200)
  4312. output_text = output.get_data(as_text=True)
  4313. self.assertIn("<title>Edit - test - Pagure</title>", output_text)
  4314. # Check that nothing changed
  4315. output = self.app.get("/test/raw/master/f/sources")
  4316. self.assertEqual(output.status_code, 200)
  4317. output_text = output.get_data(as_text=True)
  4318. self.assertEqual(output_text, "foo\n bar")
  4319. # Missing email
  4320. data["csrf_token"] = csrf_token
  4321. output = self.app.post("/test/edit/master/f/sources", data=data)
  4322. self.assertEqual(output.status_code, 200)
  4323. output_text = output.get_data(as_text=True)
  4324. self.assertIn("<title>Edit - test - Pagure</title>", output_text)
  4325. # Invalid email
  4326. data["email"] = "pingou@fp.o"
  4327. output = self.app.post("/test/edit/master/f/sources", data=data)
  4328. output_text = output.get_data(as_text=True)
  4329. self.assertIn("<title>Edit - test - Pagure</title>", output_text)
  4330. # Works
  4331. data["email"] = "bar@pingou.com"
  4332. data["branch"] = "master"
  4333. output = self.app.post(
  4334. "/test/edit/master/f/sources", data=data, follow_redirects=True
  4335. )
  4336. self.assertEqual(output.status_code, 200)
  4337. output_text = output.get_data(as_text=True)
  4338. self.assertIn(
  4339. "<title>Commits - test - Pagure</title>", output_text
  4340. )
  4341. self.assertIn("test commit", output_text)
  4342. # Check file after the commit:
  4343. output = self.app.get("/test/raw/master/f/sources")
  4344. self.assertEqual(output.status_code, 200)
  4345. output_text = output.get_data(as_text=True)
  4346. self.assertEqual(output_text, "foo\n bar\n baz")
  4347. # Add a fork of a fork
  4348. item = pagure.lib.model.Project(
  4349. user_id=1, # pingou
  4350. name="test3",
  4351. description="test project #3",
  4352. is_fork=True,
  4353. parent_id=1,
  4354. hook_token="aaabbbppp",
  4355. )
  4356. self.session.add(item)
  4357. self.session.commit()
  4358. tests.add_content_git_repo(
  4359. os.path.join(
  4360. self.path, "repos", "forks", "pingou", "test3.git"
  4361. )
  4362. )
  4363. tests.add_readme_git_repo(
  4364. os.path.join(
  4365. self.path, "repos", "forks", "pingou", "test3.git"
  4366. )
  4367. )
  4368. tests.add_commit_git_repo(
  4369. os.path.join(
  4370. self.path, "repos", "forks", "pingou", "test3.git"
  4371. ),
  4372. ncommits=10,
  4373. )
  4374. # Verify the nav links correctly when editing a file in a fork.
  4375. output = self.app.get(
  4376. "/fork/pingou/test3/edit/master/f/folder1/folder2/file"
  4377. )
  4378. self.assertEqual(output.status_code, 200)
  4379. output_text = output.get_data(as_text=True)
  4380. self.assertIn(
  4381. '<li><a\n href="/fork/pingou/test3/blob/master/f/folder1/folder2"\n'
  4382. ' ><span class="fa fa-folder"></span>&nbsp; folder2</a>\n'
  4383. " </li>",
  4384. output_text,
  4385. )
  4386. output = self.app.get("/fork/pingou/test3/edit/master/f/sources")
  4387. self.assertEqual(output.status_code, 200)
  4388. output_text = output.get_data(as_text=True)
  4389. self.assertIn(
  4390. '<li><a href="/fork/pingou/test3/tree/master">'
  4391. '<span class="fa fa-random">'
  4392. '</span>&nbsp; master</a></li><li class="active">'
  4393. '<span class="fa fa-file"></span>&nbsp; sources</li>',
  4394. output_text,
  4395. )
  4396. self.assertIn(
  4397. '<textarea id="textareaCode" name="content">foo\n barRow 0\n',
  4398. output_text,
  4399. )
  4400. # Empty the file - no `content` provided
  4401. data = {
  4402. "commit_title": "test commit",
  4403. "commit_message": "Online commits from the gure.lib.get",
  4404. "csrf_token": csrf_token,
  4405. "email": "bar@pingou.com",
  4406. "branch": "master",
  4407. }
  4408. output = self.app.post(
  4409. "/test/edit/master/f/sources", data=data, follow_redirects=True
  4410. )
  4411. self.assertEqual(output.status_code, 200)
  4412. output_text = output.get_data(as_text=True)
  4413. self.assertIn(
  4414. "<title>Commits - test - Pagure</title>", output_text
  4415. )
  4416. self.assertIn("test commit", output_text)
  4417. # Check file after the commit:
  4418. output = self.app.get("/test/raw/master/f/sources")
  4419. self.assertEqual(output.status_code, 404)
  4420. output_text = output.get_data(as_text=True)
  4421. self.assertIn("<p>No content found</p>", output_text)
  4422. def test_edit_file_default_email(self):
  4423. """ Test the default email shown by the edit_file endpoint. """
  4424. tests.create_projects(self.session)
  4425. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4426. # Add some content to the git repo
  4427. tests.add_content_git_repo(
  4428. os.path.join(self.path, "repos", "test.git")
  4429. )
  4430. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  4431. user = pagure.lib.query.search_user(self.session, username="pingou")
  4432. self.assertEquals(len(user.emails), 2)
  4433. self.assertEquals(user.default_email, "bar@pingou.com")
  4434. user = tests.FakeUser(username="pingou")
  4435. with tests.user_set(self.app.application, user):
  4436. # Edit page
  4437. output = self.app.get("/test/edit/master/f/sources")
  4438. self.assertEqual(output.status_code, 200)
  4439. output_text = output.get_data(as_text=True)
  4440. self.assertIn(
  4441. '<li><a href="/test/tree/master"><span class="fa fa-random">'
  4442. '</span>&nbsp; master</a></li><li class="active">'
  4443. '<span class="fa fa-file"></span>&nbsp; sources</li>',
  4444. output_text,
  4445. )
  4446. self.assertIn(
  4447. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  4448. output_text,
  4449. )
  4450. self.assertIn(
  4451. '<option value="bar@pingou.com" selected>bar@pingou.com'
  4452. "</option>",
  4453. output_text,
  4454. )
  4455. self.assertIn(
  4456. '<option value="foo@pingou.com" >foo@pingou.com</option>',
  4457. output_text,
  4458. )
  4459. @patch("pagure.decorators.admin_session_timedout")
  4460. def test_change_ref_head(self, ast):
  4461. """ Test the change_ref_head endpoint. """
  4462. ast.return_value = True
  4463. # No Git repo
  4464. output = self.app.post("/foo/default/branch/")
  4465. self.assertEqual(output.status_code, 404)
  4466. user = tests.FakeUser()
  4467. with tests.user_set(self.app.application, user):
  4468. output = self.app.post("/foo/default/branch/")
  4469. self.assertEqual(output.status_code, 404)
  4470. ast.return_value = False
  4471. output = self.app.post("/foo/default/branch/")
  4472. self.assertEqual(output.status_code, 404)
  4473. tests.create_projects(self.session)
  4474. repos = tests.create_projects_git(os.path.join(self.path, "repos"))
  4475. output = self.app.post("/test/default/branch/")
  4476. self.assertEqual(output.status_code, 403)
  4477. # User no logged in
  4478. output = self.app.post("/test/default/branch/")
  4479. self.assertEqual(output.status_code, 302)
  4480. user.username = "pingou"
  4481. with tests.user_set(self.app.application, user):
  4482. output = self.app.post(
  4483. "/test/default/branch/", follow_redirects=True
  4484. ) # without git branch
  4485. self.assertEqual(output.status_code, 200)
  4486. output_text = output.get_data(as_text=True)
  4487. self.assertIn(
  4488. "<title>Settings - test - Pagure</title>", output_text
  4489. )
  4490. self.assertIn(
  4491. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  4492. output_text,
  4493. )
  4494. if self.get_wtforms_version() >= (2, 2):
  4495. self.assertIn(
  4496. '<select class="c-select" id="branches" name="branches" '
  4497. "required></select>",
  4498. output_text,
  4499. )
  4500. else:
  4501. self.assertIn(
  4502. '<select class="c-select" id="branches" name="branches">'
  4503. "</select>",
  4504. output_text,
  4505. )
  4506. csrf_token = output_text.split(
  4507. 'name="csrf_token" type="hidden" value="'
  4508. )[1].split('">')[0]
  4509. repo_obj = pygit2.Repository(repos[0])
  4510. tree = repo_obj.index.write_tree()
  4511. author = pygit2.Signature("Alice Author", "alice@authors.tld")
  4512. committer = pygit2.Signature(
  4513. "Cecil Committer", "cecil@committers.tld"
  4514. )
  4515. repo_obj.create_commit(
  4516. "refs/heads/master", # the name of the reference to update
  4517. author,
  4518. committer,
  4519. "Add sources file for testing",
  4520. # binary string representing the tree object ID
  4521. tree,
  4522. # list of binary strings representing parents of the new commit
  4523. [],
  4524. )
  4525. repo_obj.create_branch("feature", repo_obj.head.peel())
  4526. data = {"branches": "feature", "csrf_token": csrf_token}
  4527. # changing head to feature branch
  4528. output = self.app.post(
  4529. "/test/default/branch/", data=data, follow_redirects=True
  4530. )
  4531. self.assertEqual(output.status_code, 200)
  4532. output_text = output.get_data(as_text=True)
  4533. self.assertIn(
  4534. "<title>Settings - test - Pagure</title>", output_text
  4535. )
  4536. self.assertIn(
  4537. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  4538. output_text,
  4539. )
  4540. if self.get_wtforms_version() >= (2, 2):
  4541. self.assertIn(
  4542. '<select class="c-select" id="branches" name="branches" '
  4543. "required>"
  4544. '<option selected value="feature">feature</option>'
  4545. '<option value="master">master</option>'
  4546. "</select>",
  4547. output_text,
  4548. )
  4549. else:
  4550. self.assertIn(
  4551. '<select class="c-select" id="branches" name="branches">'
  4552. '<option selected value="feature">feature</option>'
  4553. '<option value="master">master</option>'
  4554. "</select>",
  4555. output_text,
  4556. )
  4557. self.assertIn("Default branch updated " "to feature", output_text)
  4558. data = {"branches": "master", "csrf_token": csrf_token}
  4559. # changing head to master branch
  4560. output = self.app.post(
  4561. "/test/default/branch/", data=data, follow_redirects=True
  4562. )
  4563. self.assertEqual(output.status_code, 200)
  4564. output_text = output.get_data(as_text=True)
  4565. self.assertIn(
  4566. "<title>Settings - test - Pagure</title>", output_text
  4567. )
  4568. self.assertIn(
  4569. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  4570. output_text,
  4571. )
  4572. if self.get_wtforms_version() >= (2, 2):
  4573. self.assertIn(
  4574. '<select class="c-select" id="branches" name="branches" '
  4575. "required>"
  4576. '<option value="feature">feature</option>'
  4577. '<option selected value="master">master</option>'
  4578. "</select>",
  4579. output_text,
  4580. )
  4581. else:
  4582. self.assertIn(
  4583. '<select class="c-select" id="branches" name="branches">'
  4584. '<option value="feature">feature</option>'
  4585. '<option selected value="master">master</option>'
  4586. "</select>",
  4587. output_text,
  4588. )
  4589. self.assertIn("Default branch updated " "to master", output_text)
  4590. def test_new_release(self):
  4591. """ Test the new_release endpoint. """
  4592. # No Git repo
  4593. output = self.app.post("/foo/upload/")
  4594. self.assertEqual(output.status_code, 404)
  4595. user = tests.FakeUser()
  4596. with tests.user_set(self.app.application, user):
  4597. output = self.app.post("/foo/upload/")
  4598. self.assertEqual(output.status_code, 404)
  4599. tests.create_projects(self.session)
  4600. repo = tests.create_projects_git(os.path.join(self.path, "repos"))
  4601. output = self.app.post("/test/upload/")
  4602. self.assertEqual(output.status_code, 403)
  4603. # User not logged in
  4604. output = self.app.post("/test/upload/")
  4605. self.assertEqual(output.status_code, 302)
  4606. user.username = "pingou"
  4607. with tests.user_set(self.app.application, user):
  4608. img = os.path.join(
  4609. os.path.abspath(os.path.dirname(__file__)), "placebo.png"
  4610. )
  4611. # Missing CSRF Token
  4612. with open(img, mode="rb") as stream:
  4613. data = {"filestream": stream}
  4614. output = self.app.post("/test/upload/", data=data)
  4615. self.assertEqual(output.status_code, 200)
  4616. output_text = output.get_data(as_text=True)
  4617. self.assertIn("<h2>Upload a new release</h2>", output_text)
  4618. csrf_token = output_text.split(
  4619. 'name="csrf_token" type="hidden" value="'
  4620. )[1].split('">')[0]
  4621. upload_dir = os.path.join(self.path, "releases")
  4622. self.assertEqual(os.listdir(upload_dir), [])
  4623. # Upload successful
  4624. with open(img, mode="rb") as stream:
  4625. data = {"filestream": stream, "csrf_token": csrf_token}
  4626. output = self.app.post(
  4627. "/test/upload/", data=data, follow_redirects=True
  4628. )
  4629. self.assertEqual(output.status_code, 200)
  4630. output_text = output.get_data(as_text=True)
  4631. self.assertIn("File", output_text)
  4632. self.assertIn("uploaded", output_text)
  4633. self.assertIn("This project has not been tagged.", output_text)
  4634. self.assertEqual(os.listdir(upload_dir), ["test"])
  4635. folder = os.path.join(upload_dir, "test")
  4636. checksum_file = os.path.join(folder, "CHECKSUMS")
  4637. # Check the checksums file
  4638. self.assertTrue(os.path.exists(checksum_file))
  4639. self.assertEqual(len(os.listdir(folder)), 2)
  4640. # Check the content of the checksums file
  4641. with open(checksum_file) as stream:
  4642. data = stream.readlines()
  4643. self.assertEqual(len(data), 3)
  4644. self.assertEqual(data[0], "# Generated and updated by pagure\n")
  4645. self.assertTrue(data[1].startswith("SHA256 ("))
  4646. self.assertTrue(
  4647. data[1].endswith(
  4648. "tests_placebo.png) = 8a06845923010b27bfd8e7e75acff"
  4649. "7badc40d1021b4994e01f5e11ca40bc3abe\n"
  4650. )
  4651. )
  4652. self.assertTrue(data[2].startswith("SHA512 ("))
  4653. self.assertTrue(
  4654. data[2].endswith(
  4655. "tests_placebo.png) = 65a4458df0acb29dc3c5ad4a3620e"
  4656. "98841d1fcf3f8df358f5348fdeddd1a86706491ac6e416768e"
  4657. "9f218aae8147d6ac524a59d3eb91fb925fdcb5c489e55ccbb\n"
  4658. )
  4659. )
  4660. # Try uploading the same file -- fails
  4661. with open(img, mode="rb") as stream:
  4662. data = {"filestream": stream, "csrf_token": csrf_token}
  4663. output = self.app.post(
  4664. "/test/upload/", data=data, follow_redirects=True
  4665. )
  4666. self.assertEqual(output.status_code, 200)
  4667. output_text = output.get_data(as_text=True)
  4668. self.assertIn(
  4669. "This tarball has already " "been uploaded", output_text
  4670. )
  4671. self.assertIn("This project has not been tagged.", output_text)
  4672. def test_new_release_two_files(self):
  4673. """ Test the new_release endpoint when uploading two files. """
  4674. tests.create_projects(self.session)
  4675. repo = tests.create_projects_git(os.path.join(self.path, "repos"))
  4676. user = tests.FakeUser(username="pingou")
  4677. with tests.user_set(self.app.application, user):
  4678. img = os.path.join(
  4679. os.path.abspath(os.path.dirname(__file__)), "placebo.png"
  4680. )
  4681. img2 = os.path.join(
  4682. os.path.abspath(os.path.dirname(__file__)), "pagure.png"
  4683. )
  4684. csrf_token = self.get_csrf()
  4685. upload_dir = os.path.join(self.path, "releases")
  4686. self.assertEqual(os.listdir(upload_dir), [])
  4687. # Upload successful
  4688. with open(img, mode="rb") as stream:
  4689. with open(img2, mode="rb") as stream2:
  4690. data = {
  4691. "filestream": [stream, stream2],
  4692. "csrf_token": csrf_token,
  4693. }
  4694. output = self.app.post(
  4695. "/test/upload/", data=data, follow_redirects=True
  4696. )
  4697. self.assertEqual(output.status_code, 200)
  4698. output_text = output.get_data(as_text=True)
  4699. self.assertIn(
  4700. '<i class="fa fa-fw fa-info-circle"></i> File', output_text
  4701. )
  4702. self.assertIn("pagure.png&#34; uploaded</div>\n", output_text)
  4703. # self.assertTrue(0)
  4704. self.assertEqual(os.listdir(upload_dir), ["test"])
  4705. folder = os.path.join(upload_dir, "test")
  4706. checksum_file = os.path.join(folder, "CHECKSUMS")
  4707. # Check the checksums file
  4708. self.assertTrue(os.path.exists(checksum_file))
  4709. self.assertEqual(len(os.listdir(folder)), 3)
  4710. # Check the content of the checksums file
  4711. with open(checksum_file) as stream:
  4712. data = stream.readlines()
  4713. self.assertEqual(len(data), 5)
  4714. self.assertEqual(data[0], "# Generated and updated by pagure\n")
  4715. self.assertTrue(data[1].startswith("SHA256 ("))
  4716. self.assertTrue(
  4717. data[1].endswith(
  4718. "tests_placebo.png) = 8a06845923010b27bfd8e7e75acff"
  4719. "7badc40d1021b4994e01f5e11ca40bc3abe\n"
  4720. )
  4721. )
  4722. self.assertTrue(data[2].startswith("SHA512 ("))
  4723. self.assertTrue(
  4724. data[2].endswith(
  4725. "tests_placebo.png) = 65a4458df0acb29dc3c5ad4a3620e"
  4726. "98841d1fcf3f8df358f5348fdeddd1a86706491ac6e416768e"
  4727. "9f218aae8147d6ac524a59d3eb91fb925fdcb5c489e55ccbb\n"
  4728. )
  4729. )
  4730. self.assertTrue(data[3].startswith("SHA256 ("))
  4731. self.assertTrue(
  4732. data[3].endswith(
  4733. "tests_pagure.png) = 6498a2de405546200b6144da56fc25"
  4734. "d0a3976ae688dbfccaca609c8b4480523e\n"
  4735. )
  4736. )
  4737. self.assertTrue(data[4].startswith("SHA512 ("))
  4738. self.assertTrue(
  4739. data[4].endswith(
  4740. "tests_pagure.png) = 15458775e5d73cd74de7da7224597f6"
  4741. "7f8b23d62d3affb8abba4f5db74d33235642a0f744de2265cca7"
  4742. "d2b5866782c45e1fdeb32dd2822ae33e97995d4879afd\n"
  4743. )
  4744. )
  4745. @patch("pagure.decorators.admin_session_timedout")
  4746. def test_add_token_all_tokens(self, ast):
  4747. """ Test the add_token endpoint. """
  4748. ast.return_value = False
  4749. tests.create_projects(self.session)
  4750. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4751. user = tests.FakeUser(username="pingou")
  4752. with tests.user_set(self.app.application, user):
  4753. output = self.app.get("/test/token/new/")
  4754. self.assertEqual(output.status_code, 200)
  4755. output_text = output.get_data(as_text=True)
  4756. self.assertIn("<strong>Create a new token</strong>", output_text)
  4757. self.assertEqual(
  4758. output_text.count('<label class="c-input c-checkbox">'),
  4759. len(pagure.config.config["ACLS"].keys()) - 2,
  4760. )
  4761. @patch.dict("pagure.config.config", {"USER_ACLS": ["create_project"]})
  4762. @patch("pagure.decorators.admin_session_timedout")
  4763. def test_add_token_one_token(self, ast):
  4764. """ Test the add_token endpoint. """
  4765. ast.return_value = False
  4766. tests.create_projects(self.session)
  4767. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  4768. user = tests.FakeUser(username="pingou")
  4769. with tests.user_set(self.app.application, user):
  4770. output = self.app.get("/test/token/new/")
  4771. self.assertEqual(output.status_code, 200)
  4772. output_text = output.get_data(as_text=True)
  4773. self.assertIn("<strong>Create a new token</strong>", output_text)
  4774. self.assertEqual(
  4775. output_text.count('<label class="c-input c-checkbox">'), 1
  4776. )
  4777. @patch("pagure.decorators.admin_session_timedout")
  4778. def test_add_token(self, ast):
  4779. """ Test the add_token endpoint. """
  4780. ast.return_value = False
  4781. # No Git repo
  4782. output = self.app.get("/foo/token/new/")
  4783. self.assertEqual(output.status_code, 404)
  4784. user = tests.FakeUser()
  4785. with tests.user_set(self.app.application, user):
  4786. output = self.app.get("/foo/token/new/")
  4787. self.assertEqual(output.status_code, 404)
  4788. tests.create_projects(self.session)
  4789. tests.create_projects_git(
  4790. os.path.join(self.path, "repos"), bare=True
  4791. )
  4792. output = self.app.get("/test/token/new/")
  4793. self.assertEqual(output.status_code, 403)
  4794. # User not logged in
  4795. output = self.app.get("/test/token/new/")
  4796. self.assertEqual(output.status_code, 302)
  4797. user.username = "pingou"
  4798. with tests.user_set(self.app.application, user):
  4799. output = self.app.get("/test/token/new/")
  4800. self.assertEqual(output.status_code, 200)
  4801. output_text = output.get_data(as_text=True)
  4802. self.assertIn("<strong>Create a new token</strong>", output_text)
  4803. csrf_token = output_text.split(
  4804. 'name="csrf_token" type="hidden" value="'
  4805. )[1].split('">')[0]
  4806. data = {"csrf_token": csrf_token}
  4807. ast.return_value = True
  4808. # Test when the session timed-out
  4809. output = self.app.post("/test/token/new/", data=data)
  4810. self.assertEqual(output.status_code, 302)
  4811. output = self.app.get("/", follow_redirects=True)
  4812. self.assertEqual(output.status_code, 200)
  4813. output_text = output.get_data(as_text=True)
  4814. self.assertIn("Action canceled, try it " "again", output_text)
  4815. ast.return_value = False
  4816. # Missing acls
  4817. output = self.app.post("/test/token/new/", data=data)
  4818. self.assertEqual(output.status_code, 200)
  4819. output_text = output.get_data(as_text=True)
  4820. self.assertIn("<strong>Create a new token</strong>", output_text)
  4821. self.assertIn(
  4822. "You must select at least " "one permission.", output_text
  4823. )
  4824. data = {
  4825. "csrf_token": csrf_token,
  4826. "acls": ["issue_create"],
  4827. "description": "Test token",
  4828. }
  4829. # New token created
  4830. output = self.app.post(
  4831. "/test/token/new/", data=data, follow_redirects=True
  4832. )
  4833. self.assertEqual(output.status_code, 200)
  4834. output_text = output.get_data(as_text=True)
  4835. self.assertIn("Token created", output_text)
  4836. self.assertIn(
  4837. "<title>Settings - test - Pagure</title>", output_text
  4838. )
  4839. self.assertIn(
  4840. '<h5 class="pl-2 font-weight-bold text-muted">Project Settings</h5>',
  4841. output_text,
  4842. )
  4843. self.assertIn("<strong> Test token</strong>", output_text)
  4844. self.assertIn(
  4845. '<small class="font-weight-bold">Active until', output_text
  4846. )
  4847. @patch("pagure.decorators.admin_session_timedout")
  4848. def test_revoke_api_token(self, ast):
  4849. """ Test the revoke_api_token endpoint. """
  4850. ast.return_value = False
  4851. # No Git repo
  4852. output = self.app.post("/foo/token/revoke/123")
  4853. self.assertEqual(output.status_code, 404)
  4854. user = tests.FakeUser()
  4855. with tests.user_set(self.app.application, user):
  4856. output = self.app.post("/foo/token/revoke/123")
  4857. self.assertEqual(output.status_code, 404)
  4858. tests.create_projects(self.session)
  4859. tests.create_projects_git(
  4860. os.path.join(self.path, "repos"), bare=True
  4861. )
  4862. output = self.app.post("/test/token/revoke/123")
  4863. self.assertEqual(output.status_code, 403)
  4864. # User not logged in
  4865. output = self.app.post("/test/token/revoke/123")
  4866. self.assertEqual(output.status_code, 302)
  4867. user.username = "pingou"
  4868. with tests.user_set(self.app.application, user):
  4869. output = self.app.get("/test/token/new")
  4870. self.assertEqual(output.status_code, 200)
  4871. output_text = output.get_data(as_text=True)
  4872. self.assertIn("<strong>Create a new token</strong>", output_text)
  4873. csrf_token = output_text.split(
  4874. 'name="csrf_token" type="hidden" value="'
  4875. )[1].split('">')[0]
  4876. data = {"csrf_token": csrf_token}
  4877. ast.return_value = True
  4878. # Test when the session timed-out
  4879. output = self.app.post("/test/token/revoke/123", data=data)
  4880. self.assertEqual(output.status_code, 302)
  4881. output = self.app.get("/", follow_redirects=True)
  4882. self.assertEqual(output.status_code, 200)
  4883. output_text = output.get_data(as_text=True)
  4884. self.assertIn("Action canceled, try it again", output_text)
  4885. ast.return_value = False
  4886. output = self.app.post("/test/token/revoke/123", data=data)
  4887. self.assertEqual(output.status_code, 404)
  4888. output_text = output.get_data(as_text=True)
  4889. self.assertIn("<p>Token not found</p>", output_text)
  4890. # Create a token to revoke
  4891. data = {"csrf_token": csrf_token, "acls": ["issue_create"]}
  4892. output = self.app.post(
  4893. "/test/token/new/", data=data, follow_redirects=True
  4894. )
  4895. self.assertEqual(output.status_code, 200)
  4896. output_text = output.get_data(as_text=True)
  4897. self.assertIn("Token created", output_text)
  4898. # Existing token will expire in 60 days
  4899. repo = pagure.lib.query.get_authorized_project(
  4900. self.session, "test"
  4901. )
  4902. self.assertEqual(
  4903. repo.tokens[0].expiration.date(),
  4904. datetime.datetime.utcnow().date()
  4905. + datetime.timedelta(days=(30 * 6)),
  4906. )
  4907. token = repo.tokens[0].id
  4908. output = self.app.post(
  4909. "/test/token/revoke/%s" % token,
  4910. data=data,
  4911. follow_redirects=True,
  4912. )
  4913. output_text = output.get_data(as_text=True)
  4914. self.assertIn(
  4915. "<title>Settings - test - Pagure</title>", output_text
  4916. )
  4917. self.assertIn("Token revoked", output_text)
  4918. self.assertEqual(output_text.count('title="Revoke token">'), 0)
  4919. self.assertEqual(output_text.count('title="Renew token">'), 1)
  4920. # Existing token has been expired
  4921. self.session.commit()
  4922. repo = pagure.lib.query.get_authorized_project(
  4923. self.session, "test"
  4924. )
  4925. self.assertEqual(
  4926. repo.tokens[0].expiration.date(), repo.tokens[0].created.date()
  4927. )
  4928. self.assertEqual(
  4929. repo.tokens[0].expiration.date(),
  4930. datetime.datetime.utcnow().date(),
  4931. )
  4932. @patch("pagure.decorators.admin_session_timedout")
  4933. def test_renew_api_token(self, ast):
  4934. """ Test the renew_api_token endpoint. """
  4935. ast.return_value = False
  4936. # No Git repo
  4937. output = self.app.post("/foo/token/renew/123")
  4938. self.assertEqual(output.status_code, 404)
  4939. user = tests.FakeUser()
  4940. with tests.user_set(self.app.application, user):
  4941. # user logged in but still no git repo
  4942. output = self.app.post("/foo/token/renew/123")
  4943. self.assertEqual(output.status_code, 404)
  4944. tests.create_projects(self.session)
  4945. tests.create_projects_git(
  4946. os.path.join(self.path, "repos"), bare=True
  4947. )
  4948. # user logged in, git repo present, but user doesn't have access
  4949. output = self.app.post("/test/token/renew/123")
  4950. self.assertEqual(output.status_code, 403)
  4951. # User not logged in
  4952. output = self.app.post("/test/token/renew/123")
  4953. self.assertEqual(output.status_code, 302)
  4954. user.username = "pingou"
  4955. with tests.user_set(self.app.application, user):
  4956. output = self.app.get("/test/token/new")
  4957. self.assertEqual(output.status_code, 200)
  4958. output_text = output.get_data(as_text=True)
  4959. self.assertIn("<strong>Create a new token</strong>", output_text)
  4960. csrf_token = self.get_csrf(output=output)
  4961. data = {"csrf_token": csrf_token}
  4962. ast.return_value = True
  4963. # Test when the session timed-out
  4964. output = self.app.post("/test/token/renew/123", data=data)
  4965. self.assertEqual(output.status_code, 302)
  4966. output = self.app.get("/", follow_redirects=True)
  4967. self.assertEqual(output.status_code, 200)
  4968. output_text = output.get_data(as_text=True)
  4969. self.assertIn("Action canceled, try it again", output_text)
  4970. ast.return_value = False
  4971. output = self.app.post("/test/token/renew/123", data=data)
  4972. self.assertEqual(output.status_code, 404)
  4973. output_text = output.get_data(as_text=True)
  4974. self.assertIn("<p>Token not found</p>", output_text)
  4975. # Create a token to renew
  4976. data = {"csrf_token": csrf_token, "acls": ["issue_create"]}
  4977. output = self.app.post(
  4978. "/test/token/new/", data=data, follow_redirects=True
  4979. )
  4980. self.assertEqual(output.status_code, 200)
  4981. output_text = output.get_data(as_text=True)
  4982. self.assertIn("Token created", output_text)
  4983. # 1 token associated with the project, expires in 60 days
  4984. repo = pagure.lib.query.get_authorized_project(
  4985. self.session, "test"
  4986. )
  4987. self.assertEqual(len(repo.tokens), 1)
  4988. self.assertEqual(
  4989. repo.tokens[0].expiration.date(),
  4990. datetime.datetime.utcnow().date()
  4991. + datetime.timedelta(days=(30 * 6)),
  4992. )
  4993. token = repo.tokens[0].id
  4994. output = self.app.post(
  4995. "/test/token/renew/%s" % token,
  4996. data=data,
  4997. follow_redirects=True,
  4998. )
  4999. output_text = output.get_data(as_text=True)
  5000. self.assertIn(
  5001. "<title>Settings - test - Pagure</title>", output_text
  5002. )
  5003. self.assertIn("Token created", output_text)
  5004. self.assertEqual(output_text.count('title="Revoke token">'), 2)
  5005. self.assertEqual(output_text.count('title="Renew token">'), 2)
  5006. # Existing token has been renewed
  5007. self.session.commit()
  5008. repo = pagure.lib.query.get_authorized_project(
  5009. self.session, "test"
  5010. )
  5011. self.assertEqual(len(repo.tokens), 2)
  5012. self.assertEqual(
  5013. repo.tokens[0].expiration.date(),
  5014. repo.tokens[1].expiration.date(),
  5015. )
  5016. self.assertEqual(
  5017. repo.tokens[0].created.date(), repo.tokens[1].created.date()
  5018. )
  5019. self.assertEqual(repo.tokens[0].acls, repo.tokens[1].acls)
  5020. self.assertEqual(
  5021. repo.tokens[0].description, repo.tokens[1].description
  5022. )
  5023. def test_delete_branch(self):
  5024. """ Test the delete_branch endpoint. """
  5025. # No Git repo
  5026. output = self.app.post("/foo/b/master/delete")
  5027. self.assertEqual(output.status_code, 404)
  5028. tests.create_projects(self.session)
  5029. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5030. # User not logged in
  5031. output = self.app.post("/test/b/master/delete")
  5032. self.assertEqual(output.status_code, 302)
  5033. user = tests.FakeUser()
  5034. with tests.user_set(self.app.application, user):
  5035. # Unknown repo
  5036. output = self.app.post("/foo/b/master/delete")
  5037. self.assertEqual(output.status_code, 404)
  5038. output = self.app.post("/test/b/master/delete")
  5039. self.assertEqual(output.status_code, 403)
  5040. user.username = "pingou"
  5041. with tests.user_set(self.app.application, user):
  5042. output = self.app.post("/test/b/master/delete")
  5043. self.assertEqual(output.status_code, 403)
  5044. output_text = output.get_data(as_text=True)
  5045. self.assertIn(
  5046. "<p>You are not allowed to delete the master branch</p>",
  5047. output_text,
  5048. )
  5049. output = self.app.post("/test/b/bar/delete")
  5050. self.assertEqual(output.status_code, 404)
  5051. output_text = output.get_data(as_text=True)
  5052. self.assertIn("<p>Branch not found</p>", output_text)
  5053. # Add a branch that we can delete
  5054. path = os.path.join(self.path, "repos", "test.git")
  5055. tests.add_content_git_repo(path)
  5056. repo = pygit2.Repository(path)
  5057. repo.create_branch("foo", repo.head.peel())
  5058. # Check before deletion
  5059. output = self.app.get("/test")
  5060. self.assertEqual(output.status_code, 200)
  5061. output = self.app.get("/test/branches")
  5062. output_text = output.get_data(as_text=True)
  5063. self.assertIn('<form id="delete_branch_form-foo"', output_text)
  5064. # Delete the branch
  5065. output = self.app.post("/test/b/foo/delete", follow_redirects=True)
  5066. self.assertEqual(output.status_code, 200)
  5067. output = self.app.get("/test/branches")
  5068. output_text = output.get_data(as_text=True)
  5069. self.assertNotIn('<form id="delete_branch_form-foo"', output_text)
  5070. # Add a branch with a '/' in its name that we can delete
  5071. path = os.path.join(self.path, "repos", "test.git")
  5072. tests.add_content_git_repo(path)
  5073. repo = pygit2.Repository(path)
  5074. repo.create_branch("feature/foo", repo.head.peel())
  5075. # Check before deletion
  5076. output = self.app.get("/test")
  5077. self.assertEqual(output.status_code, 200)
  5078. output = self.app.get("/test/branches")
  5079. output_text = output.get_data(as_text=True)
  5080. self.assertIn(
  5081. '<form id="delete_branch_form-feature__foo"', output_text
  5082. )
  5083. # Delete the branch
  5084. output = self.app.post(
  5085. "/test/b/feature/foo/delete", follow_redirects=True
  5086. )
  5087. self.assertEqual(output.status_code, 200)
  5088. output = self.app.get("/test/branches")
  5089. output_text = output.get_data(as_text=True)
  5090. self.assertNotIn(
  5091. '<form id="delete_branch_form-feature__foo"', output_text
  5092. )
  5093. def test_delete_branch_unicode(self):
  5094. """ Test the delete_branch endpoint with an unicode branch. """
  5095. tests.create_projects(self.session)
  5096. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5097. user = tests.FakeUser(username="pingou")
  5098. with tests.user_set(self.app.application, user):
  5099. # Add a branch that we can delete
  5100. path = os.path.join(self.path, "repos", "test.git")
  5101. tests.add_content_git_repo(path)
  5102. repo = pygit2.Repository(path)
  5103. branchname = "☃️"
  5104. if six.PY2:
  5105. branchname = branchname.encode("utf-8")
  5106. repo.create_branch(branchname, repo.head.peel())
  5107. # Check before deletion
  5108. output = self.app.get("/test")
  5109. self.assertEqual(output.status_code, 200)
  5110. output = self.app.get("/test/branches")
  5111. output_text = output.get_data(as_text=True)
  5112. self.assertIn('<form id="delete_branch_form-☃️"', output_text)
  5113. # Delete the branch
  5114. output = self.app.post("/test/b/☃️/delete", follow_redirects=True)
  5115. self.assertEqual(output.status_code, 200)
  5116. # Check after deletion
  5117. output = self.app.get("/test/branches")
  5118. output_text = output.get_data(as_text=True)
  5119. self.assertNotIn('<form id="delete_branch_form-☃️"', output_text)
  5120. @patch.dict("pagure.config.config", {"ALLOW_DELETE_BRANCH": False})
  5121. def test_delete_branch_disabled_in_ui(self):
  5122. """ Test that the delete branch button doesn't show when the feature
  5123. is turned off. """
  5124. tests.create_projects(self.session)
  5125. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5126. # Add a branch that we can delete
  5127. path = os.path.join(self.path, "repos", "test.git")
  5128. tests.add_content_git_repo(path)
  5129. repo = pygit2.Repository(path)
  5130. repo.create_branch("foo", repo.head.peel())
  5131. user = tests.FakeUser(username="pingou")
  5132. with tests.user_set(self.app.application, user):
  5133. # Check that the UI doesn't offer the button
  5134. output = self.app.get("/test")
  5135. self.assertEqual(output.status_code, 200)
  5136. output_text = output.get_data(as_text=True)
  5137. self.assertNotIn('<form id="delete_branch_form-foo"', output_text)
  5138. self.assertNotIn(
  5139. "Are you sure you want to remove the branch", output_text
  5140. )
  5141. @patch.dict("pagure.config.config", {"ALLOW_DELETE_BRANCH": False})
  5142. def test_delete_branch_disabled(self):
  5143. """ Test the delete_branch endpoint when it's disabled in the entire
  5144. instance. """
  5145. tests.create_projects(self.session)
  5146. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5147. # Add a branch that we can delete
  5148. path = os.path.join(self.path, "repos", "test.git")
  5149. tests.add_content_git_repo(path)
  5150. repo = pygit2.Repository(path)
  5151. repo.create_branch("foo", repo.head.peel())
  5152. user = tests.FakeUser(username="pingou")
  5153. with tests.user_set(self.app.application, user):
  5154. # Check if the delete branch button does not show
  5155. output = self.app.get("/test/branches")
  5156. self.assertEqual(output.status_code, 200)
  5157. self.assertNotIn(
  5158. 'title="Remove branch foo"', output.get_data(as_text=True)
  5159. )
  5160. # Delete the branch
  5161. output = self.app.post("/test/b/foo/delete", follow_redirects=True)
  5162. self.assertEqual(output.status_code, 404)
  5163. self.assertIn(
  5164. "This pagure instance does not allow branch deletion",
  5165. output.get_data(as_text=True),
  5166. )
  5167. @patch.dict("pagure.config.config", {"ALLOW_DELETE_BRANCH": False})
  5168. def test_delete_branch_disabled_fork(self):
  5169. """ Test the delete_branch endpoint when it's disabled in the entire
  5170. instance. """
  5171. item = pagure.lib.model.Project(
  5172. user_id=2, # foo
  5173. name="test",
  5174. description="test project #1",
  5175. hook_token="aaabbb",
  5176. is_fork=True,
  5177. parent_id=1,
  5178. )
  5179. self.session.add(item)
  5180. self.session.commit()
  5181. tests.create_projects_git(
  5182. os.path.join(self.path, "repos", "forks", "foo"), bare=True
  5183. )
  5184. # Add a branch that we can delete
  5185. path = os.path.join(self.path, "repos", "forks", "foo", "test.git")
  5186. tests.add_content_git_repo(path)
  5187. repo = pygit2.Repository(path)
  5188. repo.create_branch("foo", repo.head.peel())
  5189. user = tests.FakeUser(username="foo")
  5190. with tests.user_set(self.app.application, user):
  5191. # Check if the delete branch button shows
  5192. output = self.app.get("/fork/foo/test/branches")
  5193. self.assertEqual(output.status_code, 200)
  5194. self.assertIn(
  5195. 'title="Remove branch foo"', output.get_data(as_text=True)
  5196. )
  5197. # Delete the branch
  5198. output = self.app.post(
  5199. "/fork/foo/test/b/foo/delete", follow_redirects=True
  5200. )
  5201. self.assertEqual(output.status_code, 200)
  5202. # Check if the delete branch button no longer appears
  5203. output = self.app.get("/fork/foo/test/branches")
  5204. self.assertEqual(output.status_code, 200)
  5205. self.assertNotIn(
  5206. 'title="Remove branch foo"', output.get_data(as_text=True)
  5207. )
  5208. def test_view_docs(self):
  5209. """ Test the view_docs endpoint. """
  5210. output = self.app.get("/docs/foo/")
  5211. # No project registered in the DB
  5212. self.assertEqual(output.status_code, 404)
  5213. tests.create_projects(self.session)
  5214. output = self.app.get("/docs/test/")
  5215. # No git repo associated
  5216. self.assertEqual(output.status_code, 404)
  5217. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5218. output = self.app.get("/docs/test/")
  5219. self.assertEqual(output.status_code, 404)
  5220. def test_view_project_activity(self):
  5221. """ Test the view_project_activity endpoint. """
  5222. tests.create_projects(self.session)
  5223. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5224. # Project Exists, but No DATAGREPPER_URL set
  5225. output = self.app.get("/test/activity/")
  5226. self.assertEqual(output.status_code, 404)
  5227. # Project Exists, and DATAGREPPER_URL set
  5228. pagure.config.config["DATAGREPPER_URL"] = "foo"
  5229. output = self.app.get("/test/activity/")
  5230. self.assertEqual(output.status_code, 200)
  5231. output_text = output.get_data(as_text=True)
  5232. self.assertIn("<title>Activity - test - Pagure</title>", output_text)
  5233. self.assertIn("No activity reported on the test project", output_text)
  5234. # project doesnt exist
  5235. output = self.app.get("/foo/activity/")
  5236. self.assertEqual(output.status_code, 404)
  5237. def test_goimport(self):
  5238. """ Test the go-import tag. """
  5239. tests.create_projects(self.session)
  5240. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5241. output = self.app.get("/test/")
  5242. self.assertEqual(output.status_code, 200)
  5243. output_text = output.get_data(as_text=True)
  5244. self.assertIn(
  5245. '<meta name="go-import" '
  5246. 'content="localhost.localdomain/test git git://localhost.localdomain/test.git"'
  5247. ">",
  5248. output_text,
  5249. )
  5250. def test_watch_repo(self):
  5251. """ Test the watch_repo endpoint. """
  5252. output = self.app.post("/watch/")
  5253. self.assertEqual(output.status_code, 405)
  5254. tests.create_projects(self.session)
  5255. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5256. user = tests.FakeUser()
  5257. user.username = "pingou"
  5258. with tests.user_set(self.app.application, user):
  5259. output = self.app.get("/new/")
  5260. self.assertEqual(output.status_code, 200)
  5261. output_text = output.get_data(as_text=True)
  5262. self.assertIn("<strong>Create new Project</strong>", output_text)
  5263. csrf_token = output_text.split(
  5264. 'name="csrf_token" type="hidden" value="'
  5265. )[1].split('">')[0]
  5266. data = {"csrf_token": csrf_token}
  5267. output = self.app.post(
  5268. "/foo/watch/settings/1", data=data, follow_redirects=True
  5269. )
  5270. self.assertEqual(output.status_code, 404)
  5271. output = self.app.post(
  5272. "/test/watch/settings/8", data=data, follow_redirects=True
  5273. )
  5274. self.assertEqual(output.status_code, 400)
  5275. output = self.app.post(
  5276. "/test/watch/settings/0", data=data, follow_redirects=True
  5277. )
  5278. output_text = output.get_data(as_text=True)
  5279. self.assertIn(
  5280. "You are no longer" " watching this project", output_text
  5281. )
  5282. output = self.app.post(
  5283. "/test/watch/settings/1", data=data, follow_redirects=True
  5284. )
  5285. output_text = output.get_data(as_text=True)
  5286. self.assertIn(
  5287. "You are now" " watching issues and PRs on this project",
  5288. output_text,
  5289. )
  5290. output = self.app.post(
  5291. "/test/watch/settings/2", data=data, follow_redirects=True
  5292. )
  5293. output_text = output.get_data(as_text=True)
  5294. self.assertIn(
  5295. "You are now" " watching commits on this project", output_text
  5296. )
  5297. output = self.app.post(
  5298. "/test/watch/settings/3", data=data, follow_redirects=True
  5299. )
  5300. output_text = output.get_data(as_text=True)
  5301. self.assertIn(
  5302. (
  5303. "You are now"
  5304. " watching issues, PRs, and commits on this project"
  5305. ),
  5306. output_text,
  5307. )
  5308. item = pagure.lib.model.Project(
  5309. user_id=2, # foo
  5310. name="test",
  5311. description="foo project #1",
  5312. hook_token="aaabbb",
  5313. is_fork=True,
  5314. parent_id=1,
  5315. )
  5316. self.session.add(item)
  5317. self.session.commit()
  5318. gitrepo = os.path.join(
  5319. self.path, "repos", "forks", "foo", "test.git"
  5320. )
  5321. pygit2.init_repository(gitrepo, bare=True)
  5322. output = self.app.post(
  5323. "/fork/foo/test/watch/settings/-1",
  5324. data=data,
  5325. follow_redirects=True,
  5326. )
  5327. output_text = output.get_data(as_text=True)
  5328. self.assertIn("Watch status is already reset", output_text)
  5329. output = self.app.post(
  5330. "/fork/foo/test/watch/settings/0",
  5331. data=data,
  5332. follow_redirects=True,
  5333. )
  5334. output_text = output.get_data(as_text=True)
  5335. self.assertIn(
  5336. "You are no longer" " watching this project", output_text
  5337. )
  5338. output = self.app.get("/test", data=data, follow_redirects=True)
  5339. output_text = output.get_data(as_text=True)
  5340. self.assertIn(
  5341. (
  5342. '<span class="btn btn-sm btn-primary font-weight-bold">1'
  5343. "</span>\n "
  5344. '<div class="dropdown-menu dropdown-menu-right watch-menu">'
  5345. ),
  5346. output_text,
  5347. )
  5348. output = self.app.post(
  5349. "/fork/foo/test/watch/settings/1",
  5350. data=data,
  5351. follow_redirects=True,
  5352. )
  5353. output_text = output.get_data(as_text=True)
  5354. self.assertIn(
  5355. "You are now" " watching issues and PRs on this project",
  5356. output_text,
  5357. )
  5358. output = self.app.get("/test", data=data, follow_redirects=True)
  5359. output_text = output.get_data(as_text=True)
  5360. self.assertIn(
  5361. (
  5362. '<span class="btn btn-sm btn-primary font-weight-bold">1'
  5363. "</span>\n "
  5364. '<div class="dropdown-menu dropdown-menu-right watch-menu">'
  5365. ),
  5366. output_text,
  5367. )
  5368. output = self.app.post(
  5369. "/fork/foo/test/watch/settings/2",
  5370. data=data,
  5371. follow_redirects=True,
  5372. )
  5373. output_text = output.get_data(as_text=True)
  5374. self.assertIn(
  5375. "You are now" " watching commits on this project", output_text
  5376. )
  5377. output = self.app.post(
  5378. "/fork/foo/test/watch/settings/3",
  5379. data=data,
  5380. follow_redirects=True,
  5381. )
  5382. output_text = output.get_data(as_text=True)
  5383. self.assertIn(
  5384. (
  5385. "You are now"
  5386. " watching issues, PRs, and commits on this project"
  5387. ),
  5388. output_text,
  5389. )
  5390. output = self.app.get("/test", data=data, follow_redirects=True)
  5391. output_text = output.get_data(as_text=True)
  5392. self.assertIn(
  5393. (
  5394. '<span class="btn btn-sm btn-primary font-weight-bold">1'
  5395. "</span>\n "
  5396. '<div class="dropdown-menu dropdown-menu-right watch-menu">'
  5397. ),
  5398. output_text,
  5399. )
  5400. project = pagure.lib.query._get_project(self.session, "test")
  5401. pagure.lib.query.add_user_to_project(
  5402. self.session,
  5403. project,
  5404. new_user="foo",
  5405. user="pingou",
  5406. access="commit",
  5407. )
  5408. self.session.commit()
  5409. output = self.app.get("/test", data=data, follow_redirects=True)
  5410. output_text = output.get_data(as_text=True)
  5411. self.assertIn(
  5412. (
  5413. '<span class="btn btn-sm btn-primary font-weight-bold">2'
  5414. "</span>\n "
  5415. '<div class="dropdown-menu dropdown-menu-right watch-menu">'
  5416. ),
  5417. output_text,
  5418. )
  5419. output = self.app.post(
  5420. "/fork/foo/test/watch/settings/-1",
  5421. data=data,
  5422. follow_redirects=True,
  5423. )
  5424. output_text = output.get_data(as_text=True)
  5425. self.assertIn("Watch status reset", output_text)
  5426. output = self.app.get("/test", data=data, follow_redirects=True)
  5427. output_text = output.get_data(as_text=True)
  5428. self.assertIn(
  5429. (
  5430. '<span class="btn btn-sm btn-primary font-weight-bold">2'
  5431. "</span>\n "
  5432. '<div class="dropdown-menu dropdown-menu-right watch-menu">'
  5433. ),
  5434. output_text,
  5435. )
  5436. def test_delete_report(self):
  5437. """ Test the delete_report endpoint. """
  5438. output = self.app.post("/test/delete/report")
  5439. self.assertEqual(output.status_code, 404)
  5440. tests.create_projects(self.session)
  5441. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5442. user = tests.FakeUser()
  5443. user.username = "pingou"
  5444. with tests.user_set(self.app.application, user):
  5445. output = self.app.get("/new/")
  5446. self.assertEqual(output.status_code, 200)
  5447. output_text = output.get_data(as_text=True)
  5448. self.assertIn("<strong>Create new Project</strong>", output_text)
  5449. csrf_token = output_text.split(
  5450. 'name="csrf_token" type="hidden" value="'
  5451. )[1].split('">')[0]
  5452. # No report specified
  5453. data = {"csrf_token": csrf_token}
  5454. output = self.app.post(
  5455. "/test/delete/report", data=data, follow_redirects=True
  5456. )
  5457. self.assertEqual(output.status_code, 200)
  5458. output_text = output.get_data(as_text=True)
  5459. self.assertIn("Unknown report: None", output_text)
  5460. # Report specified not in the project's reports
  5461. data = {"csrf_token": csrf_token, "report": "foo"}
  5462. output = self.app.post(
  5463. "/test/delete/report", data=data, follow_redirects=True
  5464. )
  5465. self.assertEqual(output.status_code, 200)
  5466. output_text = output.get_data(as_text=True)
  5467. self.assertIn("Unknown report: foo", output_text)
  5468. # Create a report
  5469. project = pagure.lib.query.get_authorized_project(
  5470. self.session, project_name="test"
  5471. )
  5472. self.assertEqual(project.reports, {})
  5473. name = "test report"
  5474. url = "?foo=bar&baz=biz"
  5475. pagure.lib.query.save_report(
  5476. self.session, repo=project, name=name, url=url, username=None
  5477. )
  5478. self.session.commit()
  5479. project = pagure.lib.query.get_authorized_project(
  5480. self.session, project_name="test"
  5481. )
  5482. self.assertEqual(
  5483. project.reports, {"test report": {"baz": "biz", "foo": "bar"}}
  5484. )
  5485. # Missing CSRF
  5486. data = {"report": "test report"}
  5487. output = self.app.post(
  5488. "/test/delete/report", data=data, follow_redirects=True
  5489. )
  5490. self.assertEqual(output.status_code, 200)
  5491. output_text = output.get_data(as_text=True)
  5492. self.assertIn(
  5493. "<title>Settings - test - Pagure</title>", output_text
  5494. )
  5495. project = pagure.lib.query.get_authorized_project(
  5496. self.session, project_name="test"
  5497. )
  5498. self.assertEqual(
  5499. project.reports, {"test report": {"baz": "biz", "foo": "bar"}}
  5500. )
  5501. # Delete the report
  5502. data = {"csrf_token": csrf_token, "report": "test report"}
  5503. output = self.app.post(
  5504. "/test/delete/report", data=data, follow_redirects=True
  5505. )
  5506. self.assertEqual(output.status_code, 200)
  5507. output_text = output.get_data(as_text=True)
  5508. self.assertIn("List of reports updated", output_text)
  5509. self.session.commit()
  5510. project = pagure.lib.query.get_authorized_project(
  5511. self.session, project_name="test"
  5512. )
  5513. self.assertEqual(project.reports, {})
  5514. def test_delete_report_ns_project(self):
  5515. """ Test the delete_report endpoint on a namespaced project. """
  5516. output = self.app.post("/foo/test/delete/report")
  5517. self.assertEqual(output.status_code, 404)
  5518. tests.create_projects(self.session)
  5519. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5520. user = tests.FakeUser()
  5521. user.username = "pingou"
  5522. with tests.user_set(self.app.application, user):
  5523. output = self.app.get("/new/")
  5524. self.assertEqual(output.status_code, 200)
  5525. output_text = output.get_data(as_text=True)
  5526. self.assertIn("<strong>Create new Project</strong>", output_text)
  5527. csrf_token = output_text.split(
  5528. 'name="csrf_token" type="hidden" value="'
  5529. )[1].split('">')[0]
  5530. item = pagure.lib.model.Project(
  5531. user_id=1, # pingou
  5532. namespace="foo",
  5533. name="test",
  5534. description="foo project #2",
  5535. hook_token="aaabbb",
  5536. )
  5537. self.session.add(item)
  5538. self.session.commit()
  5539. gitrepo = os.path.join(self.path, "repos", "foo", "test.git")
  5540. pygit2.init_repository(gitrepo, bare=True)
  5541. # No report specified
  5542. data = {"csrf_token": csrf_token}
  5543. output = self.app.post(
  5544. "/foo/test/delete/report", data=data, follow_redirects=True
  5545. )
  5546. self.assertEqual(output.status_code, 200)
  5547. output_text = output.get_data(as_text=True)
  5548. self.assertIn("Unknown report: None", output_text)
  5549. # Report specified not in the project's reports
  5550. data = {"csrf_token": csrf_token, "report": "foo"}
  5551. output = self.app.post(
  5552. "/foo/test/delete/report", data=data, follow_redirects=True
  5553. )
  5554. self.assertEqual(output.status_code, 200)
  5555. output_text = output.get_data(as_text=True)
  5556. self.assertIn("Unknown report: foo", output_text)
  5557. # Create a report
  5558. self.session.commit()
  5559. project = pagure.lib.query.get_authorized_project(
  5560. self.session, project_name="test", namespace="foo"
  5561. )
  5562. self.assertEqual(project.reports, {})
  5563. name = "test report"
  5564. url = "?foo=bar&baz=biz"
  5565. pagure.lib.query.save_report(
  5566. self.session, repo=project, name=name, url=url, username=None
  5567. )
  5568. self.session.commit()
  5569. project = pagure.lib.query.get_authorized_project(
  5570. self.session, project_name="test", namespace="foo"
  5571. )
  5572. self.assertEqual(
  5573. project.reports, {"test report": {"baz": "biz", "foo": "bar"}}
  5574. )
  5575. # Missing CSRF
  5576. data = {"report": "test report"}
  5577. output = self.app.post(
  5578. "/foo/test/delete/report", data=data, follow_redirects=True
  5579. )
  5580. self.assertEqual(output.status_code, 200)
  5581. output_text = output.get_data(as_text=True)
  5582. self.assertIn(
  5583. "<title>Settings - foo/test - Pagure</title>", output_text
  5584. )
  5585. project = pagure.lib.query.get_authorized_project(
  5586. self.session, project_name="test", namespace="foo"
  5587. )
  5588. self.assertEqual(
  5589. project.reports, {"test report": {"baz": "biz", "foo": "bar"}}
  5590. )
  5591. # Delete the report
  5592. data = {"csrf_token": csrf_token, "report": "test report"}
  5593. output = self.app.post(
  5594. "/foo/test/delete/report", data=data, follow_redirects=True
  5595. )
  5596. self.assertEqual(output.status_code, 200)
  5597. output_text = output.get_data(as_text=True)
  5598. self.assertIn("List of reports updated", output_text)
  5599. self.session.commit()
  5600. project = pagure.lib.query.get_authorized_project(
  5601. self.session, project_name="test", namespace="foo"
  5602. )
  5603. self.assertEqual(project.reports, {})
  5604. def test_open_pr_button_empty_repo(self):
  5605. """ Test "Open Pull-Request" button on empty project. """
  5606. tests.create_projects(self.session)
  5607. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5608. output = self.app.get("/test")
  5609. self.assertEqual(output.status_code, 200)
  5610. output_text = output.get_data(as_text=True)
  5611. self.assertIn("<p>This repo is brand new!</p>", output_text)
  5612. self.assertNotIn(
  5613. 'href="/test/diff/master..master">Open Pull-Request', output_text
  5614. )
  5615. @patch.dict(
  5616. "pagure.config.config",
  5617. {"UPLOAD_FOLDER_PATH": None, "UPLOAD_FOLDER_URL": None},
  5618. )
  5619. def test_releases_upload_folder_vars_None(self):
  5620. """ Test that /releases/ page of a repo displays correctly with
  5621. UPLOAD_FOLDER_PATH and UPLOAD_FOLDER_URL set to None
  5622. """
  5623. tests.create_projects(self.session)
  5624. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  5625. output = self.app.get("/test/releases")
  5626. self.assertEqual(output.status_code, 200)
  5627. self.assertIn(
  5628. "This project has not been tagged.", output.get_data(as_text=True)
  5629. )
  5630. class PagureFlaskRepoTestHooktests(tests.Modeltests):
  5631. """ Tests for the web hook test function """
  5632. def setUp(self):
  5633. """ Set up the environnment, ran before every tests. """
  5634. super(PagureFlaskRepoTestHooktests, self).setUp()
  5635. tests.create_projects(self.session)
  5636. tests.create_projects_git(os.path.join(self.path, "repos"))
  5637. @patch(
  5638. "pagure.decorators.admin_session_timedout",
  5639. MagicMock(return_value=False),
  5640. )
  5641. def test_test_hook_no_project(self):
  5642. """ Test the test_hook endpoint when the project doesn't exist. """
  5643. # No project
  5644. output = self.app.post("/foo/settings/test_hook")
  5645. self.assertEqual(output.status_code, 404)
  5646. @patch(
  5647. "pagure.decorators.admin_session_timedout",
  5648. MagicMock(return_value=False),
  5649. )
  5650. def test_test_hook_existing_project(self):
  5651. """ Test the test_hook endpoint when the project doesn't exist. """
  5652. user = tests.FakeUser()
  5653. with tests.user_set(self.app.application, user):
  5654. output = self.app.post("/test/settings/test_hook")
  5655. self.assertEqual(output.status_code, 403)
  5656. @patch(
  5657. "pagure.decorators.admin_session_timedout",
  5658. MagicMock(return_value=False),
  5659. )
  5660. def test_test_hook_logged_out(self):
  5661. """ Test the test_hook endpoint when the project isn't logged in. """
  5662. # User not logged in
  5663. output = self.app.post("/test/settings/test_hook")
  5664. self.assertEqual(output.status_code, 302)
  5665. @patch(
  5666. "pagure.decorators.admin_session_timedout",
  5667. MagicMock(return_value=False),
  5668. )
  5669. def test_test_hook_logged_in_no_csrf(self):
  5670. """ Test the test_hook endpoint when the user is logged in. """
  5671. user = tests.FakeUser(username="pingou")
  5672. with tests.user_set(self.app.application, user):
  5673. output = self.app.post("/test/settings/test_hook")
  5674. self.assertEqual(output.status_code, 302)
  5675. self.assertEqual(output.status_code, 302)
  5676. @patch(
  5677. "pagure.decorators.admin_session_timedout",
  5678. MagicMock(return_value=False),
  5679. )
  5680. def test_test_hook_logged_in_csrf(self):
  5681. """ Test the test_hook endpoint when the user is logged in. """
  5682. user = tests.FakeUser(username="pingou")
  5683. with tests.user_set(self.app.application, user):
  5684. data = {"csrf_token": self.get_csrf()}
  5685. output = self.app.post("/test/settings/test_hook", data=data)
  5686. self.assertEqual(output.status_code, 302)
  5687. class PagureFlaskRepoTestRegenerateGittests(tests.Modeltests):
  5688. """ Tests for the regenerate git repo function """
  5689. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  5690. @patch(
  5691. "pagure.decorators.admin_session_timedout",
  5692. MagicMock(return_value=False),
  5693. )
  5694. def setUp(self):
  5695. """ Set up the environnment, ran before every tests. """
  5696. super(PagureFlaskRepoTestRegenerateGittests, self).setUp()
  5697. tests.create_projects(self.session)
  5698. tests.create_projects_git(os.path.join(self.path, "repos"))
  5699. user = tests.FakeUser()
  5700. with tests.user_set(self.app.application, user):
  5701. self.csrf_token = self.get_csrf()
  5702. def test_regenerate_git_invalid_project(self):
  5703. """ Test the regenerate_git endpoint. """
  5704. user = tests.FakeUser()
  5705. with tests.user_set(self.app.application, user):
  5706. output = self.app.post("/foo/regenerate")
  5707. self.assertEqual(output.status_code, 404)
  5708. def test_regenerate_git_invalid_user(self):
  5709. """ Test the regenerate_git endpoint. """
  5710. user = tests.FakeUser()
  5711. with tests.user_set(self.app.application, user):
  5712. output = self.app.post("/test/regenerate")
  5713. self.assertEqual(output.status_code, 403)
  5714. @patch(
  5715. "pagure.decorators.admin_session_timedout",
  5716. MagicMock(return_value=True),
  5717. )
  5718. def test_regenerate_git_user_session_timeout(self):
  5719. """ Test the regenerate_git endpoint. """
  5720. user = tests.FakeUser()
  5721. with tests.user_set(self.app.application, user):
  5722. output = self.app.post("/test/regenerate")
  5723. self.assertEqual(output.status_code, 302)
  5724. def test_regenerate_git_no_csrf(self):
  5725. """ Test the regenerate_git endpoint. """
  5726. user = tests.FakeUser(username="pingou")
  5727. with tests.user_set(self.app.application, user):
  5728. output = self.app.post("/test/regenerate")
  5729. self.assertEqual(output.status_code, 400)
  5730. def test_regenerate_git_missing_repo_type(self):
  5731. """ Test the regenerate_git endpoint. """
  5732. user = tests.FakeUser(username="pingou")
  5733. with tests.user_set(self.app.application, user):
  5734. data = {"csrf_token": self.csrf_token}
  5735. output = self.app.post("/test/regenerate", data=data)
  5736. self.assertEqual(output.status_code, 400)
  5737. def test_regenerate_git_missing_invalid_regenerate(self):
  5738. """ Test the regenerate_git endpoint. """
  5739. user = tests.FakeUser(username="pingou")
  5740. with tests.user_set(self.app.application, user):
  5741. data = {"csrf_token": self.csrf_token, "regenerate": "ticket"}
  5742. output = self.app.post("/test/regenerate", data=data)
  5743. self.assertEqual(output.status_code, 400)
  5744. @patch("pagure.lib.git._update_git")
  5745. def test_regenerate_git_tickets(self, upgit):
  5746. """ Test the regenerate_git endpoint. """
  5747. upgit.return_value = True
  5748. user = tests.FakeUser(username="pingou")
  5749. with tests.user_set(self.app.application, user):
  5750. # Create an issue to play with
  5751. repo = pagure.lib.query.get_authorized_project(
  5752. self.session, "test"
  5753. )
  5754. msg = pagure.lib.query.new_issue(
  5755. session=self.session,
  5756. repo=repo,
  5757. title="Test issue",
  5758. content="We should work on this",
  5759. user="pingou",
  5760. )
  5761. self.session.commit()
  5762. self.assertEqual(msg.title, "Test issue")
  5763. data = {"csrf_token": self.csrf_token, "regenerate": "tickets"}
  5764. output = self.app.post(
  5765. "/test/regenerate", data=data, follow_redirects=True
  5766. )
  5767. self.assertEqual(output.status_code, 200)
  5768. output_text = output.get_data(as_text=True)
  5769. self.assertIn("Tickets git repo updating", output_text)
  5770. self.assertEqual(upgit.call_count, 2)
  5771. @patch("pagure.lib.git._update_git")
  5772. def test_regenerate_git_requests(self, upgit):
  5773. """ Test the regenerate_git endpoint. """
  5774. # upgit.return_value = True
  5775. user = tests.FakeUser(username="pingou")
  5776. with tests.user_set(self.app.application, user):
  5777. # Create a request to play with
  5778. repo = pagure.lib.query.get_authorized_project(
  5779. self.session, "test"
  5780. )
  5781. msg = pagure.lib.query.new_pull_request(
  5782. session=self.session,
  5783. repo_from=repo,
  5784. branch_from="branch",
  5785. repo_to=repo,
  5786. branch_to="master",
  5787. title="Test pull-request",
  5788. user="pingou",
  5789. )
  5790. self.session.commit()
  5791. self.assertEqual(msg.title, "Test pull-request")
  5792. data = {"csrf_token": self.csrf_token, "regenerate": "requests"}
  5793. output = self.app.post(
  5794. "/test/regenerate", data=data, follow_redirects=True
  5795. )
  5796. self.assertEqual(output.status_code, 200)
  5797. output_text = output.get_data(as_text=True)
  5798. self.assertIn("Requests git repo updating", output_text)
  5799. self.assertEqual(upgit.call_count, 1)
  5800. class PagureFlaskRepoTestGitSSHURL(tests.Modeltests):
  5801. """ Tests the display of the SSH url in the UI """
  5802. def setUp(self):
  5803. """ Set up the environnment, ran before every tests. """
  5804. super(PagureFlaskRepoTestGitSSHURL, self).setUp()
  5805. tests.create_projects(self.session)
  5806. tests.create_projects_git(os.path.join(self.path, "repos"))
  5807. pingou = pagure.lib.query.get_user(self.session, "pingou")
  5808. # Make the repo not read-only
  5809. repo = pagure.lib.query._get_project(self.session, "test")
  5810. pagure.lib.query.update_read_only_mode(
  5811. self.session, repo, read_only=False
  5812. )
  5813. self.session.commit()
  5814. # Add a group and make pingou a member of it
  5815. item = pagure.lib.model.PagureGroup(
  5816. group_name="packager",
  5817. group_type="user",
  5818. display_name="User group",
  5819. user_id=1, # pingou
  5820. )
  5821. self.session.add(item)
  5822. self.session.commit()
  5823. pagure.lib.query.add_user_to_group(
  5824. self.session, pingou.username, item, pingou.username, True
  5825. )
  5826. # Add a SSH key for pingou so that he is allowed to push via ssh
  5827. msg = pagure.lib.query.add_sshkey_to_project_or_user(
  5828. session=self.session,
  5829. user=pingou,
  5830. ssh_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==",
  5831. pushaccess=True,
  5832. creator=pingou,
  5833. )
  5834. self.session.commit()
  5835. self.assertEqual(msg, "SSH key added")
  5836. def test_logged_out(self):
  5837. """ Test the default behavior with the user logged out. """
  5838. output = self.app.get("/test")
  5839. self.assertEqual(output.status_code, 200)
  5840. output_text = output.get_data(as_text=True)
  5841. self.assertIn("<strong>Source Code</strong>", output_text)
  5842. self.assertIn(
  5843. '<div class="input-group-prepend"><span class="input-group-text">'
  5844. "GIT</span></div>",
  5845. output_text,
  5846. )
  5847. self.assertNotIn(
  5848. '<div class="input-group-prepend"><span class="input-group-text">'
  5849. "SSH</span></div>",
  5850. output_text,
  5851. )
  5852. def test_logged_in(self):
  5853. """ Test the default behavior with the user logged in. """
  5854. user = tests.FakeUser(username="pingou")
  5855. with tests.user_set(self.app.application, user):
  5856. output = self.app.get("/test")
  5857. self.assertEqual(output.status_code, 200)
  5858. output_text = output.get_data(as_text=True)
  5859. self.assertIn("<strong>Source Code</strong>", output_text)
  5860. self.assertIn(
  5861. '<div class="input-group-prepend"><span class="input-group-text">'
  5862. "GIT</span></div>",
  5863. output_text,
  5864. )
  5865. self.assertIn(
  5866. '<div class="input-group-prepend"><span class="input-group-text">'
  5867. "SSH</span></div>",
  5868. output_text,
  5869. )
  5870. @patch.dict("pagure.config.config", {"SSH_ACCESS_GROUPS": ["packager"]})
  5871. def test_ssh_restricted_user_member(self):
  5872. """ Test when ssh is restricted and the user has access. """
  5873. user = tests.FakeUser(username="pingou")
  5874. with tests.user_set(self.app.application, user):
  5875. output = self.app.get("/test")
  5876. self.assertEqual(output.status_code, 200)
  5877. output_text = output.get_data(as_text=True)
  5878. self.assertIn("<strong>Source Code</strong>", output_text)
  5879. self.assertIn(
  5880. '<div class="input-group-prepend"><span class="input-group-text">'
  5881. "GIT</span></div>",
  5882. output_text,
  5883. )
  5884. self.assertIn(
  5885. '<div class="input-group-prepend"><span class="input-group-text">'
  5886. "SSH</span></div>",
  5887. output_text,
  5888. )
  5889. @patch.dict("pagure.config.config", {"SSH_ACCESS_GROUPS": ["invalid"]})
  5890. def test_ssh_restricted_user_non_member(self):
  5891. """ Test when ssh is restricted and the user does not have access. """
  5892. user = tests.FakeUser(username="pingou")
  5893. with tests.user_set(self.app.application, user):
  5894. output = self.app.get("/test")
  5895. self.assertEqual(output.status_code, 200)
  5896. output_text = output.get_data(as_text=True)
  5897. self.assertIn("<strong>Source Code</strong>", output_text)
  5898. self.assertIn(
  5899. '<div class="input-group-prepend"><span class="input-group-text">'
  5900. "GIT</span></div>",
  5901. output_text,
  5902. )
  5903. self.assertIn(
  5904. "Only members of the invalid group(s) can clone via ssh",
  5905. output_text,
  5906. )
  5907. self.assertNotIn(
  5908. '<div class="input-group-prepend"><span class="input-group-text">'
  5909. "SSH</span></div>",
  5910. output_text,
  5911. )
  5912. if __name__ == "__main__":
  5913. unittest.main(verbosity=2)