test_pagure_flask_ui_repo.py 258 KB

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