test_pagure_flask_ui_repo.py 247 KB

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