test_pagure_flask_ui_repo.py 240 KB

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