test_pagure_flask_ui_repo.py 258 KB

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