diff options
Diffstat (limited to 't')
74 files changed, 3953 insertions, 1072 deletions
diff --git a/t/Mock/Facebook.pm b/t/Mock/Facebook.pm index 339eae536..6c9f90f10 100644 --- a/t/Mock/Facebook.pm +++ b/t/Mock/Facebook.pm @@ -20,12 +20,12 @@ has returns_email => ( sub dispatch_request { my $self = shift; - sub (GET + /v2.8/dialog/oauth + ?*) { + sub (GET + /v3.1/dialog/oauth + ?*) { my ($self) = @_; return [ 200, [ 'Content-Type' => 'text/html' ], [ 'FB login page' ] ]; }, - sub (GET + /v2.8/oauth/access_token + ?*) { + sub (GET + /v3.1/oauth/access_token + ?*) { my ($self) = @_; return [ 200, [ 'Content-Type' => 'application/json' ], [ '{"access_token": "access_token"}' ] ]; }, diff --git a/t/Mock/MapIt.pm b/t/Mock/MapIt.pm index c57f7e0ed..ea1f5b259 100644 --- a/t/Mock/MapIt.pm +++ b/t/Mock/MapIt.pm @@ -26,17 +26,27 @@ my @PLACES = ( [ '?', 53.387402, -2.943997, 2527, 'Liverpool City Council', 'MTD' ], [ 'EH1 1BB', 55.952055, -3.189579, 2651, 'Edinburgh City Council', 'UTA', 20728, 'City Centre', 'UTE' ], [ 'BS10 5EE', 51.494885, -2.602237, 2561, 'Bristol City Council', 'UTA', 148646, 'Bedminster', 'UTW' ], + [ 'BS20 5EE', 51.496194, -2.603439, 2608, 'Borsetshire County Council', 'CTY', 148646, 'Bedminster', 'UTW' ], + [ 'SL9 0NX', 51.615559, -0.556903, 2217, 'Buckinghamshire County Council', 'CTY', 2257, 'Chiltern District Council', 'DIS' ], [ 'SW1A 1AA', 51.501009, -0.141588, 2504, 'Westminster City Council', 'LBO' ], [ 'GL50 2PR', 51.896268, -2.093063, 2226, 'Gloucestershire County Council', 'CTY', 2326, 'Cheltenham Borough Council', 'DIS', 4544, 'Lansdown', 'DIW', 143641, 'Lansdown and Park', 'CED' ], - [ '?', 51.754926, -1.256179, 2237, 'Oxfordshire County Council', 'CTY', 2421, 'Oxford City Council', 'DIS' ], [ 'OX20 1SZ', 51.754926, -1.256179, 2237, 'Oxfordshire County Council', 'CTY', 2421, 'Oxford City Council', 'DIS' ], + [ 'OX16 9UP', 52.038712, -1.346397, 2237, 'Oxfordshire County Council', 'CTY', 2419, 'Cherwell District Council', 'DIS', 151767, "Banbury, Calthorpe & Easington", "DIW" ], + [ 'RG9 6TL', 51.561705, -0.868388, 2217, 'Buckinghamshire County Council', 'CTY'], + [ 'PE9 2GX', 52.656144, -0.502566, 2232, 'Lincolnshire County Council', 'CTY'], + [ 'LE15 0GJ', 52.670447, -0.727877, 2600, 'Rutland County Council', 'CTY'], [ 'BR1 3UH', 51.4021, 0.01578, 2482, 'Bromley Council', 'LBO' ], [ 'BR1 3UH', 51.402096, 0.015784, 2482, 'Bromley Council', 'LBO' ], + [ 'NN1 1NS', 52.236251, 0.892052, 2234, 'Northamptonshire County Council', 'CTY' ], [ '?', 50.78301, -0.646929 ], + [ 'TA1 1QP', 51.023569, -3.099055, 2239, 'Somerset County Council', 'CTY', 2429, 'Taunton Deane Borough Council', 'DIS' ], [ 'GU51 4AE', 51.279456, -0.846216, 2333, 'Hart District Council', 'DIS', 2227, 'Hampshire County Council', 'CTY' ], [ 'WS1 4NH', 52.563074, -1.991032, 2535, 'Sandwell Borough Council', 'MTD' ], [ 'OX28 4DS', 51.784721, -1.494453 ], [ 'E14 2DN', 51.508536, '0.000001' ], + # Norway + [ '3290', 59, 10, 709, 'Larvik', 'NKO', 7, 'Vestfold', 'NFY' ], + [ '0045', "59.9", "10.9", 301, 'Oslo', 'NKO', 3, 'Oslo', 'NFY' ], ); sub dispatch_request { @@ -46,7 +56,15 @@ sub dispatch_request { my ($self, $postcode) = @_; foreach (@PLACES) { if ($postcode eq $_->[0] || $postcode eq $_->[0] =~ s/ //gr) { - return $self->output({wgs84_lat => $_->[1], wgs84_lon => $_->[2], postcode => $postcode, coordsyst => 'G'}); + my %areas; + for (my $i=3; $i<@$_; $i+=3) { + $areas{"$_->[$i]"} = { id => $_->[$i], name => $_->[$i+1], type => $_->[$i+2] }; + } + return $self->output({ + wgs84_lat => $_->[1], wgs84_lon => $_->[2], + postcode => $postcode, coordsyst => 'G', + areas => \%areas, + }); } } my $response = { @@ -55,14 +73,18 @@ sub dispatch_request { return $self->output($response); }, - sub (GET + /point/**.*) { - my ($self, $point) = @_; + sub (GET + /point/**.* + ?*) { + my ($self, $point, $query) = @_; foreach (@PLACES) { if ($point eq "4326/$_->[2],$_->[1]") { my %out; for (my $i=3; $i<@$_; $i+=3) { $out{"$_->[$i]"} = { id => $_->[$i], name => $_->[$i+1], type => $_->[$i+2] }; } + if ($query->{type}) { + my %types = map { $_ => 1 } split ',', $query->{type}; + %out = map { $_ => $out{$_} } grep { $types{$out{$_}{type}} } keys %out; + } return $self->output(\%out); } } @@ -88,6 +110,11 @@ sub dispatch_request { } }, + sub (GET + .geojson) { + my ($self) = @_; + return [ 200, [ 'Content-Type' => 'text/html' ], [ '{ "type": "Polygon", "coordinates": [ [ [ -2.628887610656303, 51.6416000233516 ], [ -2.627997933115663, 51.64267930705379 ], [ -2.62729758117729, 51.644287101889574 ], [ -2.624828153396058, 51.64768374200581 ], [ -2.623083921531683, 51.648866319056673 ], [ -2.621138681992249, 51.650572451312357 ], [ -2.619281456879798, 51.652590895708542 ], [ -2.617688060838417, 51.655108776219315 ], [ -2.617005541882011, 51.655727377054454 ], [ -2.615023843110563, 51.656918360487168 ], [ -2.612113285345945, 51.658056628664745 ], [ -2.60957228091137, 51.658196591484653 ], [ -2.599133960093137, 51.659885831427125 ], [ -2.591733711631031, 51.660468262821567 ], [ -2.586234534167322, 51.660486863075633 ], [ -2.583985127868503, 51.660840635263419 ], [ -2.582574937847228, 51.661236944306765 ], [ -2.580285680729184, 51.662208549915654 ], [ -2.579459490394377, 51.662835730557724 ], [ -2.574489601617846, 51.664611701752563 ], [ -2.570501061181081, 51.66626395561083 ], [ -2.565224884413629, 51.668815129922514 ], [ -2.558130519127701, 51.673367162781922 ], [ -2.551366274652055, 51.678304804609361 ], [ -2.547997628201342, 51.680197058131128 ], [ -2.545307270671993, 51.68114647651511 ], [ -2.540812299669275, 51.6823936848144 ], [ -2.5338121569224, 51.676537308293852 ], [ -2.526741601679602, 51.674042696109176 ], [ -2.522034007407363, 51.672119823793878 ], [ -2.520094956565791, 51.671505332219979 ], [ -2.519781109696169, 51.671252251703486 ], [ -2.5174914494476, 51.670697695535281 ], [ -2.515764574847389, 51.669900625104425 ], [ -2.509861242051534, 51.667911411373971 ], [ -2.509005492836268, 51.665998191406331 ], [ -2.508185534983574, 51.665987361727943 ], [ -2.508074595576015, 51.666151526423654 ], [ -2.507196392514714, 51.666230829051145 ], [ -2.505351251393102, 51.666215415527603 ], [ -2.501364254745949, 51.665364829802009 ], [ -2.50125167534058, 51.665123424220397 ], [ -2.501673903811009, 51.66473321824293 ], [ -2.500844875962225, 51.664416669885547 ], [ -2.500076250819516, 51.664864168898333 ], [ -2.498637529371763, 51.664987141989791 ], [ -2.496423511524656, 51.664418371075733 ], [ -2.495195435664323, 51.664639376822329 ], [ -2.492540116802006, 51.664164977203349 ], [ -2.491877084799754, 51.664353014552404 ], [ -2.4908355957446, 51.664313329050088 ], [ -2.489640507456253, 51.663958681348937 ], [ -2.489816442154644, 51.66338248994056 ], [ -2.491142021666106, 51.663227648976942 ], [ -2.491678718214046, 51.662855876253801 ], [ -2.491801955968634, 51.660355777422112 ], [ -2.492343750761095, 51.658325111491521 ], [ -2.492705029773037, 51.657776002646905 ], [ -2.49170186055767, 51.655922599029871 ], [ -2.491403750233439, 51.653750642627955 ], [ -2.491741932835433, 51.653073992992113 ], [ -2.492685380239788, 51.652372331555981 ], [ -2.493014750438256, 51.651819759555082 ], [ -2.491845142971805, 51.649662246391529 ], [ -2.489350668232967, 51.648878697255761 ], [ -2.488787865173645, 51.648959334125891 ], [ -2.486074529489112, 51.648383457456383 ], [ -2.48497067484795, 51.648416787419464 ], [ -2.486435292188961, 51.647385741218471 ], [ -2.487569069367985, 51.647033981924828 ], [ -2.487947846213224, 51.646508184646606 ], [ -2.490050540517064, 51.64569646041015 ], [ -2.489891524185981, 51.645558697588008 ], [ -2.490835115873529, 51.645135790230988 ], [ -2.490675732082632, 51.644831648363642 ], [ -2.487935768621695, 51.644851160482531 ], [ -2.487262068464783, 51.644686678695834 ], [ -2.485114198154437, 51.645207214783518 ], [ -2.482152699357456, 51.646406290555156 ], [ -2.477267625079288, 51.646678839317303 ], [ -2.474718455352253, 51.646562435880156 ], [ -2.473060124115014, 51.646785849660731 ], [ -2.470962755671979, 51.647593562244033 ], [ -2.470335638336707, 51.6474720323463 ], [ -2.470310912442152, 51.64773109680953 ], [ -2.469432830767572, 51.647932364026481 ], [ -2.469153206042532, 51.648295817797951 ], [ -2.468396031807806, 51.648725087415656 ], [ -2.468083576075323, 51.649407859362682 ], [ -2.465790694526994, 51.651042592059483 ], [ -2.464566162380982, 51.650878456955972 ], [ -2.463714448908142, 51.650974408728942 ], [ -2.463316571399485, 51.65164492082782 ], [ -2.462748963518903, 51.651975338242494 ], [ -2.460442535615518, 51.652599416804989 ], [ -2.458779997856523, 51.651278831705909 ], [ -2.458432636722947, 51.65151847994553 ], [ -2.455800668071223, 51.651830751042461 ], [ -2.455951411216347, 51.652304050978515 ], [ -2.452520726350855, 51.651368747603996 ], [ -2.450657247012778, 51.650306888402255 ], [ -2.449208090706901, 51.649787322274783 ], [ -2.445656716368873, 51.649331469131219 ], [ -2.445043570707363, 51.649889478408156 ], [ -2.445229196842058, 51.649957987583569 ], [ -2.445029264971886, 51.650643057152401 ], [ -2.444629784166214, 51.650885468826424 ], [ -2.444804067117561, 51.651109616379351 ], [ -2.444281558139852, 51.651336403197519 ], [ -2.44416020816488, 51.651638074441067 ], [ -2.443322711762089, 51.652024249921965 ], [ -2.442984733285543, 51.652489433685339 ], [ -2.442644615911436, 51.652295661654477 ], [ -2.441935553208066, 51.652214738447547 ], [ -2.439556972499991, 51.649896670618475 ], [ -2.439076158197298, 51.650542242370335 ], [ -2.438672484838386, 51.650205686025366 ], [ -2.437707501790271, 51.650102322852348 ], [ -2.437064603963198, 51.649536451733759 ], [ -2.435506942811041, 51.649886599595014 ], [ -2.434490357745992, 51.649532526303425 ], [ -2.434305030226391, 51.649194247590366 ], [ -2.433049880633498, 51.64928877246772 ], [ -2.432177864881468, 51.649083358423219 ], [ -2.431703150435795, 51.64856277093034 ], [ -2.431876751991456, 51.648271706714439 ], [ -2.431802176477283, 51.647722590467545 ], [ -2.4320475777, 51.647238004251946 ], [ -2.432011971662659, 51.646989956688031 ], [ -2.430835794928993, 51.646559945000618 ], [ -2.427230491966149, 51.647241255703307 ], [ -2.426151098823684, 51.646961945230963 ], [ -2.425926362751782, 51.646581459450047 ], [ -2.424117159450851, 51.645833677586026 ], [ -2.423482170832871, 51.646078755856657 ], [ -2.422764988494484, 51.645584984179337 ], [ -2.421926660851629, 51.645414518597399 ], [ -2.42128557272021, 51.645477944856367 ], [ -2.420946184375182, 51.645038535435383 ], [ -2.420216826727378, 51.644614993764129 ], [ -2.41880613344551, 51.644293655663574 ], [ -2.416737704741536, 51.643308393773793 ], [ -2.415768374096149, 51.643658886349506 ], [ -2.415639038670033, 51.644213229572763 ], [ -2.415299296646752, 51.644353757465524 ], [ -2.415321907871578, 51.644624327873728 ], [ -2.413919275481692, 51.644059218331307 ], [ -2.413051411600185, 51.643490413404365 ], [ -2.412382435439872, 51.64271146609137 ], [ -2.411536199836601, 51.642789042939995 ], [ -2.410185448561206, 51.641874854424785 ], [ -2.407394585181527, 51.641356847600129 ], [ -2.407218355729421, 51.641196471158871 ], [ -2.40696884010188, 51.641247673536412 ], [ -2.407017984283043, 51.641572984827448 ], [ -2.406423440042848, 51.641667719029925 ], [ -2.404784772133554, 51.641360484941366 ], [ -2.404189613743223, 51.642350666557547 ], [ -2.404133350591639, 51.642857015257384 ], [ -2.402739988819236, 51.64249587422519 ], [ -2.40213966232318, 51.643406962180762 ], [ -2.401774568172401, 51.643473830281707 ], [ -2.401870113986149, 51.643660558412428 ], [ -2.401252200271076, 51.644216557556625 ], [ -2.401360573671157, 51.644371691817348 ], [ -2.401101468791152, 51.644662104259076 ], [ -2.400309811577192, 51.645192624706787 ], [ -2.398994222125593, 51.645632248460743 ], [ -2.39883823645013, 51.645808148509765 ], [ -2.39823783468051, 51.645569199884619 ], [ -2.397216483839058, 51.644462195092103 ], [ -2.395836127315136, 51.643610054338495 ], [ -2.396567619806918, 51.64280462254554 ], [ -2.395870633034205, 51.642428460674012 ], [ -2.394785560819355, 51.64211831958842 ], [ -2.395216171975116, 51.641447030743755 ], [ -2.39683490544894, 51.640161214564074 ], [ -2.396601420334136, 51.640056745894711 ], [ -2.39714460555341, 51.639552349361871 ], [ -2.395785012918386, 51.638741395465118 ], [ -2.394617985762697, 51.638628472103107 ], [ -2.392942787410724, 51.638924518931631 ], [ -2.391529147624174, 51.639711442549626 ], [ -2.390166399390646, 51.640713999005079 ], [ -2.389992143500879, 51.640443028935401 ], [ -2.388443301714674, 51.64014425712557 ], [ -2.385990861304208, 51.639941114145991 ], [ -2.385367109343339, 51.639320065877278 ], [ -2.385477420969552, 51.63921992876007 ], [ -2.385352891079851, 51.638669149248088 ], [ -2.386118434254522, 51.637610098242241 ], [ -2.386328571379746, 51.637523114881354 ], [ -2.388267322510226, 51.637299998191644 ], [ -2.38818390966087, 51.637172634225898 ], [ -2.388323920130202, 51.636994104330412 ], [ -2.389993893129772, 51.636441062993597 ], [ -2.391352673781165, 51.636333978091066 ], [ -2.391598468970301, 51.636183945238805 ], [ -2.391550207885503, 51.635947612815599 ], [ -2.392637006803586, 51.636146317893932 ], [ -2.3929491548601, 51.635982487197445 ], [ -2.393333422007448, 51.6361403902524 ], [ -2.396317574048576, 51.636008912435116 ], [ -2.397000757656144, 51.635647862975382 ], [ -2.397293414640006, 51.635736849748511 ], [ -2.397444394777382, 51.635986225224457 ], [ -2.398351280001673, 51.635758432035772 ], [ -2.398341475060128, 51.635468938281115 ], [ -2.3987438795207, 51.63522119051914 ], [ -2.399361579502424, 51.635464572308869 ], [ -2.399875741601714, 51.635110373240401 ], [ -2.400477041985556, 51.635141581079957 ], [ -2.400293594219425, 51.634981218771735 ], [ -2.400554118312832, 51.634708780191801 ], [ -2.400459178907854, 51.634425869216678 ], [ -2.3996969885367, 51.634345771360408 ], [ -2.399254006446898, 51.633743056622933 ], [ -2.39873708379946, 51.633957937069709 ], [ -2.398355547764272, 51.633934963265503 ], [ -2.398176770435028, 51.633490447885507 ], [ -2.397748230263496, 51.633391227347019 ], [ -2.397683623676227, 51.63311450338913 ], [ -2.39750233180638, 51.633035117885377 ], [ -2.396664560866987, 51.633382311141908 ], [ -2.396453223838603, 51.633177093407127 ], [ -2.396571575200989, 51.632828739579175 ], [ -2.39593046375111, 51.632544972750082 ], [ -2.395308435948397, 51.632619069578297 ], [ -2.395321635746634, 51.632315115966584 ], [ -2.395011019792736, 51.631815309589193 ], [ -2.393658075827358, 51.631740755150616 ], [ -2.393645563608084, 51.631300169261998 ], [ -2.392971611922201, 51.630051735183386 ], [ -2.391289019700665, 51.628941585699565 ], [ -2.390661343015156, 51.628866373878019 ], [ -2.390433942075337, 51.628463356518239 ], [ -2.389702184479185, 51.628209609898583 ], [ -2.388912073244873, 51.627538704886135 ], [ -2.389548928621172, 51.627172458468699 ], [ -2.389331011418121, 51.627040148318713 ], [ -2.389167003881376, 51.626609951824463 ], [ -2.389581288840586, 51.62640363375651 ], [ -2.388973111399246, 51.62606938248387 ], [ -2.389435927468697, 51.625786409805514 ], [ -2.389167369887602, 51.625637098884589 ], [ -2.389400745400919, 51.625391830791891 ], [ -2.389293748229544, 51.62522041090434 ], [ -2.389511122128517, 51.624789937610537 ], [ -2.389300842731849, 51.624699759229109 ], [ -2.388936814567736, 51.624861954847852 ], [ -2.388833604418968, 51.624617713135308 ], [ -2.388443522997589, 51.624449117824078 ], [ -2.388758714377174, 51.624300568653574 ], [ -2.388535042175411, 51.623994703350647 ], [ -2.38872497471998, 51.623572412158275 ], [ -2.388618157293414, 51.623407283138171 ], [ -2.389108164861394, 51.623451501846603 ], [ -2.389537036124464, 51.623255023040379 ], [ -2.389424473100767, 51.623100700314247 ], [ -2.388962753627569, 51.62316065863822 ], [ -2.388887132672759, 51.622938887206359 ], [ -2.389627085761559, 51.622477826504593 ], [ -2.389210114695729, 51.622533142842393 ], [ -2.388852223565686, 51.622241206314001 ], [ -2.388858949370915, 51.622011072031924 ], [ -2.389371045938758, 51.621757598911273 ], [ -2.389286795957778, 51.621529474305525 ], [ -2.389581873188081, 51.621246158287022 ], [ -2.38924288641801, 51.621130429542823 ], [ -2.389412627133618, 51.620883484652325 ], [ -2.389240407174279, 51.620340056809084 ], [ -2.38947915489697, 51.620210725395552 ], [ -2.389404749160666, 51.619963691758223 ], [ -2.389543627652221, 51.619645837889173 ], [ -2.388933638253139, 51.619590333410251 ], [ -2.389149819646947, 51.619371100018675 ], [ -2.389193814893633, 51.61894569612781 ], [ -2.389752771311303, 51.618939346372315 ], [ -2.38958350522396, 51.618740268261433 ], [ -2.389930687909915, 51.618466665820016 ], [ -2.389303664012677, 51.618102815670156 ], [ -2.38957848242142, 51.617820465558587 ], [ -2.389359759350119, 51.617574899646741 ], [ -2.390020471563605, 51.617646413066055 ], [ -2.390165779736665, 51.617413031267382 ], [ -2.389877890635426, 51.617017494139283 ], [ -2.39073103831554, 51.616964319103957 ], [ -2.3903944979132, 51.616797259679601 ], [ -2.390427027486773, 51.616549870695238 ], [ -2.390005315270475, 51.616393071053949 ], [ -2.390452262721699, 51.616299000349088 ], [ -2.390500493571589, 51.616021896164888 ], [ -2.390863990892461, 51.61597304538784 ], [ -2.390903804327539, 51.615728328595807 ], [ -2.39159667099267, 51.615346602592815 ], [ -2.391587254700638, 51.615096656577109 ], [ -2.391237861668196, 51.614943125566768 ], [ -2.391699406194891, 51.614706978960804 ], [ -2.391251546947745, 51.614346945251448 ], [ -2.391767002242265, 51.613997270263724 ], [ -2.391522718995733, 51.61363125425698 ], [ -2.391842686206985, 51.613397287235671 ], [ -2.390773653738782, 51.613026830147618 ], [ -2.390769350997096, 51.612692372555045 ], [ -2.391010076638892, 51.612465862667634 ], [ -2.390502577569776, 51.612395642757271 ], [ -2.3902618495576, 51.612108713353457 ], [ -2.39057212115442, 51.61157815269781 ], [ -2.391196812036903, 51.611513959110781 ], [ -2.39127447477347, 51.611309655133354 ], [ -2.391809273852887, 51.611357308624939 ], [ -2.391671376756563, 51.611106892556698 ], [ -2.392161923971524, 51.61106300673098 ], [ -2.393189238764193, 51.610619927810291 ], [ -2.393343656454454, 51.610274061723075 ], [ -2.394166816620838, 51.609605950403427 ], [ -2.393842615518367, 51.609195263566434 ], [ -2.394453054031109, 51.608974695805173 ], [ -2.394239547403608, 51.608669705314995 ], [ -2.394624671051732, 51.608280005733079 ], [ -2.39455068131188, 51.60775243384068 ], [ -2.395188309191183, 51.607512085320408 ], [ -2.395176205089613, 51.607283721347002 ], [ -2.394791035490119, 51.607323669794418 ], [ -2.394462348676581, 51.606888729925359 ], [ -2.394714143375008, 51.606777231258086 ], [ -2.395040435291721, 51.606936223124748 ], [ -2.3954362113281, 51.606788282918686 ], [ -2.395066754953549, 51.606484718225801 ], [ -2.395239510040521, 51.60592314688008 ], [ -2.395430666582214, 51.605821738567222 ], [ -2.395151855376495, 51.605303036781528 ], [ -2.395430435372906, 51.605124030485641 ], [ -2.394806666942402, 51.604625276541604 ], [ -2.394961129360961, 51.604466554149127 ], [ -2.394910762902535, 51.60382114960511 ], [ -2.39388976218216, 51.60313136727251 ], [ -2.394492004353229, 51.603141928041197 ], [ -2.394494654634341, 51.602788570168428 ], [ -2.394711698901559, 51.602667300587015 ], [ -2.394568759626289, 51.602506882228099 ], [ -2.394835457611185, 51.602455647785888 ], [ -2.394974313634318, 51.602159359581805 ], [ -2.394908810851462, 51.601758500631817 ], [ -2.395169475835327, 51.601684813769566 ], [ -2.395299209723987, 51.601325634380842 ], [ -2.395662305129277, 51.601408904940818 ], [ -2.395783758830124, 51.601097393472784 ], [ -2.396361129161602, 51.600742994007184 ], [ -2.396489367707331, 51.600377526132952 ], [ -2.396024625264149, 51.599734420191275 ], [ -2.395176146546283, 51.599629415905213 ], [ -2.394491641576359, 51.599104797010959 ], [ -2.394457766323526, 51.59853394317679 ], [ -2.394845216326506, 51.597763918634442 ], [ -2.394659896384956, 51.597367956858342 ], [ -2.393102539542556, 51.597074668012063 ], [ -2.39187222975377, 51.597380897372794 ], [ -2.390031347404598, 51.597017503122039 ], [ -2.38914705290806, 51.597101338916993 ], [ -2.388881830740288, 51.596988060798068 ], [ -2.388451657033466, 51.59715676735059 ], [ -2.388091681703877, 51.596931351424445 ], [ -2.38802113715846, 51.597117742578675 ], [ -2.387744597848921, 51.597198657143345 ], [ -2.387456454384997, 51.597105137012839 ], [ -2.386829476637812, 51.597227745750374 ], [ -2.385901938416759, 51.596971833621062 ], [ -2.385479896754047, 51.597090075423203 ], [ -2.385159752313931, 51.596787216059489 ], [ -2.385001257079749, 51.596821983609125 ], [ -2.385042715816907, 51.596938701777319 ], [ -2.384295946990622, 51.596901599801505 ], [ -2.384038696703008, 51.596870981481317 ], [ -2.384034306863386, 51.596689332457913 ], [ -2.382717016952396, 51.596779030880413 ], [ -2.381490155301607, 51.596467430690197 ], [ -2.380002831470514, 51.596421920800339 ], [ -2.37872150399978, 51.596685031358746 ], [ -2.378192795005272, 51.59716152471141 ], [ -2.377111294652397, 51.597309725782829 ], [ -2.376848462589734, 51.597654031863648 ], [ -2.376303826251677, 51.597618926175386 ], [ -2.375760999761879, 51.597961430978124 ], [ -2.375379866428684, 51.597617391991477 ], [ -2.374416487760911, 51.597555751502142 ], [ -2.374052281423936, 51.597690846248405 ], [ -2.373575603134363, 51.597480229911831 ], [ -2.372452511940456, 51.597668969992583 ], [ -2.370579518754981, 51.597612879115061 ], [ -2.370085017920192, 51.597872508152719 ], [ -2.370081908244647, 51.598558541802461 ], [ -2.36908728992712, 51.599108372994699 ], [ -2.3687694409004, 51.599077012987536 ], [ -2.368327691854239, 51.599621413002097 ], [ -2.367784611302568, 51.59976612836784 ], [ -2.367484730022335, 51.600353316289244 ], [ -2.367616770615899, 51.600444588125242 ], [ -2.366764896776442, 51.600975075548277 ], [ -2.366674745445634, 51.601251312810057 ], [ -2.366818123788742, 51.601670820198635 ], [ -2.366583927395295, 51.60305528425426 ], [ -2.365584368367885, 51.603733640069031 ], [ -2.362235061807085, 51.602710051202592 ], [ -2.362737687543008, 51.602008991738927 ], [ -2.362946629323111, 51.601235041164877 ], [ -2.36212964995662, 51.601073071368383 ], [ -2.359860835755725, 51.601002749647343 ], [ -2.357542124563282, 51.601565435784728 ], [ -2.357247553257312, 51.600830871693638 ], [ -2.356832218454405, 51.600512944391241 ], [ -2.356053136412053, 51.600214996643345 ], [ -2.355099299434031, 51.600098337129118 ], [ -2.354818528619455, 51.598715364534591 ], [ -2.35405561730487, 51.59938841218586 ], [ -2.353514955201816, 51.598547614577114 ], [ -2.353613807025592, 51.598263181363308 ], [ -2.352788866954544, 51.596694876048069 ], [ -2.349904625588195, 51.597100908827848 ], [ -2.349868242911752, 51.597261107502106 ], [ -2.347195660021305, 51.59741196983763 ], [ -2.345059100372815, 51.596844610383059 ], [ -2.345049109247335, 51.596672954100988 ], [ -2.34402280017971, 51.596497900837761 ], [ -2.344037552384133, 51.595788463104952 ], [ -2.34429669032089, 51.595113364470805 ], [ -2.344314535932006, 51.594608861678402 ], [ -2.344115263405587, 51.59422823219488 ], [ -2.343369014902477, 51.595196083836761 ], [ -2.342962513309081, 51.594893362390899 ], [ -2.342628488533546, 51.594809843998121 ], [ -2.342588812256837, 51.595104881784586 ], [ -2.339482071923744, 51.594132968638625 ], [ -2.338259582013817, 51.595320592403759 ], [ -2.337909367354163, 51.595220028600217 ], [ -2.337931457014513, 51.595085133269585 ], [ -2.335256124339245, 51.594252988576166 ], [ -2.335051675655772, 51.596488812332296 ], [ -2.334179395572385, 51.596632424447279 ], [ -2.333296039577599, 51.595476014709135 ], [ -2.331273567574961, 51.595485339545633 ], [ -2.331147969992536, 51.595286053438343 ], [ -2.330823979034669, 51.593813257346248 ], [ -2.330379283497915, 51.593203992761737 ], [ -2.330983512920772, 51.592526153146117 ], [ -2.331182586832403, 51.592503119271633 ], [ -2.33106629059591, 51.591601602988419 ], [ -2.330869893967923, 51.591599460527128 ], [ -2.330373413863329, 51.592198793828707 ], [ -2.329198572492558, 51.59282519939525 ], [ -2.328890692303677, 51.592170601121879 ], [ -2.32859052730275, 51.591989868996016 ], [ -2.32840572750456, 51.59318256865317 ], [ -2.327798209332903, 51.593212133255228 ], [ -2.327310923786925, 51.592896999078967 ], [ -2.327057321054739, 51.592967908866527 ], [ -2.326753034049749, 51.59280956562678 ], [ -2.324993414278703, 51.593226320244383 ], [ -2.323828257358478, 51.593187205693233 ], [ -2.322653746951422, 51.593675117428489 ], [ -2.319850507144412, 51.593914795552415 ], [ -2.31969618718062, 51.593312788357309 ], [ -2.319387331259915, 51.592907157199214 ], [ -2.319671355260464, 51.592658293138456 ], [ -2.317740267454853, 51.591061290204486 ], [ -2.318736219914905, 51.590638632004989 ], [ -2.3186257463728, 51.590532864532413 ], [ -2.317593687050345, 51.590744293312966 ], [ -2.316574044385084, 51.589833519876983 ], [ -2.313474682241087, 51.590836273476988 ], [ -2.312767455693502, 51.591282297207471 ], [ -2.311590400205579, 51.591617205984541 ], [ -2.310646990339961, 51.592130450912116 ], [ -2.308257156208086, 51.592864128143525 ], [ -2.307878473810935, 51.592360762485875 ], [ -2.308613649065739, 51.591796851929601 ], [ -2.308152014569621, 51.591627189018617 ], [ -2.306909345050649, 51.591645728276589 ], [ -2.306106047123665, 51.591976007855123 ], [ -2.305802931344419, 51.59219261912196 ], [ -2.305601904189262, 51.592989818399445 ], [ -2.304005249977793, 51.592762866318026 ], [ -2.302325940070474, 51.592274442325646 ], [ -2.301791227391229, 51.591958425714481 ], [ -2.301340698953847, 51.592150236085338 ], [ -2.301085648930611, 51.592007879666852 ], [ -2.301016542774162, 51.591600775547882 ], [ -2.300102045147939, 51.591480871714879 ], [ -2.300027669551002, 51.591807444509811 ], [ -2.299625221680249, 51.592071934382211 ], [ -2.297889351902017, 51.592386558818518 ], [ -2.296874364696937, 51.593028414084174 ], [ -2.296441990161243, 51.59380092431843 ], [ -2.296553673503761, 51.594993811652152 ], [ -2.294394179523162, 51.594795116986688 ], [ -2.291587983519886, 51.593920059022842 ], [ -2.291764378266195, 51.593734451626041 ], [ -2.289858271973296, 51.593203267316802 ], [ -2.290233785258385, 51.59254957389976 ], [ -2.289304454686306, 51.592360319232469 ], [ -2.290331244197314, 51.591072926319889 ], [ -2.292704337652322, 51.589963834954474 ], [ -2.293727934123245, 51.58908999342578 ], [ -2.294089841053377, 51.588572950681503 ], [ -2.29303294290834, 51.58830143838437 ], [ -2.293428830291336, 51.587701615904258 ], [ -2.291877204621569, 51.5877027911705 ], [ -2.29211042041553, 51.587381221101722 ], [ -2.291009093131862, 51.586929845784105 ], [ -2.290531629323968, 51.58741300811068 ], [ -2.287675664391987, 51.586582024320592 ], [ -2.286384281357879, 51.585968374679744 ], [ -2.28601203938222, 51.585533237200195 ], [ -2.285346653900522, 51.585526768184813 ], [ -2.283507285098432, 51.584962958351561 ], [ -2.283793812678396, 51.584634084773363 ], [ -2.284127752054691, 51.584714175241992 ], [ -2.284597609998135, 51.584150158160426 ], [ -2.286555262651742, 51.584470874897384 ], [ -2.287281672071755, 51.583156375191187 ], [ -2.285759838510563, 51.583063913354557 ], [ -2.285288885859958, 51.582746767014832 ], [ -2.284936898298666, 51.583241197132686 ], [ -2.284415174067759, 51.583120216114786 ], [ -2.282076127265286, 51.582267166775893 ], [ -2.280892548735147, 51.581312432063825 ], [ -2.280720610350774, 51.581043090196005 ], [ -2.282053451394207, 51.580700924692906 ], [ -2.281281909951052, 51.579621156579726 ], [ -2.282749895048961, 51.57851613941174 ], [ -2.280245121959878, 51.577892756801255 ], [ -2.278673046776333, 51.577803019865954 ], [ -2.276753845168845, 51.579464649159718 ], [ -2.276808009278581, 51.579605735235454 ], [ -2.276565966776921, 51.579895835315611 ], [ -2.274333134411876, 51.579142156518394 ], [ -2.274477497435404, 51.578910806733688 ], [ -2.273225340857874, 51.578264470494133 ], [ -2.272563202100845, 51.577589874389645 ], [ -2.273955263721872, 51.574382124300143 ], [ -2.273996507596004, 51.572359008401627 ], [ -2.270349924106984, 51.5725454511499 ], [ -2.268903621049119, 51.572465181081263 ], [ -2.266433565310434, 51.571748839242481 ], [ -2.263426848293026, 51.571305114183176 ], [ -2.260352134931933, 51.570048695540571 ], [ -2.260303702711808, 51.569900487812191 ], [ -2.260523798506436, 51.569778560223121 ], [ -2.262255335826719, 51.569064404603388 ], [ -2.263999715508298, 51.568071451479355 ], [ -2.264437011891275, 51.567601969364183 ], [ -2.264606709171837, 51.567265315184649 ], [ -2.264441200282208, 51.566827843705831 ], [ -2.265112439583236, 51.566395673973801 ], [ -2.266471730014054, 51.564711145419487 ], [ -2.266478992558163, 51.56446834106994 ], [ -2.266065491128286, 51.56431916698012 ], [ -2.267410214176918, 51.562884638909964 ], [ -2.267289271367175, 51.561692727918803 ], [ -2.26795697486925, 51.559928855897233 ], [ -2.268377409206115, 51.560049243311134 ], [ -2.268627903245282, 51.55970880232546 ], [ -2.267902383153833, 51.559483944132083 ], [ -2.268106063017239, 51.558787474061333 ], [ -2.267689812551514, 51.558162623368354 ], [ -2.268286501011684, 51.556609338891363 ], [ -2.268408298998787, 51.555744155229206 ], [ -2.267804466758534, 51.553874421591487 ], [ -2.267386641570556, 51.55394548817133 ], [ -2.267033957684896, 51.553322287446889 ], [ -2.267397889944657, 51.552660599059756 ], [ -2.267125552464626, 51.552475061210153 ], [ -2.267558174349296, 51.552212409747277 ], [ -2.266893577124978, 51.551769786433432 ], [ -2.267044577208774, 51.551684947537417 ], [ -2.26684510117187, 51.55161438997235 ], [ -2.266813256735744, 51.551354595279527 ], [ -2.267692924790479, 51.550596359286608 ], [ -2.268372648624755, 51.549692056437912 ], [ -2.264249113762942, 51.545652671026268 ], [ -2.263455945153186, 51.545159890200573 ], [ -2.261725960740881, 51.544741199990206 ], [ -2.26164709660967, 51.543554489106008 ], [ -2.262041935571962, 51.542747038041149 ], [ -2.262217355586714, 51.541661422283916 ], [ -2.262486058567417, 51.541498931751121 ], [ -2.262917235129565, 51.540504427985766 ], [ -2.263820495942986, 51.539369533707664 ], [ -2.264819446205273, 51.53758605004289 ], [ -2.266505833947524, 51.536262304463165 ], [ -2.265663254636472, 51.535426185961292 ], [ -2.264072822376485, 51.53539831878453 ], [ -2.263911714615679, 51.534960834357108 ], [ -2.263247130351492, 51.53471774195657 ], [ -2.263466352826799, 51.534475359219968 ], [ -2.263366382546683, 51.534392886379756 ], [ -2.261866181583959, 51.534505012742287 ], [ -2.260261260789144, 51.533952896041527 ], [ -2.260543347278885, 51.532082945866605 ], [ -2.260106145326577, 51.532016500422372 ], [ -2.260101260977379, 51.53143115652275 ], [ -2.260327047202351, 51.531068314177368 ], [ -2.259892490587377, 51.53046324931627 ], [ -2.260010220886866, 51.530369504016591 ], [ -2.259178452207264, 51.529868688884804 ], [ -2.258532336822606, 51.529050151486786 ], [ -2.257668117951575, 51.528415463018021 ], [ -2.255582616825308, 51.528738325055549 ], [ -2.254948892003327, 51.52856972579908 ], [ -2.253726135775975, 51.528764830840494 ], [ -2.252112431428694, 51.528138912678081 ], [ -2.252338235699779, 51.527792265462587 ], [ -2.252392342312548, 51.526874115846013 ], [ -2.25335726468908, 51.526720931049276 ], [ -2.253452895792945, 51.526285573103202 ], [ -2.253847693389477, 51.526005074924093 ], [ -2.254929684979947, 51.525665553904531 ], [ -2.254822567747257, 51.525318726522393 ], [ -2.254927141243429, 51.524423836638306 ], [ -2.254753507797949, 51.524040299402429 ], [ -2.25578802274791, 51.522958122763207 ], [ -2.25608166228582, 51.522363137049197 ], [ -2.255813394285843, 51.522078685630547 ], [ -2.260063186419594, 51.520440997151709 ], [ -2.262694592408256, 51.51963044397958 ], [ -2.263605912520164, 51.519220122759926 ], [ -2.263723183242187, 51.518559895144307 ], [ -2.267522325591904, 51.518574655869735 ], [ -2.271558441491479, 51.518214717231508 ], [ -2.275118236044667, 51.5175194844659 ], [ -2.279858696975647, 51.516169456014531 ], [ -2.28171764458475, 51.515453801463316 ], [ -2.286935844558597, 51.512937016514805 ], [ -2.291804971738683, 51.511120383694788 ], [ -2.296388488968322, 51.509746704272338 ], [ -2.296145602997476, 51.509629473722804 ], [ -2.296640630933542, 51.509076123414665 ], [ -2.296272893382791, 51.50881367869399 ], [ -2.297120656649234, 51.508008553723734 ], [ -2.296733816276589, 51.507456536277289 ], [ -2.296831239548753, 51.507366400514456 ], [ -2.296288470614796, 51.506766236258933 ], [ -2.297456226619446, 51.506215674042025 ], [ -2.299267223540902, 51.505537614663659 ], [ -2.306027043814682, 51.503970021057647 ], [ -2.306047524264091, 51.503800077113105 ], [ -2.308628707607018, 51.503501078869711 ], [ -2.311891892806919, 51.502864834409877 ], [ -2.315503173371846, 51.501321209815991 ], [ -2.319568160746804, 51.499180091802806 ], [ -2.32164335515492, 51.498256376226315 ], [ -2.324327612026502, 51.497510808267791 ], [ -2.319216187548819, 51.494571079854239 ], [ -2.317033425415605, 51.492437998715353 ], [ -2.313648119078655, 51.490477902014305 ], [ -2.313108413162778, 51.489288041489523 ], [ -2.311699042396277, 51.488119281523318 ], [ -2.311426066543476, 51.487374554528579 ], [ -2.310427625140803, 51.48815861212455 ], [ -2.309718863140244, 51.488148801856973 ], [ -2.308431340751925, 51.487509308731454 ], [ -2.306433849121015, 51.487096383611508 ], [ -2.306194554376773, 51.486845318802132 ], [ -2.30557792105783, 51.486811871525298 ], [ -2.304405494989342, 51.486359003919837 ], [ -2.304334262266213, 51.486271996216821 ], [ -2.304562518370548, 51.486151760401732 ], [ -2.30423488534722, 51.486042047497335 ], [ -2.304227737321248, 51.485842421679749 ], [ -2.303476154822628, 51.485869629426759 ], [ -2.3035853205518, 51.486036540959823 ], [ -2.302877021891276, 51.486091408546201 ], [ -2.302015238305951, 51.486441594645569 ], [ -2.301784313192037, 51.486356794651904 ], [ -2.301620187502669, 51.486587423953893 ], [ -2.30092878442126, 51.486793250445352 ], [ -2.300936771623596, 51.487122404866476 ], [ -2.300514345882352, 51.48727809866444 ], [ -2.299657210355987, 51.48725692239428 ], [ -2.29746756848404, 51.487829882938627 ], [ -2.297229195906795, 51.487713541734792 ], [ -2.295583519470492, 51.487795099113512 ], [ -2.294879289754339, 51.487584644574362 ], [ -2.293695399531571, 51.486905177677656 ], [ -2.29302422309459, 51.487123491337798 ], [ -2.292322791100819, 51.486901418719519 ], [ -2.291957748953834, 51.487010196043109 ], [ -2.291879126891313, 51.487324195684273 ], [ -2.291323443060973, 51.48736962427833 ], [ -2.291243824414293, 51.487081187442023 ], [ -2.290561163219666, 51.486859057639911 ], [ -2.290469127473108, 51.486652450375871 ], [ -2.2913403346894, 51.486629613003295 ], [ -2.290589110129043, 51.485353790659801 ], [ -2.290797294287423, 51.485265182596528 ], [ -2.29025211938896, 51.483541017227367 ], [ -2.290565632485446, 51.48347372204951 ], [ -2.29006778699791, 51.482186480420694 ], [ -2.289636073019261, 51.47883458139934 ], [ -2.288854223607366, 51.478151373711455 ], [ -2.290343425647054, 51.477076749383855 ], [ -2.291248236263149, 51.475574786851617 ], [ -2.291618977682161, 51.47296895501804 ], [ -2.291797137319134, 51.472928061144458 ], [ -2.292480342423038, 51.471003978652284 ], [ -2.292928732892267, 51.470214346700118 ], [ -2.29340384179224, 51.468652224258513 ], [ -2.29282324276102, 51.467459582496666 ], [ -2.294008002667127, 51.46722910467269 ], [ -2.294583910151932, 51.466787108741549 ], [ -2.294596668007473, 51.463849481012907 ], [ -2.295324494159185, 51.460439029015603 ], [ -2.295327787124616, 51.460269039130317 ], [ -2.295147423366591, 51.460199379619574 ], [ -2.295745836664805, 51.458591989233611 ], [ -2.293338497987202, 51.457786066917286 ], [ -2.289247209297006, 51.457653314873745 ], [ -2.287756899247483, 51.456871977186069 ], [ -2.286595464507621, 51.457113122192055 ], [ -2.285318593775271, 51.457988439808332 ], [ -2.285127718322855, 51.457846788746693 ], [ -2.28569081020863, 51.457448014054222 ], [ -2.287516533446205, 51.455503185593976 ], [ -2.288043189245482, 51.454564969894925 ], [ -2.288947326232272, 51.446422671186717 ], [ -2.290062603686001, 51.442576936718247 ], [ -2.294618432523423, 51.428803922025075 ], [ -2.297339474403669, 51.428966938562731 ], [ -2.298821308338191, 51.428800466006457 ], [ -2.299365317197626, 51.428185845329715 ], [ -2.301655894101443, 51.426323194288869 ], [ -2.301468951642616, 51.425902000097537 ], [ -2.303632600748276, 51.425099713067979 ], [ -2.303745377343799, 51.425189310998178 ], [ -2.30765264888681, 51.424692716342257 ], [ -2.308281915245369, 51.424366467685665 ], [ -2.30986819715063, 51.423085478885483 ], [ -2.312618000535081, 51.422448759188789 ], [ -2.313786503628844, 51.42317931996682 ], [ -2.313858415691777, 51.424017175355431 ], [ -2.313625244056836, 51.424409811864052 ], [ -2.313813048547551, 51.424526166327297 ], [ -2.313753731237151, 51.42490314566033 ], [ -2.313353675670733, 51.425291733959668 ], [ -2.313248042326039, 51.425607621551649 ], [ -2.313423871742777, 51.425879608840972 ], [ -2.313162514203234, 51.426574441144986 ], [ -2.313813658855941, 51.426933248557305 ], [ -2.313734524184037, 51.427135803684905 ], [ -2.314156354855844, 51.427395355009239 ], [ -2.314235597608735, 51.42764063292644 ], [ -2.314198244527835, 51.427848469665093 ], [ -2.313775000133464, 51.428213749903406 ], [ -2.3140211537505, 51.428656339369475 ], [ -2.313851662994252, 51.428913070898311 ], [ -2.315035265284715, 51.429501551473464 ], [ -2.316027523673754, 51.429684142455351 ], [ -2.317685798616933, 51.430271314615368 ], [ -2.317671591158113, 51.430496977771163 ], [ -2.317935134244953, 51.430550286805826 ], [ -2.31815268362895, 51.431016316579488 ], [ -2.318890992904203, 51.431274181727929 ], [ -2.32016262329909, 51.432102467649727 ], [ -2.321072772882244, 51.432455132915074 ], [ -2.321105467736228, 51.432601564421908 ], [ -2.321503676683643, 51.432558223730076 ], [ -2.322151120825305, 51.432791148406835 ], [ -2.322221035325296, 51.433119145440273 ], [ -2.322657028875526, 51.433337277536943 ], [ -2.323489365648337, 51.434471554198595 ], [ -2.324158535513619, 51.434718790188896 ], [ -2.324313453149454, 51.435256084750073 ], [ -2.324609585775717, 51.435434146064239 ], [ -2.324395817878863, 51.435513841634169 ], [ -2.324714439634884, 51.435818675497195 ], [ -2.325030701332412, 51.43699302301146 ], [ -2.326250558786503, 51.437176693511709 ], [ -2.326846062731041, 51.436967297236585 ], [ -2.327347839615824, 51.437120597185711 ], [ -2.328617552503092, 51.437043242363366 ], [ -2.328841536357162, 51.437180235729308 ], [ -2.329421040092333, 51.437139055857536 ], [ -2.329668646180636, 51.437360388116765 ], [ -2.330742727450224, 51.437475206586534 ], [ -2.330803193366376, 51.437684480028942 ], [ -2.331624328634414, 51.437643505593499 ], [ -2.331855670807563, 51.437795753702829 ], [ -2.332529868696965, 51.437530373678825 ], [ -2.332722084406294, 51.437652078581088 ], [ -2.333705945284229, 51.437429947949255 ], [ -2.335843181848731, 51.437540697558646 ], [ -2.336073688612981, 51.437383537636435 ], [ -2.338011617474452, 51.437987597491812 ], [ -2.33939979052212, 51.438159858630662 ], [ -2.342039017868961, 51.439405611677898 ], [ -2.342899262839726, 51.439388714467555 ], [ -2.343291703621747, 51.439535883968119 ], [ -2.343536547319605, 51.43918899906776 ], [ -2.34695150888321, 51.438555816183964 ], [ -2.347898691839339, 51.438617818049394 ], [ -2.350634634296108, 51.438379452428102 ], [ -2.351795628689918, 51.438741914956324 ], [ -2.35276755994155, 51.437919822582714 ], [ -2.353839267383765, 51.43735019208227 ], [ -2.354994777733106, 51.437204579829782 ], [ -2.355834931674494, 51.436821705257451 ], [ -2.356524142531584, 51.436280088404736 ], [ -2.357671508052502, 51.435840533260972 ], [ -2.358836478820275, 51.435788429959302 ], [ -2.360357288058508, 51.436188358014064 ], [ -2.361044927361707, 51.436553083083801 ], [ -2.361476070437141, 51.437405980881572 ], [ -2.364180388390411, 51.437176385540653 ], [ -2.364276926132984, 51.437382922938156 ], [ -2.36722065016053, 51.437056330187268 ], [ -2.369666568027833, 51.435827568030703 ], [ -2.370226754741977, 51.435897711328067 ], [ -2.371266402933215, 51.435488027109727 ], [ -2.371855449984981, 51.435037426392661 ], [ -2.373232868672892, 51.434424308871563 ], [ -2.375900285316555, 51.433759401141259 ], [ -2.377254988300567, 51.432833400613525 ], [ -2.379076928304628, 51.433453336222485 ], [ -2.38034100438552, 51.43410471976263 ], [ -2.383990014942615, 51.432662300885518 ], [ -2.384393361877749, 51.432729294855321 ], [ -2.385120311831114, 51.432280062224542 ], [ -2.38604284866309, 51.431988387823431 ], [ -2.388547975205006, 51.431901901513179 ], [ -2.391710134132683, 51.432117895219172 ], [ -2.393449335251461, 51.431951163373967 ], [ -2.396699500306869, 51.43202739676655 ], [ -2.397189015337444, 51.431252500618271 ], [ -2.397859144740923, 51.431392253674908 ], [ -2.399070319200484, 51.432059795665936 ], [ -2.401193261949073, 51.431700084573222 ], [ -2.403099850684236, 51.431597357282243 ], [ -2.403052615249566, 51.430812506385088 ], [ -2.404167412408649, 51.429664989238177 ], [ -2.405773698842572, 51.428647809061204 ], [ -2.409903011606075, 51.426535748523541 ], [ -2.411197695208569, 51.42607798323381 ], [ -2.413455334762511, 51.425862390099262 ], [ -2.414764171657084, 51.426331576833917 ], [ -2.416364089422934, 51.426074118140789 ], [ -2.417965077067512, 51.425312257679181 ], [ -2.420874394222553, 51.424335248346921 ], [ -2.424037132725166, 51.423718699723729 ], [ -2.427634457690852, 51.424214584649377 ], [ -2.430146729968987, 51.424172037973541 ], [ -2.431383616667874, 51.423725138169893 ], [ -2.435090830826496, 51.423359866425791 ], [ -2.435721843024884, 51.42347617692289 ], [ -2.436319064431456, 51.423206889024343 ], [ -2.437427288660864, 51.423290040236189 ], [ -2.438444417078307, 51.423171987039417 ], [ -2.439482301107175, 51.4228201313732 ], [ -2.44129840834571, 51.422493203738227 ], [ -2.442796687683437, 51.422753716751579 ], [ -2.444007287936907, 51.422571960342729 ], [ -2.444456702443487, 51.422351821819149 ], [ -2.444106095161139, 51.421046679781007 ], [ -2.44364522338434, 51.420535869035383 ], [ -2.441524990976041, 51.419293139309097 ], [ -2.443800295124112, 51.418281990296869 ], [ -2.44435714745618, 51.418605373908626 ], [ -2.445874727816165, 51.418947574983633 ], [ -2.446026152468695, 51.418254659879885 ], [ -2.446544496417276, 51.418019778247455 ], [ -2.450059766241879, 51.417365225176049 ], [ -2.452090632100411, 51.417539973756526 ], [ -2.454463124556206, 51.418385835459688 ], [ -2.455656484658474, 51.418513429382671 ], [ -2.457034839203075, 51.418143912609757 ], [ -2.457677771659074, 51.417722331676913 ], [ -2.458219444054347, 51.416957760334071 ], [ -2.458542680669806, 51.416782916405666 ], [ -2.460934245287635, 51.41666476321992 ], [ -2.464308721615182, 51.417321304225936 ], [ -2.465537090988903, 51.416927112153438 ], [ -2.467470971667353, 51.416610096935138 ], [ -2.469452417694516, 51.415904440709426 ], [ -2.470836795374536, 51.416566055073154 ], [ -2.472181409801494, 51.416989512664486 ], [ -2.473501225700361, 51.418074022536963 ], [ -2.474013144483518, 51.418205889767655 ], [ -2.47532494317067, 51.41809899814308 ], [ -2.47636017590216, 51.418499392112068 ], [ -2.478114220578245, 51.419844564829901 ], [ -2.479930061286118, 51.420751599804127 ], [ -2.48044065317562, 51.421441846211188 ], [ -2.481126745505313, 51.421589238244962 ], [ -2.48326889089541, 51.421391561027654 ], [ -2.484863965953019, 51.420717800812866 ], [ -2.486422898022738, 51.420586390447717 ], [ -2.487126831816338, 51.420114055652206 ], [ -2.488849203028705, 51.418445248716353 ], [ -2.49000859438625, 51.417671568409226 ], [ -2.492314344060039, 51.417989194639645 ], [ -2.492896217238615, 51.418347390364779 ], [ -2.492476915752655, 51.419732934076784 ], [ -2.49269734113127, 51.420846114794635 ], [ -2.492603803226562, 51.421376954089432 ], [ -2.490318457833817, 51.424044522614977 ], [ -2.488642676662168, 51.42523754288014 ], [ -2.488419221882386, 51.426267993688157 ], [ -2.488562059597947, 51.426717840785081 ], [ -2.490469800540346, 51.427977689444113 ], [ -2.491510027084896, 51.428942622210648 ], [ -2.493950565972149, 51.429432331120907 ], [ -2.496138756782668, 51.428672318239286 ], [ -2.496943341914825, 51.428587916916577 ], [ -2.49763657710615, 51.428843050996868 ], [ -2.497985652841876, 51.428803813751017 ], [ -2.502492411631867, 51.427128334687595 ], [ -2.503974808213247, 51.426029434806466 ], [ -2.505721143200838, 51.425664054718261 ], [ -2.507297873076301, 51.424785027606255 ], [ -2.508181153282117, 51.424672431922787 ], [ -2.508468213531788, 51.425011063805762 ], [ -2.50807417306847, 51.426445183679157 ], [ -2.508156085394993, 51.427468055636957 ], [ -2.508287437924941, 51.427901748376897 ], [ -2.508997829326568, 51.428532574389408 ], [ -2.509579648242662, 51.428734187427395 ], [ -2.510461966465064, 51.428784281274602 ], [ -2.510419161188802, 51.428944563262625 ], [ -2.510856616284203, 51.429089178766858 ], [ -2.510419822352514, 51.429131533233289 ], [ -2.510700442208358, 51.429271528873905 ], [ -2.511884653746007, 51.429305014351328 ], [ -2.51360473910797, 51.429670623776509 ], [ -2.516990751823846, 51.43081838008483 ], [ -2.519901695673812, 51.431277516618991 ], [ -2.521795980150971, 51.431763675342047 ], [ -2.523541877569515, 51.432608231899067 ], [ -2.525354513632164, 51.434126014755655 ], [ -2.527097373490651, 51.436444380532748 ], [ -2.526800511356212, 51.439394939807954 ], [ -2.526892505258131, 51.440894352121603 ], [ -2.526448412196593, 51.442558875658335 ], [ -2.526574087917753, 51.443604098574191 ], [ -2.527418159918259, 51.444426577209434 ], [ -2.528576453970668, 51.445057064718974 ], [ -2.531054825778265, 51.44560066445834 ], [ -2.537211507978284, 51.444579940266195 ], [ -2.538618795127773, 51.445075160126166 ], [ -2.539327182876971, 51.445719294421117 ], [ -2.539118504967807, 51.446334387376638 ], [ -2.538127393846533, 51.446850600122666 ], [ -2.535606413392633, 51.447342344892412 ], [ -2.535036698232074, 51.446612968237154 ], [ -2.534768089241134, 51.446531494944679 ], [ -2.531666127259257, 51.446444032853691 ], [ -2.530480785888674, 51.447468134597301 ], [ -2.530457914435372, 51.44785935200666 ], [ -2.529931314909733, 51.448233971319823 ], [ -2.528952334961618, 51.448570180245696 ], [ -2.527229495940143, 51.448666126527861 ], [ -2.52612412554339, 51.449146705180567 ], [ -2.525511320983162, 51.449158443829916 ], [ -2.525582484141521, 51.448970253474194 ], [ -2.525129291664243, 51.448974082934328 ], [ -2.524211391187317, 51.449374699611788 ], [ -2.522362457929481, 51.449767776975627 ], [ -2.521770528436976, 51.450102199824691 ], [ -2.518936662239174, 51.452612659558362 ], [ -2.519176744023299, 51.453734687510511 ], [ -2.518661596062758, 51.45411819388341 ], [ -2.51835197701242, 51.455372096932535 ], [ -2.519183009566746, 51.457067796432831 ], [ -2.51921463484984, 51.457574817897644 ], [ -2.518602506948954, 51.458169186665678 ], [ -2.518463064536292, 51.459079763794421 ], [ -2.51671161329898, 51.459610750537649 ], [ -2.516228146123298, 51.460001387133246 ], [ -2.515362342221042, 51.459933195405426 ], [ -2.515184052731389, 51.460467208715613 ], [ -2.514258014197855, 51.461438765222773 ], [ -2.513033576690709, 51.461617709680489 ], [ -2.513289884153927, 51.462142535578245 ], [ -2.512749526300702, 51.46221690300343 ], [ -2.512683754841838, 51.462384386675645 ], [ -2.512245618129016, 51.462335064982327 ], [ -2.512148694390968, 51.463059285128431 ], [ -2.511660075590919, 51.463908455303162 ], [ -2.511346460297257, 51.465209996624935 ], [ -2.512248781988785, 51.465319318116848 ], [ -2.513251658419395, 51.465662985685391 ], [ -2.512899157060823, 51.466193173288431 ], [ -2.512875186520338, 51.467262432510502 ], [ -2.512589751852669, 51.467476720994071 ], [ -2.512284196013724, 51.468607437423287 ], [ -2.512639243655309, 51.468683190616758 ], [ -2.512451654371601, 51.468901635099172 ], [ -2.512922685086454, 51.469052388035543 ], [ -2.512929661644513, 51.469293353095651 ], [ -2.51261668824106, 51.470398034347717 ], [ -2.511507680255672, 51.470231998206195 ], [ -2.510834800222967, 51.471596229280891 ], [ -2.51118470181449, 51.473407428149535 ], [ -2.511181894874503, 51.474186158420139 ], [ -2.512851834740658, 51.477497605540336 ], [ -2.513758411219981, 51.478861312622648 ], [ -2.514339460143644, 51.479431453888999 ], [ -2.514469956460948, 51.480023436287802 ], [ -2.515264422088594, 51.481523357205255 ], [ -2.515045831438118, 51.481544093669136 ], [ -2.515127454913194, 51.481759560894538 ], [ -2.516711062657161, 51.485156814385789 ], [ -2.511392682866152, 51.489291071947093 ], [ -2.510998616176547, 51.489987818835097 ], [ -2.515965292699978, 51.49257448753584 ], [ -2.515318360688447, 51.493076401452541 ], [ -2.515864591612921, 51.493868804894959 ], [ -2.516144889888083, 51.493554664664181 ], [ -2.517471141250464, 51.493272856152323 ], [ -2.518036885273835, 51.492986215747784 ], [ -2.520685565301794, 51.492583280791386 ], [ -2.523339917816512, 51.492441120983557 ], [ -2.525329534189247, 51.493227028244597 ], [ -2.527472072823452, 51.492655506097186 ], [ -2.527702526012364, 51.492907059506628 ], [ -2.527852809918305, 51.493569140908868 ], [ -2.527972134880103, 51.493556018990695 ], [ -2.527937832217857, 51.493824944152962 ], [ -2.528554516201714, 51.494086531457974 ], [ -2.528100079266846, 51.494401486025005 ], [ -2.528133876379425, 51.494828490322085 ], [ -2.527753258136073, 51.49492368981862 ], [ -2.529295364362595, 51.495992089642954 ], [ -2.529228473366476, 51.496184845746058 ], [ -2.529477550058349, 51.496298780059135 ], [ -2.529665962456461, 51.496148711852527 ], [ -2.530276857790714, 51.496409417320955 ], [ -2.531740755697126, 51.495698679600174 ], [ -2.53280061209391, 51.496285522541712 ], [ -2.534328646652024, 51.496746175029529 ], [ -2.537703385892039, 51.497074214406524 ], [ -2.537676347706461, 51.496855816209795 ], [ -2.538375688499714, 51.495576710156051 ], [ -2.538950900571979, 51.495003985647195 ], [ -2.541742620519305, 51.49574196846558 ], [ -2.542536588950806, 51.494551390819929 ], [ -2.542160504042497, 51.492954438697545 ], [ -2.543865349930368, 51.492665995532384 ], [ -2.545049146070618, 51.492644317505686 ], [ -2.545559350816182, 51.492793858290661 ], [ -2.551850262783649, 51.492250153506568 ], [ -2.555347027951369, 51.492687675301788 ], [ -2.556154598390171, 51.49406230949171 ], [ -2.554661223755787, 51.496349622171287 ], [ -2.556824647167915, 51.496564181506287 ], [ -2.560075855413039, 51.49644343358829 ], [ -2.560511518675352, 51.495911809920038 ], [ -2.5612237341189, 51.495608080366615 ], [ -2.56158974440823, 51.495856221707228 ], [ -2.562239740609839, 51.495293900944816 ], [ -2.564787832640362, 51.495517164906069 ], [ -2.564719116031625, 51.49613611856315 ], [ -2.565337700386616, 51.496186172360431 ], [ -2.565063980529813, 51.497582134299947 ], [ -2.565971636575172, 51.498289864073463 ], [ -2.567765482879168, 51.498889026255583 ], [ -2.569086105722617, 51.4995506852311 ], [ -2.569926486249777, 51.49924717973763 ], [ -2.57309445728215, 51.500403362180528 ], [ -2.57547593025771, 51.500753144451373 ], [ -2.577194691972206, 51.500750987782475 ], [ -2.578116463272656, 51.500958676332253 ], [ -2.579832019799019, 51.500712805243843 ], [ -2.58122008711461, 51.501223878060308 ], [ -2.581713820262912, 51.501191765734482 ], [ -2.582495537417829, 51.501601468145026 ], [ -2.582412847788992, 51.501777254174989 ], [ -2.584517162202276, 51.502642489736225 ], [ -2.585626402104035, 51.501845743350223 ], [ -2.585243045927762, 51.501157123061944 ], [ -2.588148450865404, 51.5012360698394 ], [ -2.587761271283397, 51.502606495880372 ], [ -2.587674642313055, 51.503379354223007 ], [ -2.587847335315288, 51.50381094887954 ], [ -2.587712718651984, 51.504436538353943 ], [ -2.58787508687405, 51.5049608611331 ], [ -2.588319705027256, 51.505133916291669 ], [ -2.588510598355956, 51.505529552476681 ], [ -2.588535841258577, 51.506483427055812 ], [ -2.588389922035093, 51.507347281887014 ], [ -2.588018865780922, 51.507731355004374 ], [ -2.588544322950741, 51.507694470597357 ], [ -2.589627626832567, 51.508233940201421 ], [ -2.590501514863232, 51.508406715278355 ], [ -2.591221241854905, 51.509683479299852 ], [ -2.590266761739933, 51.51075015662127 ], [ -2.589226405269918, 51.511536801316517 ], [ -2.585850346680231, 51.512672216557 ], [ -2.58510429895361, 51.512476386429633 ], [ -2.584146139907678, 51.512825531418009 ], [ -2.582974053247217, 51.513012941999385 ], [ -2.582540818911891, 51.513391912987785 ], [ -2.582384899449814, 51.514162323448495 ], [ -2.581400022479722, 51.515580636884849 ], [ -2.580986634999152, 51.517409783729477 ], [ -2.585022533700172, 51.517342076062555 ], [ -2.587987700546971, 51.517063778295423 ], [ -2.594265366994196, 51.515840822820017 ], [ -2.594118496179937, 51.515739901758174 ], [ -2.59449754245414, 51.51552125642678 ], [ -2.594662638434277, 51.515689501908327 ], [ -2.595422922016071, 51.515311612481483 ], [ -2.598882276411231, 51.514705037511504 ], [ -2.601700744778099, 51.513917376602805 ], [ -2.606324272607675, 51.513523034263109 ], [ -2.609743672512172, 51.513397435331932 ], [ -2.612446284179514, 51.513549736658661 ], [ -2.621091826402241, 51.514867351906723 ], [ -2.622724208687345, 51.514521517377617 ], [ -2.626128036050305, 51.514730902792444 ], [ -2.627509379646895, 51.514571514959634 ], [ -2.634750917268544, 51.512716222769569 ], [ -2.638773649366454, 51.512047889060142 ], [ -2.638942241281022, 51.512149534984587 ], [ -2.645087403488808, 51.511992649781718 ], [ -2.648479568149587, 51.512298531898864 ], [ -2.652537444555164, 51.513099682654421 ], [ -2.654483106980029, 51.513725440268821 ], [ -2.65395502695915, 51.514484541243426 ], [ -2.65438993439304, 51.514561218206538 ], [ -2.654490757962858, 51.514963542475684 ], [ -2.654109036699217, 51.515472741834152 ], [ -2.653201281379614, 51.516090132444795 ], [ -2.653728536182441, 51.517586109371457 ], [ -2.653823702797999, 51.51819071791968 ], [ -2.653685643649464, 51.518714826819505 ], [ -2.652756280580995, 51.51923875854358 ], [ -2.65271461572452, 51.519649068271576 ], [ -2.652264449754476, 51.51991315271129 ], [ -2.651662232979636, 51.519931872008051 ], [ -2.651476268438206, 51.520232238664335 ], [ -2.651671514267032, 51.520581904204199 ], [ -2.651399366259446, 51.520705666512136 ], [ -2.652666307491629, 51.521813616249268 ], [ -2.652599796176256, 51.52189938179135 ], [ -2.653650670722635, 51.523118188639678 ], [ -2.657408607752302, 51.525943005169488 ], [ -2.658090906219495, 51.526774434702013 ], [ -2.660125923298637, 51.527648681882219 ], [ -2.663365496972627, 51.52965894555507 ], [ -2.663494231679165, 51.529594305654562 ], [ -2.665420031175603, 51.530967248167606 ], [ -2.664609444562704, 51.531533835477084 ], [ -2.66572338504938, 51.533681006819137 ], [ -2.663733938541788, 51.534870107927546 ], [ -2.664472870768095, 51.536014175075593 ], [ -2.663684061990169, 51.536997810005971 ], [ -2.673808750932124, 51.544432744190644 ], [ -2.67755183351855, 51.5405250712315 ], [ -2.67831306032973, 51.539541412780807 ], [ -2.679758251112324, 51.538219397245342 ], [ -2.680647464494658, 51.537222486551883 ], [ -2.680592295631178, 51.537102354420668 ], [ -2.68104734902308, 51.536775120950985 ], [ -2.68099146712508, 51.536607261667989 ], [ -2.681362104383632, 51.536223886490319 ], [ -2.681257585224592, 51.536078782312018 ], [ -2.681537674409133, 51.535722000496889 ], [ -2.680858999229015, 51.53555335394082 ], [ -2.680424258342531, 51.535018156181742 ], [ -2.681188033239811, 51.535576612495873 ], [ -2.682039010220572, 51.535693018109825 ], [ -2.682768288262449, 51.534905654921999 ], [ -2.682992959830558, 51.534889964399397 ], [ -2.682927239049214, 51.534740141232767 ], [ -2.683105318327449, 51.534502604058417 ], [ -2.684524867045481, 51.533218431126087 ], [ -2.684481098198971, 51.533082054021037 ], [ -2.685012683054738, 51.532481003082218 ], [ -2.685843601761002, 51.531938425756593 ], [ -2.685850677643139, 51.53173703107538 ], [ -2.686224603789832, 51.531395869056247 ], [ -2.686864701013342, 51.530339151857532 ], [ -2.686866385639578, 51.530072079110106 ], [ -2.687152372158209, 51.529914894290592 ], [ -2.687028148280427, 51.529416553321042 ], [ -2.687320660746971, 51.529314162680024 ], [ -2.687978154292548, 51.529422669903397 ], [ -2.692735438886793, 51.524677689989183 ], [ -2.694416281310978, 51.523272296475277 ], [ -2.694674933480761, 51.523213234982549 ], [ -2.694587507768936, 51.523153526502455 ], [ -2.695209631143482, 51.52245831598561 ], [ -2.701622615132472, 51.522668309659231 ], [ -2.698994770384039, 51.524915702429425 ], [ -2.698822850881668, 51.525268286892242 ], [ -2.69911949252715, 51.525431107497099 ], [ -2.7005273645545, 51.525222161511344 ], [ -2.700863092427152, 51.525399126641567 ], [ -2.702055146125604, 51.525206733196683 ], [ -2.702355306762784, 51.525419862998895 ], [ -2.70229189955465, 51.525794275149217 ], [ -2.70209557852241, 51.526058019404793 ], [ -2.701320784540003, 51.526381854788085 ], [ -2.699427489996249, 51.526621572133074 ], [ -2.698877690157024, 51.527056411713524 ], [ -2.698899747527976, 51.527464470720425 ], [ -2.698244606265581, 51.527890136955534 ], [ -2.698368981726668, 51.528103334530037 ], [ -2.698956566064365, 51.528256332523817 ], [ -2.698537066790418, 51.529098673915499 ], [ -2.699317154252495, 51.52986815726161 ], [ -2.69851954705254, 51.529934035739707 ], [ -2.698292953118196, 51.530101771421457 ], [ -2.698254970604742, 51.530633337016077 ], [ -2.697956601096445, 51.531020021757762 ], [ -2.697986040008019, 51.531437025712506 ], [ -2.697282986003121, 51.531749620103191 ], [ -2.696700917649108, 51.532427433406937 ], [ -2.696637198741557, 51.532792854796348 ], [ -2.697178676957101, 51.533316571807518 ], [ -2.697110875354893, 51.53340686472405 ], [ -2.696578868096014, 51.53341002570739 ], [ -2.696231289082928, 51.53311356526271 ], [ -2.696047364886485, 51.533531925825379 ], [ -2.696242802162317, 51.533867942729671 ], [ -2.69650299856382, 51.53391403943192 ], [ -2.697428505848638, 51.533718781941381 ], [ -2.697203789666467, 51.534018642324412 ], [ -2.697411247263409, 51.534098309773093 ], [ -2.696921351754177, 51.534399746153227 ], [ -2.697159998550778, 51.534645614862896 ], [ -2.697754084173317, 51.534651070957032 ], [ -2.697242582092398, 51.535047920443624 ], [ -2.697434394822624, 51.535612366993661 ], [ -2.697195355587728, 51.535916806908375 ], [ -2.697236702053584, 51.536638646266631 ], [ -2.696919712778699, 51.536844580211728 ], [ -2.696804300809722, 51.537219297544937 ], [ -2.696299034680646, 51.53708476684502 ], [ -2.695777550079904, 51.537297394816456 ], [ -2.695704079135105, 51.537491992668045 ], [ -2.696483291627036, 51.537629483844221 ], [ -2.696494385509172, 51.537881109467122 ], [ -2.696238640024637, 51.538034631592673 ], [ -2.694675821381771, 51.537854141031886 ], [ -2.695093279768842, 51.538287813085695 ], [ -2.694713710777112, 51.538921268155818 ], [ -2.694719859089435, 51.539324926802635 ], [ -2.695081747718122, 51.539512540049074 ], [ -2.695827743836139, 51.539551263787864 ], [ -2.696277792235068, 51.540132157461066 ], [ -2.695747511267196, 51.540339354055519 ], [ -2.695622814402168, 51.540581987072891 ], [ -2.694717300542827, 51.540577466170561 ], [ -2.694894884516957, 51.540785947238987 ], [ -2.694846613492404, 51.541113521857888 ], [ -2.695367537766311, 51.54132886676598 ], [ -2.695536227740241, 51.541897048500729 ], [ -2.694529114796858, 51.542709597085768 ], [ -2.69440346689533, 51.542976504541436 ], [ -2.693784647686764, 51.543345208717405 ], [ -2.69380653205183, 51.543744279527317 ], [ -2.693605431750988, 51.5440772518497 ], [ -2.693852291545392, 51.544759133361808 ], [ -2.693985264188151, 51.545066758249654 ], [ -2.694645048705034, 51.545395534447103 ], [ -2.694616965073065, 51.545542310858799 ], [ -2.693431882414902, 51.546128392334168 ], [ -2.693281229761784, 51.546276701957225 ], [ -2.693741185331564, 51.546459245065215 ], [ -2.691506849652164, 51.547758220504541 ], [ -2.691717692359412, 51.548065388689473 ], [ -2.691293798962213, 51.54826204933493 ], [ -2.691556159851033, 51.548445765345157 ], [ -2.692126717527532, 51.548409140892907 ], [ -2.693467237478764, 51.547984045398486 ], [ -2.694750479521598, 51.547297515066411 ], [ -2.696330986579673, 51.546068969127333 ], [ -2.696715687932674, 51.545387747751185 ], [ -2.697375788712492, 51.544794867530797 ], [ -2.697552934385552, 51.544405400669682 ], [ -2.69787048192171, 51.544232721264102 ], [ -2.699634100352611, 51.544141224124949 ], [ -2.700936830071498, 51.544650492072194 ], [ -2.700898695728592, 51.544985199654995 ], [ -2.701144767927332, 51.545701228769019 ], [ -2.700956911261675, 51.546328163766219 ], [ -2.700479059496729, 51.546762668819021 ], [ -2.699571849644603, 51.546756397452626 ], [ -2.698575753098539, 51.546970878237602 ], [ -2.698220757637854, 51.547238256417764 ], [ -2.698839279045093, 51.547229179553526 ], [ -2.698852466203461, 51.547337058499402 ], [ -2.697791050971926, 51.54780639939522 ], [ -2.697213522460419, 51.54738636341505 ], [ -2.696370750592217, 51.548104374750189 ], [ -2.695628893086032, 51.548252600163615 ], [ -2.692877921840326, 51.549720150796787 ], [ -2.69156022100553, 51.550994831226639 ], [ -2.687379625768219, 51.552837510754955 ], [ -2.686461241670178, 51.553060511486521 ], [ -2.68450867451906, 51.552789578928312 ], [ -2.683223441877977, 51.55287977027902 ], [ -2.681240365898319, 51.553557565232602 ], [ -2.680356526376604, 51.554066255958674 ], [ -2.679693688867009, 51.554587053108051 ], [ -2.679750982555675, 51.555334871332846 ], [ -2.680365838960501, 51.55469021486077 ], [ -2.681789044741508, 51.553699189434361 ], [ -2.682754623824235, 51.553353611036066 ], [ -2.684735384512057, 51.55329172704846 ], [ -2.685406805243107, 51.553528799598013 ], [ -2.685995444646741, 51.553543336520079 ], [ -2.68609190421162, 51.553718146854727 ], [ -2.685527041839142, 51.554620614292652 ], [ -2.684710687458398, 51.555194472824276 ], [ -2.684545591049696, 51.55563607474194 ], [ -2.684167254708911, 51.555895455841068 ], [ -2.683909976887423, 51.556431888473035 ], [ -2.68331398801285, 51.556802200691713 ], [ -2.683462818844772, 51.557011764896849 ], [ -2.683136567840919, 51.557279828039825 ], [ -2.682870915733249, 51.557846060404366 ], [ -2.682291077817255, 51.557843142138367 ], [ -2.682385110455758, 51.557959451462999 ], [ -2.682048725851442, 51.558131388746951 ], [ -2.681976481306843, 51.558509434347513 ], [ -2.681359051512256, 51.558705385663913 ], [ -2.681118773750268, 51.559029663902521 ], [ -2.679700270387211, 51.559869548568201 ], [ -2.67895080629324, 51.56001061052303 ], [ -2.680278090193959, 51.560986580724332 ], [ -2.680393991615726, 51.560631654406237 ], [ -2.682333246929514, 51.559794037083073 ], [ -2.683669361318805, 51.559911204068733 ], [ -2.683739409536964, 51.559387549402267 ], [ -2.684197987304759, 51.559384875612807 ], [ -2.684142916603938, 51.559654056114951 ], [ -2.685426622095259, 51.559647461308067 ], [ -2.685269024216872, 51.560097919131124 ], [ -2.685631744137873, 51.559952875478388 ], [ -2.686182833381707, 51.559379574338855 ], [ -2.68687194805018, 51.559253201804815 ], [ -2.686999654279246, 51.559306387641954 ], [ -2.68692954131392, 51.559728559536481 ], [ -2.687413390713974, 51.559768872135059 ], [ -2.687371071206082, 51.560022698247082 ], [ -2.689295579143514, 51.560508584205671 ], [ -2.691773580381619, 51.56058847123343 ], [ -2.693131271771177, 51.560220809234025 ], [ -2.693719571258084, 51.560300928904653 ], [ -2.693690457834232, 51.560474587738199 ], [ -2.693920500155328, 51.560514576332238 ], [ -2.694143613502586, 51.560864903904381 ], [ -2.694009548088574, 51.561629038375827 ], [ -2.694158367170776, 51.561646135746692 ], [ -2.69446833895352, 51.561443757760806 ], [ -2.694611502628538, 51.560707434584941 ], [ -2.695036088031769, 51.560362350971168 ], [ -2.695875299019506, 51.560337600057693 ], [ -2.699136381464774, 51.55926892975922 ], [ -2.699859191005196, 51.559279001995677 ], [ -2.700869751843892, 51.558673225727368 ], [ -2.701482412758742, 51.558736980817613 ], [ -2.701681160681132, 51.558621632457367 ], [ -2.702124020112757, 51.558903932415781 ], [ -2.702048189073126, 51.55903841154764 ], [ -2.702238092785115, 51.559198177121239 ], [ -2.702021739014623, 51.559568198885458 ], [ -2.702444267610848, 51.559842529225854 ], [ -2.702412923479042, 51.560525247939502 ], [ -2.702578385040446, 51.560588078628214 ], [ -2.702673626987218, 51.560964235062876 ], [ -2.702470368542186, 51.561821469997248 ], [ -2.701515164832503, 51.562649854477662 ], [ -2.701071343439686, 51.564464319439836 ], [ -2.700539537108479, 51.564968360275245 ], [ -2.699324571920375, 51.565332560100394 ], [ -2.698153080232338, 51.566928332847631 ], [ -2.697913956012818, 51.56705110633078 ], [ -2.697754341947896, 51.567930544650288 ], [ -2.697289221510121, 51.567985445947656 ], [ -2.6971812200107, 51.568188428786961 ], [ -2.698094552216399, 51.568853751917104 ], [ -2.69713548459912, 51.569257754667227 ], [ -2.694318382777464, 51.56987689931168 ], [ -2.694073000658189, 51.570059118728118 ], [ -2.694452651050891, 51.570162941425203 ], [ -2.694655862483892, 51.570523183305539 ], [ -2.694918477164453, 51.570620596169547 ], [ -2.697535271722502, 51.570109596729864 ], [ -2.697897067422784, 51.570181154297813 ], [ -2.697976126732926, 51.570449542962471 ], [ -2.710695408398487, 51.569641301536727 ], [ -2.708535439045781, 51.573629453747742 ], [ -2.706472787268318, 51.576751163301694 ], [ -2.703667559818078, 51.580301747109019 ], [ -2.702485889197005, 51.581260125521759 ], [ -2.699627926523646, 51.583019703705283 ], [ -2.694052604983358, 51.585383461091077 ], [ -2.689369198668501, 51.586641113170373 ], [ -2.682679588317429, 51.587921053973247 ], [ -2.680195357338215, 51.588590053158882 ], [ -2.671186476667818, 51.591698065720998 ], [ -2.66743746803905, 51.593265988707948 ], [ -2.663107571048552, 51.595895425931324 ], [ -2.658458343155317, 51.598052510207552 ], [ -2.654751566618742, 51.599006566549271 ], [ -2.651091751595601, 51.599517902559313 ], [ -2.647470941994793, 51.600341721603066 ], [ -2.646303957569757, 51.600827441200011 ], [ -2.645465640742998, 51.60137246598088 ], [ -2.642623925956069, 51.604324633594018 ], [ -2.640286123034171, 51.607086114805206 ], [ -2.638528900209647, 51.608748289742351 ], [ -2.63786424539474, 51.609849802377788 ], [ -2.637631963875533, 51.611516248594299 ], [ -2.637770526881691, 51.612125119132898 ], [ -2.638525533828323, 51.613343855956828 ], [ -2.639291026654889, 51.614170437347433 ], [ -2.64487120411163, 51.61668267111466 ], [ -2.6468012663864, 51.618745505628105 ], [ -2.647324265799068, 51.620072430758896 ], [ -2.64743797512391, 51.621567995194283 ], [ -2.647157145031922, 51.623049555407562 ], [ -2.64663724525002, 51.624580971615224 ], [ -2.645400705605619, 51.627024379151379 ], [ -2.644348446019458, 51.628519159281694 ], [ -2.643247995316836, 51.629668933000374 ], [ -2.641106620802154, 51.631597604357381 ], [ -2.636556277607092, 51.634233440746591 ], [ -2.633947261501882, 51.636545729453495 ], [ -2.632556223869354, 51.637094539865821 ], [ -2.628887610656303, 51.6416000233516 ] ] ] }' ] ]; + }, + sub (GET + /area/*) { my ($self, $area) = @_; my $response; @@ -104,8 +131,8 @@ sub dispatch_request { my ($self, $area) = @_; if ($area eq '2514') { return $self->output({ - 8794 => {parent_area => 2514, id => 8794, name => "Aston", type => "MTW"}, - 8773 => {parent_area => 2514, id => 8773, name => "Bournville", type => "MTW"}, + 151907 => {parent_area => 2514, id => 151907, name => "Bordesley & Highgate", type => "MTW"}, + 151942 => {parent_area => 2514, id => 151942, name => "Birchfield", type => "MTW"}, }); } if ($area eq '2326') { diff --git a/t/Mock/Nominatim.pm b/t/Mock/Nominatim.pm index 1f4e248d2..806ebbfd3 100644 --- a/t/Mock/Nominatim.pm +++ b/t/Mock/Nominatim.pm @@ -39,6 +39,6 @@ sub query { return []; } - +LWP::Protocol::PSGI->register(t::Mock::Nominatim->to_psgi_app, host => 'nominatim.openstreetmap.org'); __PACKAGE__->run_if_script; diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index b69a711c8..d50702086 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -1,3 +1,9 @@ +package FixMyStreet::Cobrand::OxfordshireUTA; +use parent 'FixMyStreet::Cobrand::Oxfordshire'; +sub area_types { [ 'UTA' ] } + +package main; + use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -8,6 +14,7 @@ my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super Us my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council'); my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire); +$oxfordshireuser->user_body_permissions->create({ body => $oxfordshire, permission_type => 'category_edit' }); my $dt = DateTime->new( year => 2011, @@ -129,35 +136,51 @@ subtest 'check summary counts' => sub { subtest "Check admin_base_url" => sub { my $rs = FixMyStreet::App->model('DB::Problem'); - my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($report->cobrand)->new(); + my $cobrand = $report->get_cobrand_logged; is ($report->admin_url($cobrand), (sprintf 'http://www.example.org/admin/report_edit/%d', $report_id), 'get_admin_url OK'); }; +subtest "Check body dropdown on admin index page" => sub { + FixMyStreet::override_config { + MAPIT_TYPES => [ 'UTA' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + ok $mech->get('/admin'); + $mech->submit_form_ok({ with_fields => { body => $oxfordshire->id } }); + }; +}; + # Finished with the superuser tests $mech->log_out_ok; subtest "Users without from_body can't access admin" => sub { $mech->log_in_ok( $user->email ); - ok $mech->get('/admin'); is $mech->res->code, 403, "got 403"; - - $mech->log_out_ok; }; +$mech->log_in_ok( $oxfordshireuser->email ); + subtest "Users with from_body can access their own council's admin" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], }, sub { - $mech->log_in_ok( $oxfordshireuser->email ); - $mech->get_ok('/admin'); $mech->content_contains( 'FixMyStreet admin:' ); + }; +}; - $mech->log_out_ok; + +subtest "Check admin index page redirects" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshireuta' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + ok $mech->get('/admin/bodies'); + is $mech->uri->path, '/admin/body/' . $oxfordshire->id, 'body redirects okay'; }; }; @@ -165,12 +188,8 @@ subtest "Users with from_body can't access another council's admin" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'bristol' ], }, sub { - $mech->log_in_ok( $oxfordshireuser->email ); - ok $mech->get('/admin'); is $mech->res->code, 403, "got 403"; - - $mech->log_out_ok; }; }; @@ -178,12 +197,8 @@ subtest "Users with from_body can't access fixmystreet.com admin" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'fixmystreet' ], }, sub { - $mech->log_in_ok( $oxfordshireuser->email ); - ok $mech->get('/admin'); is $mech->res->code, 403, "got 403"; - - $mech->log_out_ok; }; }; diff --git a/t/app/controller/admin/bodies.t b/t/app/controller/admin/bodies.t index a485d286d..f67e45bf6 100644 --- a/t/app/controller/admin/bodies.t +++ b/t/app/controller/admin/bodies.t @@ -1,9 +1,17 @@ +package FixMyStreet::Cobrand::Tester; + +use parent 'FixMyStreet::Cobrand::Default'; + +sub enable_category_groups { 1 } + +package main; use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1); $mech->log_in_ok( $superuser->email ); +my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); # This override is wrapped around ALL the /admin/body tests FixMyStreet::override_config { @@ -12,7 +20,6 @@ FixMyStreet::override_config { BASE_URL => 'http://www.example.org', }, sub { -my $body = $mech->create_body_ok(2650, 'Aberdeen City Council'); $mech->get_ok('/admin/body/' . $body->id); $mech->content_contains('Aberdeen City Council'); $mech->content_like(qr{AB\d\d}); @@ -56,6 +63,7 @@ subtest 'check contact creation' => sub { subtest 'check contact editing' => sub { $mech->get_ok('/admin/body/' . $body->id .'/test%20category'); + $mech->content_lacks( 'group</strong> is used for the top-level category' ); $mech->submit_form_ok( { with_fields => { email => 'test2@example.com', @@ -201,4 +209,47 @@ subtest 'check text output' => sub { }; # END of override wrap +FixMyStreet::override_config { + ALLOWED_COBRANDS => ['tester'], + MAPIT_URL => 'http://mapit.uk/', + MAPIT_TYPES => [ 'UTA' ], + BASE_URL => 'http://www.example.org', +}, sub { + subtest 'group editing works' => sub { + $mech->get_ok('/admin/body/' . $body->id); + $mech->content_contains( 'group</strong> is used for the top-level category' ); + + $mech->submit_form_ok( { with_fields => { + category => 'grouped category', + email => 'test@example.com', + note => 'test note', + group => 'group a', + non_public => undef, + state => 'unconfirmed', + } } ); + + my $contact = $body->contacts->find({ category => 'grouped category' }); + is $contact->get_extra_metadata('group'), 'group a', "group stored correctly"; + }; + + subtest 'group can be unset' => sub { + $mech->get_ok('/admin/body/' . $body->id); + $mech->content_contains( 'group</strong> is used for the top-level category' ); + + $mech->submit_form_ok( { with_fields => { + category => 'grouped category', + email => 'test@example.com', + note => 'test note', + group => undef, + non_public => undef, + state => 'unconfirmed', + } } ); + + my $contact = $body->contacts->find({ category => 'grouped category' }); + is $contact->get_extra_metadata('group'), undef, "group unset correctly"; + }; + +}; + + done_testing(); diff --git a/t/app/controller/admin/defecttypes.t b/t/app/controller/admin/defecttypes.t index e7d0e42af..12ae8948c 100644 --- a/t/app/controller/admin/defecttypes.t +++ b/t/app/controller/admin/defecttypes.t @@ -1,4 +1,5 @@ use FixMyStreet::TestMech; +use Test::MockModule; my $mech = FixMyStreet::TestMech->new; @@ -26,8 +27,32 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['bromley'], }, sub { FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cobrand->mock('available_permissions', sub { + my $self = shift; + + my $perms = FixMyStreet::Cobrand::Default->available_permissions; + $perms->{Bodies}->{defect_type_edit} = "Add/edit defect types"; + + return $perms; + }); + my $body = $mech->create_body_ok( 2237, 'Oxfordshire County Council' ); + subtest 'check defect types menu available to superusers' => sub { + my $user = $mech->create_user_ok( + 'superuser@example.com', + name => 'Test Superuser', + is_superuser => 1 + ); + + $mech->log_in_ok( $user->email ); + $mech->get_ok('/admin'); + $mech->content_contains('Defect Types'); + $mech->get_ok('/admin/defecttypes'); + $mech->log_out_ok(); + }; + my $user = $mech->create_user_ok( 'oxford@example.com', name => 'Test User', diff --git a/t/app/controller/admin/permissions.t b/t/app/controller/admin/permissions.t index 7944cc0b1..ff5a8ec4f 100644 --- a/t/app/controller/admin/permissions.t +++ b/t/app/controller/admin/permissions.t @@ -1,4 +1,5 @@ use FixMyStreet::TestMech; +use Test::MockModule; my $mech = FixMyStreet::TestMech->new; @@ -28,6 +29,13 @@ ok $report, "created test report - $report_id"; $mech->log_in_ok( $oxfordshireuser->email ); +my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); +$cobrand->mock('available_permissions', sub { + my $self = shift; + + return FixMyStreet::Cobrand::Default->available_permissions; +}); + subtest "Users can't edit report without report_edit permission" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], @@ -91,7 +99,7 @@ FixMyStreet::override_config { my $p = $perm ? 'with' : 'without'; my $r = $report->user eq $user2 ? 'with' : 'without'; subtest "User $u edit user for $b $p permission, $r cobrand relation" => sub { - $mech->get("/admin/user_edit/$user2_id"); + $mech->get("/admin/users/$user2_id"); my $success = $mech->res->is_success(); ok $result == 200 ? $success : !$success, "got correct response"; is $mech->res->code, $result, "got $result"; @@ -100,13 +108,23 @@ FixMyStreet::override_config { } } + subtest "Users can't edit users of their own council without permission" => sub { + $mech->get_ok("/admin/users/$user2_id"); + $mech->submit_form_ok( { with_fields => { + email => $user2->email, + } } ); + $user2->discard_changes; + # Make sure we haven't lost the from_body info + is $user2->from_body->id, $oxfordshire->id; + }; + $oxfordshireuser->user_body_permissions->create({ body => $oxfordshire, permission_type => 'user_assign_body', }); subtest "Users can edit users of their own council" => sub { - $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->get_ok("/admin/users/$user2_id"); $mech->content_contains( $user2->name ); # We shouldn't be able to see the permissions tick boxes @@ -131,7 +149,7 @@ FixMyStreet::override_config { subtest "Users can edit permissions" => sub { is $user2->user_body_permissions->count, 0, 'user2 has no permissions'; - $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->get_ok("/admin/users/$user2_id"); $mech->content_contains('Moderate report details'); $mech->submit_form_ok( { with_fields => { @@ -163,8 +181,9 @@ FixMyStreet::override_config { subtest "Unsetting user from_body removes all permissions and area " => sub { is $user2->user_body_permissions->count, 1, 'user2 has 1 permission'; + $user2->update({ area_ids => [123] }); # Set to check cleared - $mech->get_ok("/admin/user_edit/$user2_id"); + $mech->get_ok("/admin/users/$user2_id"); $mech->content_contains('Moderate report details'); $mech->submit_form_ok( { with_fields => { @@ -186,8 +205,9 @@ FixMyStreet::override_config { "permissions[user_assign_areas]" => undef, } } ); + $user2->discard_changes; is $user2->user_body_permissions->count, 0, 'user2 has had permissions removed'; - is $user2->area_id, undef, 'user2 has had area removed'; + is $user2->area_ids, undef, 'user2 has had area removed'; }; }; diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t index 5e3e6c315..c6e03ff7e 100644 --- a/t/app/controller/admin/report_edit.t +++ b/t/app/controller/admin/report_edit.t @@ -608,6 +608,32 @@ subtest "Test display of report extra data" => sub { $mech->content_contains('extra_field</strong>: this is extra data'); }; +subtest "Test alert count display" => sub { + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->content_contains('Alerts: 0'); + + my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( + { + alert_type => 'new_updates', + parameter => $report_id, + user => $user, + } + ); + + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->content_contains('Alerts: 0', 'does not include unconfirmed reports'); + + $alert->update( { confirmed => 1 } ); + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->content_contains('Alerts: 1'); + + $alert->update( { whendisabled => \"now()" } ); + $mech->get_ok("/admin/report_edit/$report_id"); + $mech->content_contains('Alerts: 0'); + + $alert->delete; +}; + my $report2 = FixMyStreet::App->model('DB::Problem')->find_or_create( { postcode => 'SW1A 1AA', diff --git a/t/app/controller/admin/reportextrafields.t b/t/app/controller/admin/reportextrafields.t index fb06665f4..e02df864f 100644 --- a/t/app/controller/admin/reportextrafields.t +++ b/t/app/controller/admin/reportextrafields.t @@ -120,12 +120,42 @@ FixMyStreet::override_config { $contact->update; }; + subtest 'check contact updating does not remove server_set' => sub { + $contact->set_extra_fields(({ code => 'POT', automated => 'server_set' })); + $contact->update; + + $mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category); + $mech->submit_form_ok( { with_fields => { + email => 'test4@example.com', + note => 'test4 note', + } } ); + + $mech->content_like(qr'test4@example.com's); + + $contact->discard_changes; + my $meta_data = $contact->get_extra_fields; + is $contact->email, 'test4@example.com', 'contact updated'; + is_deeply $meta_data, [ { + order => 0, + datatype => 'string', + datatype_description => '', + description => '', + required => 'false', + variable => 'true', + code => 'POT', + automated => 'server_set' + } ], "automated fields not unset"; + }; + + subtest 'Create and update new ReportExtraFields' => sub { my $extra_fields = []; - my $model = FixMyStreet::App->model('DB::ReportExtraFields'); + my $model = FixMyStreet::App->model('DB::ReportExtraField'); is $model->count, 0, 'no ReportExtraFields yet'; + $mech->get_ok("/admin/reportextrafields"); + $mech->get_ok("/admin/reportextrafields/new"); $mech->submit_form_ok({ with_fields => { name => "Test extra fields", @@ -181,11 +211,39 @@ FixMyStreet::override_config { { name => "name1", key => "key1" }, ] }; + $object->discard_changes; is_deeply $object->get_extra_fields, $extra_fields, 'new list field was added'; is $object->language, "en-gb", "Correct language was set"; $mech->get_ok("/admin/reportextrafields/" . $object->id); + $mech->submit_form_ok({ with_fields => { + "metadata[2].order" => "3", + "metadata[2].code" => "automated_test", + "metadata[2].required" => undef, + "metadata[2].notice" => "", + "metadata[2].description" => "", + "metadata[2].datatype_description" => "", + "metadata[2].datatype" => "string", + "metadata[2].automated" => "server_set", + }}); + + push @$extra_fields, { + order => "3", + code => "automated_test", + required => "false", + variable => "true", + description => "", + datatype_description => "", + datatype => "string", + automated => "server_set", + }; + + $object->discard_changes; + is_deeply $object->get_extra_fields, $extra_fields, 'new automated field was added'; + is $object->language, "en-gb", "Correct language was set"; + + $mech->get_ok("/admin/reportextrafields/" . $object->id); $mech->submit_form_ok( { with_fields => { "metadata[1].values[1].key" => "key2", "metadata[1].values[1].name" => "name2", @@ -233,7 +291,7 @@ FixMyStreet::override_config { LANGUAGES => [ 'en-gb,English,en_GB' ] }, sub { subtest "Extra fields are missing from cobrand that doesn't allow them" => sub { - my $object = FixMyStreet::App->model('DB::ReportExtraFields')->first; + my $object = FixMyStreet::App->model('DB::ReportExtraField')->first; $object->update({ language => "", cobrand => ""}); $mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category); @@ -242,7 +300,7 @@ FixMyStreet::override_config { }; }; -FixMyStreet::App->model('DB::ReportExtraFields')->delete_all; +FixMyStreet::App->model('DB::ReportExtraField')->delete_all; $mech->log_out_ok; subtest 'Reports are created with correct extra metadata' => sub { @@ -250,7 +308,7 @@ subtest 'Reports are created with correct extra metadata' => sub { ALLOWED_COBRANDS => [ 'tester' ], MAPIT_URL => 'http://mapit.uk/', }, sub { - my $model = FixMyStreet::App->model('DB::ReportExtraFields'); + my $model = FixMyStreet::App->model('DB::ReportExtraField'); my $extra_fields = $model->find_or_create({ name => "Test extra fields", language => "", diff --git a/t/app/controller/admin/search.t b/t/app/controller/admin/search.t index 497ac9fd6..f8e70cb7a 100644 --- a/t/app/controller/admin/search.t +++ b/t/app/controller/admin/search.t @@ -103,7 +103,7 @@ subtest 'report search' => sub { $update->update; $mech->get_ok('/admin/reports?search=' . $report->user->email); - $mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td> \s* $u_id \s* </td>}xs ); + $mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td[^>]*> \s* $u_id \s* </td>}xs ); $report->state('hidden'); $report->update; diff --git a/t/app/controller/admin/users.t b/t/app/controller/admin/users.t index 8759e260d..e2c922a23 100644 --- a/t/app/controller/admin/users.t +++ b/t/app/controller/admin/users.t @@ -19,7 +19,7 @@ subtest 'search abuse' => sub { }; subtest 'remove user from abuse list from edit user page' => sub { - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->content_contains('User in abuse table'); $mech->click_ok('unban'); @@ -31,7 +31,7 @@ subtest 'remove user from abuse list from edit user page' => sub { subtest 'remove user with phone account from abuse list from edit user page' => sub { my $abuse_user = $mech->create_user_ok('01234 456789'); my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $abuse_user->phone } ); - $mech->get_ok( '/admin/user_edit/' . $abuse_user->id ); + $mech->get_ok( '/admin/users/' . $abuse_user->id ); $mech->content_contains('User in abuse table'); my $abuse_found = FixMyStreet::App->model('DB::Abuse')->find( { email => $abuse_user->phone } ); ok $abuse_found, 'user in abuse table'; @@ -45,7 +45,7 @@ subtest 'remove user with phone account from abuse list from edit user page' => subtest 'no option to remove user already in abuse list' => sub { my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } ); $abuse->delete if $abuse; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->content_lacks('User in abuse table'); }; @@ -66,11 +66,11 @@ subtest 'user search' => sub { $mech->content_contains( $user->name); my $u_id = $user->id; - $mech->content_like( qr{user_edit/$u_id">Edit</a>} ); + $mech->content_like( qr{users/$u_id">Edit</a>} ); $mech->get_ok('/admin/users?search=' . $user->email); - $mech->content_like( qr{user_edit/$u_id">Edit</a>} ); + $mech->content_like( qr{users/$u_id">Edit</a>} ); $user->from_body($haringey->id); $user->update; @@ -96,7 +96,7 @@ subtest 'user_edit does not show user from another council' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], }, sub { - $mech->get('/admin/user_edit/' . $user->id); + $mech->get('/admin/users/' . $user->id); ok !$mech->res->is_success(), "want a bad response"; is $mech->res->code, 404, "got 404"; }; @@ -168,14 +168,17 @@ for my $test ( my %default_perms = ( "permissions[moderate]" => undef, "permissions[planned_reports]" => undef, + "permissions[report_mark_private]" => undef, "permissions[report_edit]" => undef, "permissions[report_edit_category]" => undef, "permissions[report_edit_priority]" => undef, "permissions[report_inspect]" => undef, "permissions[report_instruct]" => undef, + "permissions[report_prefill]" => undef, "permissions[contribute_as_another_user]" => undef, "permissions[contribute_as_anonymous_user]" => undef, "permissions[contribute_as_body]" => undef, + "permissions[default_to_body]" => undef, "permissions[view_body_contribute_details]" => undef, "permissions[user_edit]" => undef, "permissions[user_manage_permissions]" => undef, @@ -206,7 +209,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -226,7 +229,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -246,7 +249,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -266,7 +269,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -286,7 +289,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => 'on', is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -306,7 +309,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => undef, - area_id => '', + area_ids => undef, %default_perms, }, changes => { @@ -329,7 +332,7 @@ FixMyStreet::override_config { phone_verified => undef, flagged => undef, is_superuser => 'on', - area_id => '', + area_ids => undef, }, changes => { is_superuser => undef, @@ -342,7 +345,7 @@ FixMyStreet::override_config { }, ) { subtest $test->{desc} => sub { - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); my $visible = $mech->visible_form_values; is_deeply $visible, $test->{fields}, 'expected user'; @@ -378,7 +381,7 @@ FixMyStreet::override_config { SMS_AUTHENTICATION => 1, }, sub { subtest "Test edit user add verified phone" => sub { - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok( { with_fields => { phone => '+61491570157', phone_verified => 1, @@ -390,9 +393,9 @@ FixMyStreet::override_config { my $existing_user = $mech->create_user_ok('existing@example.com', name => 'Existing User'); $mech->create_problems_for_body(2, 2514, 'Title', { user => $existing_user }); my $count = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok( { with_fields => { email => 'existing@example.com' } }, 'submit email change' ); - is $mech->uri->path, '/admin/user_edit/' . $existing_user->id, 'redirected'; + is $mech->uri->path, '/admin/users/' . $existing_user->id, 'redirected'; my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $existing_user->id })->count; is $p, $count + 2, 'reports merged'; }; @@ -401,11 +404,76 @@ FixMyStreet::override_config { $user = $mech->create_user_ok('test@example.com', name => 'Test User'); +subtest "Send login email from admin" => sub { + $mech->email_count_is(0); + $mech->get_ok( '/admin/users/' . $user->id ); + $mech->submit_form_ok( + { + button => 'send_login_email' + }, + "send login email form submitted" + ); + + my $email = $mech->get_email; + ok $email, "got an email"; + + is $email->header('Subject'), "Your FixMyStreet account details", + "subject is correct"; + is $email->header('To'), $user->email, "to is correct"; + + my $link = $mech->get_link_from_email($email); + + my $mech2 = FixMyStreet::TestMech->new; + $mech2->not_logged_in_ok; + $mech2->get_ok($link); + $mech2->logged_in_ok; + $mech2->log_out_ok; + + $mech->clear_emails_ok; +}; + +subtest "Send login email from admin for unverified email" => sub { + $user->update( { email_verified => 0 } ); + $mech->email_count_is(0); + $mech->get_ok( '/admin/users/' . $user->id ); + $mech->submit_form_ok( + { + button => 'send_login_email' + }, + "send login email form submitted" + ); + + my $email = $mech->get_email; + ok $email, "got an email"; + + is $email->header('Subject'), "Your FixMyStreet account details", + "subject is correct"; + is $email->header('To'), 'test@example.com', "to is correct"; + + my $link = $mech->get_link_from_email($email); + + my $mech2 = FixMyStreet::TestMech->new; + $mech2->not_logged_in_ok; + $mech2->get_ok($link); + $mech2->logged_in_ok; + + my $test_user = FixMyStreet::DB->resultset('User')->search({ + email => $user->email + }, { order_by => [ { -desc => 'id' } ] } ); + $user->discard_changes; + + is $test_user->count, 1, "only one user"; + is $test_user->first->id, $user->id, "User is same"; + ok $user->email_verified, 'email is verified now'; + $mech2->log_out_ok; + $user->update( { email_verified => 1 } ); +}; + subtest "Anonymizing user from admin" => sub { $mech->create_problems_for_body(4, 2237, 'Title'); my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok({ button => 'anon_everywhere' }); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1 })->count; is $c, $count_p; @@ -416,7 +484,7 @@ subtest "Anonymizing user from admin" => sub { subtest "Hiding user's reports from admin" => sub { my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok({ button => 'hide_everywhere' }); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, state => 'hidden' })->count; is $c, $count_p; @@ -429,7 +497,7 @@ subtest "Logging user out" => sub { $mech2->log_in_ok($user->email); $mech2->logged_in_ok; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok({ button => 'logout_everywhere' }, 'Logging user out'); $mech2->not_logged_in_ok; }; @@ -438,7 +506,7 @@ subtest "Removing account from admin" => sub { $mech->create_problems_for_body(4, 2237, 'Title'); my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count; - $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->get_ok( '/admin/users/' . $user->id ); $mech->submit_form_ok({ button => 'remove_account' }, 'Removing account'); my $c = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id, anonymous => 1, name => '' })->count; is $c, $count_p, 'All reports anon/nameless'; @@ -450,4 +518,66 @@ subtest "Removing account from admin" => sub { is $user->email, 'removed-' . $user->id . '@example.org', 'Email gone' }; +subtest "can view list of user's alerts" => sub { + $mech->get_ok( '/admin/users/' . $user->id ); + $mech->content_lacks("User's alerts", 'no list of alerts'); + + $mech->create_problems_for_body(1, 2514, 'Title', { user => $user }); + my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->first; + + my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create({ + user_id => $user->id, + alert_type => 'new_updates', + parameter => $p->id + }); + + + $mech->get_ok( '/admin/users/' . $user->id ); + $mech->content_contains("User's alerts", 'has list of alerts'); + $mech->content_contains($alert->id, 'lists alert'); +}; + +subtest "can edit list of user's alerts" => sub { + $mech->get_ok( '/admin/users/' . $user->id ); + + my $alert = FixMyStreet::DB->resultset('Alert')->search({ + user_id => $user->id, + alert_type => 'new_updates', + })->first; + + $mech->content_like(qr[<td>${\$alert->id}</td>\s*<td>new_updates</td>]m, 'alert on page'); + + $mech->submit_form_ok( { + with_fields => { + 'edit_alert[' . $alert->id . ']' => 'disable' + } + }, 'disabling alert'); + + $alert->discard_changes; + ok $alert->whendisabled, 'alert disabled'; + + $mech->submit_form_ok( { + with_fields => { + 'edit_alert[' . $alert->id . ']' => 'enable' + } + }, 'enabling alert'); + + $alert->discard_changes; + is $alert->whendisabled, undef, 'alert enabled'; + + $mech->submit_form_ok( { + with_fields => { + 'edit_alert[' . $alert->id . ']' => 'delete', + } + }, 'deleting alert'); + + $mech->content_unlike(qr[<td>${\$alert->id}</td>\s*<td>new_updates</td>]m, 'alert not on page'); + + is $user->alerts->count, 0, 'alert deleted'; +}; + +subtest "View timeline" => sub { + $mech->get_ok('/admin/timeline'); +}; + done_testing(); diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t index ce3c2ef9b..41aee5bbc 100644 --- a/t/app/controller/alert.t +++ b/t/app/controller/alert.t @@ -1,5 +1,3 @@ -use LWP::Protocol::PSGI; - use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -11,6 +9,11 @@ $mech->title_like(qr/^Local RSS feeds and email alerts/); $mech->content_contains('Local RSS feeds and email alerts'); $mech->content_contains('html class="no-js" lang="en-gb"'); +my $body = $mech->create_body_ok(2651, 'Edinburgh'); +$mech->create_body_ok(2504, 'Birmingham City Council'); +$mech->create_body_ok(2226, 'Gloucestershire County Council'); +$mech->create_body_ok(2326, 'Cheltenham Borough Council'); + # check that we can get list page FixMyStreet::override_config { ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], @@ -35,11 +38,10 @@ FixMyStreet::override_config { $mech->content_contains('Problems within City Centre ward'); $mech->content_contains('/rss/reports/Edinburgh'); $mech->content_contains('/rss/reports/Edinburgh/City+Centre'); - $mech->content_contains('council:2651:Edinburgh'); - $mech->content_contains('ward:2651:20728:Edinburgh:City_Centre'); + $mech->content_contains('council:' . $body->id . ':Edinburgh'); + $mech->content_contains('ward:' . $body->id . ':20728:Edinburgh:City_Centre'); subtest "Test Nominatim lookup" => sub { - LWP::Protocol::PSGI->register(t::Mock::Nominatim->run_if_script, host => 'nominatim.openstreetmap.org'); $mech->get_ok('/alert/list?pc=High Street'); $mech->content_contains('We found more than one match for that location'); }; @@ -52,16 +54,12 @@ FixMyStreet::override_config { $mech->content_contains('Problems in an area'); $mech->content_contains('Reports by destination'); - $mech->get_ok('/alert/subscribe?rss=1&type=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=' ); + $mech->get_ok('/alert/subscribe?rss=1&type=local&pc=EH1+1BB&rss=Give+me+an+RSS+feed&rznvy=' ); $mech->content_contains('Please select the feed you want'); - $mech->get_ok('/alert/subscribe?rss=1&feed=invalid:1000:A_Locationtype=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy='); + $mech->get_ok('/alert/subscribe?rss=1&feed=invalid:1000:A_Locationtype=local&pc=EH1+1BB&rss=Give+me+an+RSS+feed&rznvy='); $mech->content_contains('Illegal feed selection'); - $mech->create_body_ok(2504, 'Birmingham City Council'); - $mech->create_body_ok(2226, 'Gloucestershire County Council'); - $mech->create_body_ok(2326, 'Cheltenham Borough Council'); - $mech->get_ok('/alert/subscribe?rss=1&feed=area:1000:Birmingham'); is $mech->uri->path, '/rss/reports/Birmingham'; diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index 27371e4a9..f77114d86 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -184,13 +184,15 @@ foreach my $test ( }; } +my $body = $mech->create_body_ok(2651, 'Edinburgh Council'); + foreach my $test ( { desc => 'logged in user signing up', email => 'test-sign-in@example.com', type => 'council', - param1 => 2651, - param2 => 2651, + param1 => $body->id, + param2 => $body->id, confirmed => 1, } ) @@ -207,9 +209,9 @@ foreach my $test ( ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], MAPIT_URL => 'http://mapit.uk/', }, sub { - $mech->get_ok('/alert/list?pc=EH991SP'); + $mech->get_ok('/alert/list?pc=EH11BB'); }; - $mech->set_visible( [ radio => 'council:2651:City_of_Edinburgh' ] ); + $mech->set_visible( [ radio => 'council:' . $body->id . ':City_of_Edinburgh' ] ); $mech->click('alert'); my $alert = FixMyStreet::App->model('DB::Alert')->find( @@ -324,11 +326,7 @@ subtest "Test two-tier council alerts" => sub { }; subtest "Test normal alert signups and that alerts are sent" => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); - my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); for my $alert ( @@ -368,69 +366,31 @@ subtest "Test normal alert signups and that alerts are sent" => sub { } } - my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + my $dt = DateTime->now()->add(days => 2); - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; - - my $report_time = '2011-03-01 12:00:00'; - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { + my ($report) = $mech->create_problems_for_body(1, 1, 'Testing', { + dt => $dt, + user => $user1, postcode => 'EH1 1BB', - bodies_str => '1', areas => ',11808,135007,14419,134935,2651,20728,', category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, state => 'fixed - user', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, + lastupdate => $dt, + whensent => $dt->clone->add( minutes => 5 ), latitude => '55.951963', longitude => '-3.189944', - user_id => $user1->id, - } ); + }); my $report_id = $report->id; ok $report, "created test report - $report_id"; - my $alert = FixMyStreet::App->model('DB::Alert')->create( { - parameter => $report_id, - alert_type => 'new_updates', - user => $user1, - } )->confirm; - ok $alert, 'created alert for reporter'; - - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user2->id, - name => 'Other User', - mark_fixed => 'false', - text => 'This is some update text', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 7 ), - anonymous => 'f', - } ); - my $update_id = $update->id; - ok $update, "created test update - $update_id"; - - $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user2->id, - name => 'Anonymous User', - mark_fixed => 'true', - text => 'This is some more update text', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 8 ), - anonymous => 't', - } ); - $update_id = $update->id; - ok $update, "created test update - $update_id"; + subtest 'check signing up for alerts via report page' => sub { + $mech->log_in_ok($user1->email); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ button => 'alert', with_fields => { type => 'updates' } }); + }; + + $mech->create_comment_for_problem($report, $user2, 'Other User', 'This is some update text', 'f', 'confirmed', undef, { confirmed => $dt->clone->add( hours => 7 ) }); + $mech->create_comment_for_problem($report, $user2, 'Anonymous User', 'This is some more update text', 't', 'confirmed', 'fixed - user', { confirmed => $dt->clone->add( hours => 8 ) }); FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', @@ -475,66 +435,16 @@ subtest "Test normal alert signups and that alerts are sent" => sub { }; subtest "Test alerts are not sent for no-text updates" => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); - my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); - - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + my $dt = DateTime->now()->add(days => 2); - my $report_time = '2011-03-01 12:00:00'; - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '1', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, - state => 'fixed - user', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user1->id, - } ); + my ($report, $report2) = $mech->create_problems_for_body(2, 1, 'Testing', { + user => $user1, + }); my $report_id = $report->id; ok $report, "created test report - $report_id"; - - my $report2 = FixMyStreet::App->model('DB::Problem')->create( { - postcode => 'EH1 1BB', - bodies_str => '1', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, - state => 'fixed - user', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user1->id, - } ); my $report2_id = $report2->id; ok $report2, "created test report - $report2_id"; @@ -553,31 +463,8 @@ subtest "Test alerts are not sent for no-text updates" => sub { } )->confirm; ok $alert, 'created alert for other user'; - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user3->id, - name => 'Staff User', - mark_fixed => 'false', - text => '', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 9 ), - anonymous => 'f', - } ); - my $update_id = $update->id; - ok $update, "created test update from staff user - $update_id"; - - my $update2 = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report2_id, - user_id => $user3->id, - name => 'Staff User', - mark_fixed => 'false', - text => 'This is a normal update', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 9 ), - anonymous => 'f', - } ); - my $update2_id = $update2->id; - ok $update2, "created test update from staff user - $update2_id"; + $mech->create_comment_for_problem($report, $user3, 'Staff User', '', 'f', 'confirmed', undef, { confirmed => $dt->clone->add( hours => 9 ) }); + $mech->create_comment_for_problem($report2, $user3, 'Staff User', 'This is a normal update', 'f', 'confirmed', undef, { confirmed => $dt->clone->add( hours => 9 ) }); $mech->clear_emails_ok; FixMyStreet::override_config { @@ -594,40 +481,14 @@ subtest "Test alerts are not sent for no-text updates" => sub { }; subtest "Test no marked as confirmed added to alerts" => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); - my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); - - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + my $dt = DateTime->now()->add(days => 2); - my $report_time = '2011-03-01 12:00:00'; - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '1', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, - state => 'confirmed', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user1->id, - } ); + my ($report) = $mech->create_problems_for_body(1, 1, 'Testing', { + user => $user1, + }); my $report_id = $report->id; ok $report, "created test report - $report_id"; @@ -638,19 +499,7 @@ subtest "Test no marked as confirmed added to alerts" => sub { } )->confirm; ok $alert, 'created alert for other user'; - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user3->id, - name => 'Staff User', - mark_fixed => 'false', - text => 'this is update', - state => 'confirmed', - problem_state => 'confirmed', - confirmed => $dt->clone->add( hours => 9 ), - anonymous => 'f', - } ); - my $update_id = $update->id; - ok $update, "created test update from staff user - $update_id"; + $mech->create_comment_for_problem($report, $user3, 'Staff User', 'this is update', 'f', 'confirmed', 'confirmed', { confirmed => $dt->clone->add( hours => 9 ) }); $mech->clear_emails_ok; FixMyStreet::override_config { @@ -692,40 +541,14 @@ for my $test ( }, ) { subtest $test->{desc} => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); my $user3 = $mech->create_user_ok('staff@example.com', name => 'Staff User', from_body => $gloucester ); - my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + my $dt = DateTime->now()->add(days => 2); - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; - - my $report_time = '2011-03-01 12:00:00'; - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '1', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, - state => 'confirmed', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user1->id, - } ); + my ($report) = $mech->create_problems_for_body(1, 1, 'Testing', { + user => $user1, + }); my $report_id = $report->id; ok $report, "created test report - $report_id"; @@ -736,19 +559,7 @@ for my $test ( } )->confirm; ok $alert, 'created alert for other user'; - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user3->id, - name => 'Staff User', - mark_fixed => 'false', - text => $test->{update_text}, - problem_state => $test->{problem_state}, - state => 'confirmed', - confirmed => $dt->clone->add( hours => 9 ), - anonymous => 'f', - } ); - my $update_id = $update->id; - ok $update, "created test update from staff user - $update_id"; + $mech->create_comment_for_problem($report, $user3, 'Staff User', $test->{update_text}, 'f', 'confirmed', $test->{problem_state}, { confirmed => $dt->clone->add( hours => 9 ) }); $mech->clear_emails_ok; FixMyStreet::override_config { @@ -775,41 +586,14 @@ for my $test ( } subtest "Test signature template is used from cobrand" => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' ); - my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' ); - my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2); + my $dt = DateTime->now()->add(days => 2); - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; - - my $report_time = '2011-03-01 12:00:00'; - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '2651', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Testing', - detail => 'Testing Detail', - used_map => 1, - name => $user1->name, - anonymous => 0, - state => 'fixed - user', - confirmed => $dt_parser->format_datetime($dt), - lastupdate => $dt_parser->format_datetime($dt), - whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user1->id, - } ); + my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', { + user => $user1, + }); my $report_id = $report->id; ok $report, "created test report - $report_id"; @@ -822,19 +606,7 @@ subtest "Test signature template is used from cobrand" => sub { my $ret = $alert->confirm; ok $ret, 'created alert for reporter'; - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user2->id, - name => 'Other User', - mark_fixed => 'false', - text => 'This is some update text', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 7 ), - anonymous => 'f', - } ); - my $update_id = $update->id; - ok $update, "created test update - $update_id"; - + $mech->create_comment_for_problem($report, $user2, 'Other User', 'This is some update text', 'f', 'confirmed', undef, { confirmed => $dt->clone->add( hours => 7 ) }); $mech->clear_emails_ok; FixMyStreet::override_config { @@ -848,18 +620,7 @@ subtest "Test signature template is used from cobrand" => sub { like $email, qr/All the best/, 'default signature used'; unlike $email, qr/twitter.com/, 'nothing from fixmystreet signature'; - $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report_id, - user_id => $user2->id, - name => 'Anonymous User', - mark_fixed => 'true', - text => 'This is some more update text', - state => 'confirmed', - confirmed => $dt->clone->add( hours => 8 ), - anonymous => 't', - } ); - $update_id = $update->id; - ok $update, "created test update - $update_id"; + $mech->create_comment_for_problem($report, $user2, 'Anonymous User', 'This is some more update text', 't', 'confirmed', 'fixed - user', { confirmed => $dt->clone->add( hours => 8 ) }); $alert->cobrand('fixmystreet'); $alert->update; @@ -884,15 +645,15 @@ for my $test ( desc => 'check non public reports are not included in council problems alerts', alert_params => { alert_type => 'council_problems', - parameter => '2651', - parameter2 => '2651', + parameter => $body->id, + parameter2 => $body->id, } }, { desc => 'check non public reports are not included in ward problems alerts', alert_params => { alert_type => 'ward_problems', - parameter => '2651', + parameter => $body->id, parameter2 => '20728', } }, @@ -914,14 +675,10 @@ for my $test ( }, ) { subtest $test->{desc} => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User'); - my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User'); - my $dt = DateTime->now->add( minutes => -30 ); + my $dt = DateTime->now()->add( minutes => -30 ); my $r_dt = $dt->clone->add( minutes => 20 ); my $alert_params = $test->{alert_params}; @@ -932,32 +689,15 @@ for my $test ( my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( $alert_params ); ok $alert_user1, "alert created"; - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; - - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '2651', + my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', { areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', title => 'Alert test for non public reports', - detail => 'Testing Detail', - used_map => 1, - name => $user2->name, - anonymous => 0, - state => 'confirmed', - confirmed => $dt_parser->format_datetime($r_dt), - lastupdate => $dt_parser->format_datetime($r_dt), - whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, + confirmed => $r_dt, # Needed so timezone set right latitude => '55.951963', longitude => '-3.189944', - user_id => $user2->id, + user => $user2, non_public => 1, - } ); + }); $mech->clear_emails_ok; FixMyStreet::override_config { @@ -982,55 +722,19 @@ for my $test ( } subtest 'check new updates alerts for non public reports only go to report owner' => sub { - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); - my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User'); - my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User'); - my $user3 = $mech->create_user_ok('updates@example.com', name => 'Update User'); my $dt = DateTime->now->add( minutes => -30 ); my $r_dt = $dt->clone->add( minutes => 20 ); - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; + my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', { + user => $user2, + non_public => 1, + }); - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '2651', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Alert test for non public reports', - detail => 'Testing Detail', - used_map => 1, - name => $user2->name, - anonymous => 0, - state => 'confirmed', - confirmed => $dt_parser->format_datetime($r_dt), - lastupdate => $dt_parser->format_datetime($r_dt), - whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user2->id, - non_public => 1, - } ); - - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report->id, - user_id => $user3->id, - name => 'Anonymous User', - mark_fixed => 'false', - text => 'This is some more update text', - state => 'confirmed', - confirmed => $r_dt->clone->add( minutes => 8 ), - anonymous => 't', - } ); + $mech->create_comment_for_problem($report, $user3, 'Anonymous User', 'This is some more update text', 't', 'confirmed', undef, { confirmed => $r_dt->clone->add( minutes => 8 ) }); my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( { user => $user1, @@ -1041,7 +745,6 @@ subtest 'check new updates alerts for non public reports only go to report owner } ); ok $alert_user1, "alert created"; - $mech->clear_emails_ok; FixMyStreet::App->model('DB::AlertType')->email_alerts(); $mech->email_count_is(0); @@ -1070,59 +773,24 @@ subtest 'check new updates alerts for non public reports only go to report owner $mech->delete_user( $user3 ); }; -subtest 'check setting inlude dates in new updates cobrand option' => sub { +subtest 'check setting include dates in new updates cobrand option' => sub { my $include_date_in_alert_override= Sub::Override->new( "FixMyStreet::Cobrand::Default::include_time_in_update_alerts", sub { return 1; } ); - $mech->delete_user( 'reporter@example.com' ); - $mech->delete_user( 'alerts@example.com' ); my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User'); - my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User'); - my $user3 = $mech->create_user_ok('updates@example.com', name => 'Update User'); my $dt = DateTime->now->add( minutes => -30 ); my $r_dt = $dt->clone->add( minutes => 20 ); - my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser; - - my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { - postcode => 'EH1 1BB', - bodies_str => '2651', - areas => ',11808,135007,14419,134935,2651,20728,', - category => 'Street lighting', - title => 'Alert test for non public reports', - detail => 'Testing Detail', - used_map => 1, - name => $user2->name, - anonymous => 0, - state => 'confirmed', - confirmed => $dt_parser->format_datetime($r_dt), - lastupdate => $dt_parser->format_datetime($r_dt), - whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )), - lang => 'en-gb', - service => '', - cobrand => 'default', - cobrand_data => '', - send_questionnaire => 1, - latitude => '55.951963', - longitude => '-3.189944', - user_id => $user2->id, - } ); + my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', { + user => $user2, + }); - my $update = FixMyStreet::App->model('DB::Comment')->create( { - problem_id => $report->id, - user_id => $user3->id, - name => 'Anonymous User', - mark_fixed => 'false', - text => 'This is some more update text', - state => 'confirmed', - confirmed => $r_dt->clone->add( minutes => 8 ), - anonymous => 't', - } ); + my $update = $mech->create_comment_for_problem($report, $user3, 'Anonymous User', 'This is some more update text', 't', 'confirmed', undef, { confirmed => $r_dt }); my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( { user => $user1, @@ -1137,13 +805,6 @@ subtest 'check setting inlude dates in new updates cobrand option' => sub { $mech->clear_emails_ok; FixMyStreet::App->model('DB::AlertType')->email_alerts(); - # if we don't do this then we're applying the date inflation code and - # it's timezone munging to the DateTime object above and not the DateTime - # object that's inflated from the database value and these turn out to be - # different as the one above has a UTC timezone and not the floating one - # that those from the DB do. - $update->discard_changes(); - my $date_in_alert = Utils::prettify_dt( $update->confirmed ); my $email = $mech->get_text_body_from_email; like $email, qr/$date_in_alert/, 'alert contains date'; diff --git a/t/app/controller/around.t b/t/app/controller/around.t index 8eaba6450..b123692fa 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -1,3 +1,13 @@ +package FixMyStreet::Map::Tester; +use base 'FixMyStreet::Map::FMS'; + +use constant ZOOM_LEVELS => 99; +use constant MIN_ZOOM_LEVEL => 88; + +1; + +package main; + use Test::MockModule; use FixMyStreet::TestMech; @@ -8,28 +18,6 @@ subtest "check that if no query we get sent back to the homepage" => sub { is $mech->uri->path, '/', "redirected to '/'"; }; -# x,y requests were generated by the old map code. We keep the behavior for -# historic links -subtest "redirect x,y requests to lat/lon (301 - permanent)" => sub { - - FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.uk/', - }, sub { - $mech->get_ok('/around?x=3281&y=1113'); - }; - - # did we redirect to lat,lon? - is $mech->uri->path, '/around', "still on /around"; - is_deeply { $mech->uri->query_form }, - { lat => 51.499825, lon => -0.140137, zoom => 3 }, - "lat,lon correctly set"; - - # was it a 301? - is $mech->res->code, 200, "got 200 for final destination"; - is $mech->res->previous->code, 301, "got 301 for redirect"; - -}; - # test various locations on inital search box foreach my $test ( { @@ -94,7 +82,10 @@ foreach my $test ( }; } -my @edinburgh_problems = $mech->create_problems_for_body( 5, 2651, 'Around page', { +my $body_edin_id = $mech->create_body_ok(2651, 'City of Edinburgh Council')->id; +my $body_west_id = $mech->create_body_ok(2504, 'Westminster City Council')->id; + +my @edinburgh_problems = $mech->create_problems_for_body( 5, $body_edin_id, 'Around page', { postcode => 'EH1 1BB', latitude => 55.9519637512, longitude => -3.17492254484, @@ -118,7 +109,7 @@ subtest 'check non public reports are not displayed on around page' => sub { $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } }, "good location" ); }; - $mech->content_contains( 'Around page Test 3 for 2651', + $mech->content_contains( "Around page Test 3 for $body_edin_id", 'problem to be marked non public visible' ); my $private = $edinburgh_problems[2]; @@ -132,14 +123,82 @@ subtest 'check non public reports are not displayed on around page' => sub { $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } }, "good location" ); }; - $mech->content_lacks( 'Around page Test 3 for 2651', + $mech->content_lacks( "Around page Test 3 for $body_edin_id", 'problem marked non public is not visible' ); }; +for my $permission ( qw/ report_inspect report_mark_private/ ) { + subtest 'check non public reports are displayed on around page with $permission permission' => sub { + my $body = FixMyStreet::DB->resultset('Body')->find( $body_edin_id ); + my $body2 = FixMyStreet::DB->resultset('Body')->find( $body_west_id ); + my $user = $mech->log_in_ok( 'test@example.com' ); + $user->user_body_permissions->delete(); + $user->update({ from_body => $body }); + $user->user_body_permissions->find_or_create({ + body => $body, + permission_type => $permission, + }); -subtest 'check category, status and extra filtering works on /around' => sub { - my $body = $mech->create_body_ok(2237, "Oxfordshire"); + $mech->get_ok('/'); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } }, + "good location" ); + }; + $mech->content_contains( "Around page Test 3 for $body_edin_id", + 'problem marked non public is visible' ); + $mech->content_contains( "Around page Test 2 for $body_edin_id", + 'problem marked public is visible' ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/around?pc=EH1+1BB&status=non_public'); + }; + $mech->content_contains( "Around page Test 3 for $body_edin_id", + 'problem marked non public is visible' ); + $mech->content_lacks( "Around page Test 2 for $body_edin_id", + 'problem marked public is not visible' ); + + $user->user_body_permissions->delete(); + $user->update({ from_body => $body2 }); + $user->user_body_permissions->find_or_create({ + body => $body2, + permission_type => $permission, + }); + + $mech->get_ok('/'); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } }, + "good location" ); + }; + $mech->content_lacks( "Around page Test 3 for $body_edin_id", + 'problem marked non public is not visible' ); + $mech->content_contains( "Around page Test 2 for $body_edin_id", + 'problem marked public is visible' ); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/around?pc=EH1+1BB&status=non_public'); + }; + $mech->content_lacks( "Around page Test 3 for $body_edin_id", + 'problem marked non public is not visible' ); + $mech->content_lacks( "Around page Test 2 for $body_edin_id", + 'problem marked public is visible' ); + }; +} + +my $body = $mech->create_body_ok(2237, "Oxfordshire"); + +subtest 'check category, status and extra filtering works on /around' => sub { my $categories = [ 'Pothole', 'Vegetation', 'Flytipping' ]; my $params = { postcode => 'OX20 1SZ', @@ -152,7 +211,7 @@ subtest 'check category, status and extra filtering works on /around' => sub { # Create one open and one fixed report in each category foreach my $category ( @$categories ) { $mech->create_contact_ok( category => $category, body_id => $body->id, email => "$category\@example.org" ); - foreach my $state ( 'confirmed', 'fixed' ) { + foreach my $state ( 'confirmed', 'fixed - user', 'fixed - council' ) { my %report_params = ( %$params, category => $category, @@ -165,10 +224,11 @@ subtest 'check category, status and extra filtering works on /around' => sub { my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox ); my $pins = $json->{pins}; - is scalar @$pins, 6, 'correct number of reports when no filters'; + is scalar @$pins, 9, 'correct number of reports when no filters'; # Regression test for filter_category in /around URL FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->get_ok( '/around?filter_category=Pothole&bbox=' . $bbox ); @@ -177,7 +237,7 @@ subtest 'check category, status and extra filtering works on /around' => sub { $json = $mech->get_ok_json( '/around?ajax=1&filter_category=Pothole&bbox=' . $bbox ); $pins = $json->{pins}; - is scalar @$pins, 2, 'correct number of Pothole reports'; + is scalar @$pins, 3, 'correct number of Pothole reports'; $json = $mech->get_ok_json( '/around?ajax=1&status=open&bbox=' . $bbox ); $pins = $json->{pins}; @@ -185,16 +245,86 @@ subtest 'check category, status and extra filtering works on /around' => sub { $json = $mech->get_ok_json( '/around?ajax=1&status=fixed&filter_category=Vegetation&bbox=' . $bbox ); $pins = $json->{pins}; - is scalar @$pins, 1, 'correct number of fixed Vegetation reports'; + is scalar @$pins, 2, 'correct number of fixed Vegetation reports'; my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Default'); - $cobrand->mock('display_location_extra_params', sub { { external_body => "Pothole-fixed" } }); + $cobrand->mock('display_location_extra_params', sub { { external_body => "Pothole-confirmed" } }); $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox ); $pins = $json->{pins}; is scalar @$pins, 1, 'correct number of external_body reports'; }; +subtest 'check old problems not shown by default on around page' => sub { + my $params = { + postcode => 'OX20 1SZ', + latitude => 51.754926, + longitude => -1.256179, + }; + my $bbox = ($params->{longitude} - 0.01) . ',' . ($params->{latitude} - 0.01) + . ',' . ($params->{longitude} + 0.01) . ',' . ($params->{latitude} + 0.01); + + my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox ); + my $pins = $json->{pins}; + is scalar @$pins, 9, 'correct number of reports when no age'; + + my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id ); + $problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } ); + + $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox ); + $pins = $json->{pins}; + is scalar @$pins, 8, 'correct number of reports with old report'; + + $json = $mech->get_ok_json( '/around?show_old_reports=1&ajax=1&bbox=' . $bbox ); + $pins = $json->{pins}; + is scalar @$pins, 9, 'correct number of reports with show_old_reports'; + + $problems->update( { confirmed => \"current_timestamp" } ); +}; + +subtest 'check sorting by update uses lastupdate to determine age' => sub { + my $params = { + postcode => 'OX20 1SZ', + latitude => 51.754926, + longitude => -1.256179, + }; + my $bbox = ($params->{longitude} - 0.01) . ',' . ($params->{latitude} - 0.01) + . ',' . ($params->{longitude} + 0.01) . ',' . ($params->{latitude} + 0.01); + + my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id ); + $problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } ); + + my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox ); + my $pins = $json->{pins}; + is scalar @$pins, 8, 'correct number of reports with default sorting'; + + + $json = $mech->get_ok_json( '/around?ajax=1&sort=updated-desc&bbox=' . $bbox ); + $pins = $json->{pins}; + is scalar @$pins, 9, 'correct number of reports with updated sort'; + + $problems->update( { confirmed => \"current_timestamp" } ); +}; + +subtest 'check show old reports checkbox shown on around page' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok( '/around?pc=OX20+1SZ' ); + $mech->content_contains('id="show_old_reports_wrapper" class="report-list-filters hidden"'); + + my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id ); + $problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } ); + + $mech->get_ok( '/around?pc=OX20+1SZ&status=all' ); + $mech->content_lacks('id="show_old_reports_wrapper" class="report-list-filters hidden"'); + $mech->content_contains('id="show_old_reports_wrapper" class="report-list-filters"'); + + $problems->update( { confirmed => \"current_timestamp" } ); + }; +}; + subtest 'check skip_around skips around page' => sub { my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Default'); $cobrand->mock('skip_around_page', sub { 1 }); @@ -202,11 +332,41 @@ subtest 'check skip_around skips around page' => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/', + MAPIT_TYPES => ['CTY', 'DIS'], }, sub { $mech->get('/around?latitude=51.754926&longitude=-1.256179'); - is $mech->res->code, 302, "around page is a redirect"; + is $mech->res->previous->code, 302, "around page is a redirect"; is $mech->uri->path, '/report/new', "and redirects to /report/new"; }; }; +subtest 'check map zoom level customisation' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + MAP_TYPE => 'OSM', + }, sub { + $mech->get('/around?latitude=51.754926&longitude=-1.256179'); + $mech->content_contains('data-numZoomLevels=6'); + $mech->content_contains('data-zoomOffset=13'); + }; + + + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + MAP_TYPE => 'Tester', + }, sub { + $mech->get('/around?latitude=51.754926&longitude=-1.256179'); + $mech->content_contains('data-numZoomLevels=99'); + $mech->content_contains('data-zoomOffset=88'); + }; +}; + +subtest 'check nearby lookup' => sub { + my $p = FixMyStreet::DB->resultset("Problem")->search({ external_body => "Pothole-confirmed" })->first; + $mech->get_ok('/around/nearby?latitude=51.754926&longitude=-1.256179&filter_category=Pothole'); + $mech->content_contains('["51.754926","-1.256179","yellow",' . $p->id . ',"Around page Test 1 for ' . $body->id . '","small",false]'); +}; + done_testing(); diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t index 8cc7e4154..ffabc75f3 100644 --- a/t/app/controller/auth.t +++ b/t/app/controller/auth.t @@ -100,33 +100,6 @@ $mech->not_logged_in_ok; $mech->log_out_ok; } -foreach my $remember_me ( '1', '0' ) { - subtest "sign in using valid details (remember_me => '$remember_me')" => sub { - $mech->get_ok('/auth'); - $mech->submit_form_ok( - { - form_name => 'general_auth', - fields => { - username => $test_email, - password_sign_in => $test_password, - remember_me => ( $remember_me ? 1 : undef ), - }, - button => 'sign_in_by_password', - }, - "sign in with '$test_email' & '$test_password'" - ); - is $mech->uri->path, '/my', "redirected to correct page"; - - my $expiry = $mech->session_cookie_expiry; - $remember_me - ? cmp_ok( $expiry, '>', 86400, "long expiry time" ) - : is( $expiry, 0, "no expiry time" ); - - # logout - $mech->log_out_ok; - }; -} - # try to sign in with bad details $mech->get_ok('/auth'); $mech->submit_form_ok( @@ -278,7 +251,7 @@ subtest "check logging in with token" => sub { }; subtest 'check password length/common' => sub { - $mech->get_ok('/auth'); + $mech->get_ok('/auth/create'); $mech->submit_form_ok({ form_name => 'general_auth', fields => { username => $test_email, password_register => 'short' }, @@ -300,6 +273,16 @@ subtest 'check common password AJAX call' => sub { $mech->content_contains("true"); }; +subtest 'test forgotten password page' => sub { + $mech->get_ok('/auth/forgot'); + $mech->content_contains('Forgot password'); + $mech->submit_form_ok({ + form_name => 'general_auth', + fields => { username => $test_email, password_register => 'squirblewirble' }, + button => 'sign_in_by_code', + }); +}; + subtest "Test two-factor authentication login" => sub { use Auth::GoogleAuth; my $auth = Auth::GoogleAuth->new; diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t index 031fb8d9e..ac3d98b15 100644 --- a/t/app/controller/auth_social.t +++ b/t/app/controller/auth_social.t @@ -103,8 +103,8 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) { # We don't have an email, so check that we can still submit it, # and the ID carries through the confirmation $fields->{username} = $fb_email; - $fields->{name} = 'Ffion Tester'; - $mech->submit_form(with_fields => $fields); + $fields->{name} = 'Ffion Tester' unless $page eq 'my'; + $mech->submit_form(with_fields => $fields, $page eq 'my' ? (button => 'sign_in_by_code') : ()); $mech->content_contains('Nearly done! Now check your email'); my $url = $mech->get_link_from_email; @@ -211,8 +211,8 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) { # We don't have an email, so check that we can still submit it, # and the ID carries through the confirmation $fields->{username} = $tw_email; - $fields->{name} = 'Ffion Tester'; - $mech->submit_form(with_fields => $fields); + $fields->{name} = 'Ffion Tester' unless $page eq 'my'; + $mech->submit_form(with_fields => $fields, $page eq 'my' ? (button => 'sign_in_by_code') : ()); $mech->content_contains('Nearly done! Now check your email'); my $url = $mech->get_link_from_email; diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t index 4f255f058..842f27dd5 100644 --- a/t/app/controller/contact.t +++ b/t/app/controller/contact.t @@ -1,8 +1,19 @@ +package FixMyStreet::Cobrand::AbuseOnly; + +use base 'FixMyStreet::Cobrand::Default'; + +sub abuse_reports_only { 1; } + +1; + +package main; + use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; $mech->get_ok('/contact'); +my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; $mech->title_like(qr/Contact Us/); $mech->content_contains("It's often quickest to "); @@ -269,25 +280,16 @@ for my $test ( }; } -for my $test ( - { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - }, - }, - { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - id => $problem_main->id, - }, - }, +my %common = ( + em => 'test@example.com', + name => 'A name', + subject => 'A subject', + message => 'A message', +); +for my $test ( + { fields => \%common }, + { fields => { %common, id => $problem_main->id } }, ) { subtest 'check email sent correctly' => sub { @@ -305,11 +307,11 @@ for my $test ( my $email = $mech->get_email; - is $email->header('Subject'), 'FMS message: ' . $test->{fields}->{subject}, 'subject'; + is $email->header('Subject'), 'FixMyStreet message: ' . $test->{fields}->{subject}, 'subject'; is $email->header('From'), "\"$test->{fields}->{name}\" <$test->{fields}->{em}>", 'from'; my $body = $mech->get_text_body_from_email($email); like $body, qr/$test->{fields}->{message}/, 'body'; - like $body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer'; + like $body, qr/Sent by contact form on \S+.\s+IP address (?:\d{1,3}\.){3,}\d{1,3}, user agent ./, 'body footer'; my $problem_id = $test->{fields}{id}; like $body, qr/Complaint about report $problem_id/, 'reporting a report' if $test->{fields}{id}; @@ -326,39 +328,22 @@ for my $test ( for my $test ( { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => undef, - }, + fields => { %common, dest => undef }, page_errors => [ 'There were problems with your report. Please see below.', 'Please enter who your message is for', + 'You can only contact the team behind FixMyStreet using our contact form', # The JS-hidden one ] }, { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => 'council', - }, + fields => { %common, dest => 'council' }, page_errors => [ 'There were problems with your report. Please see below.', 'You can only contact the team behind FixMyStreet using our contact form', ] }, { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => 'update', - }, + fields => { %common, dest => 'update' }, page_errors => [ 'There were problems with your report. Please see below.', 'You can only contact the team behind FixMyStreet using our contact form', @@ -381,44 +366,21 @@ for my $test ( $test->{fields}->{'extra.phone'} = ''; is_deeply $mech->visible_form_values, $test->{fields}, 'form values'; + # Ugh, but checking div not hidden; text always shown and hidden with CSS if ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'update' ) { - $mech->content_contains( 'www.writetothem.com', 'includes link to WTT if trying to update report' ); + $mech->content_contains('<div class="form-error__box form-error--update">'); } elsif ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'council' ) { - $mech->content_lacks( 'www.writetothem.com', 'does not include link to WTT if trying to contact council' ); - $mech->content_contains( 'should find contact details', 'mentions checking council website for contact details' ); + # Ugh, but checking div not hidden + $mech->content_contains('<div class="form-error__box form-error--council">'); } } }; } for my $test ( - { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => 'help', - }, - }, - { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => 'feedback', - }, - }, - { - fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', - dest => 'from_council', - }, - }, + { fields => { %common, dest => 'help' } }, + { fields => { %common, dest => 'feedback' } }, + { fields => { %common, dest => 'from_council' } }, ) { subtest 'check email sent correctly with dest field set to us' => sub { @@ -436,24 +398,67 @@ for my $test ( for my $test ( { + fields => { %common, dest => undef }, + page_errors => + [ 'There were problems with your report. Please see below.', + 'Please enter a topic of your message', + 'You can only use this form to report inappropriate content', # The JS-hidden one + ] + }, + { + fields => { %common, dest => 'council' }, + page_errors => + [ 'There were problems with your report. Please see below.', + 'You can only use this form to report inappropriate content', + ] + }, + { + fields => { %common, dest => 'update' }, + page_errors => + [ 'There were problems with your report. Please see below.', + 'You can only use this form to report inappropriate content', + ] + }, + ) +{ + subtest 'check Bucks submit page incorrect destination handling' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'buckinghamshire' ], + }, sub { + $mech->get_ok( '/contact?id=' . $problem_main->id, 'can visit for abuse report' ); + $mech->submit_form_ok( { with_fields => $test->{fields} } ); + is_deeply $mech->page_errors, $test->{page_errors}, 'page errors'; + + $test->{fields}->{'extra.phone'} = ''; + is_deeply $mech->visible_form_values, $test->{fields}, 'form values'; + + if ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'update' ) { + $mech->content_contains('please leave an update'); + } elsif ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'council' ) { + $mech->content_contains('should find other contact details'); + } + } + }; +} + +for my $test ( + { fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', + %common, + token => $csrf, dest => 'from_council', success_url => '/faq', + s => "", }, url_should_be => 'http://localhost/faq', }, { fields => { - em => 'test@example.com', - name => 'A name', - subject => 'A subject', - message => 'A message', + %common, + token => $csrf, dest => 'from_council', success_url => 'http://www.example.com', + s => "", }, url_should_be => 'http://www.example.com', }, @@ -469,6 +474,24 @@ for my $test ( }; } +subtest 'check can limit contact to abuse reports' => sub { + FixMyStreet::override_config { + 'ALLOWED_COBRANDS' => [ 'abuseonly' ], + }, sub { + $mech->get( '/contact' ); + is $mech->res->code, 404, 'cannot visit contact page'; + $mech->get_ok( '/contact?id=' . $problem_main->id, 'can visit for abuse report' ); + + my $token = FixMyStreet::App->model("DB::Token")->create({ + scope => 'moderation', + data => { id => $problem_main->id } + }); + + $mech->get_ok( '/contact?m=' . $token->token, 'can visit for moderation complaint' ); + + } +}; + $problem_main->delete; done_testing(); diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t index b53056968..ff8d1a9d5 100644 --- a/t/app/controller/dashboard.t +++ b/t/app/controller/dashboard.t @@ -1,4 +1,17 @@ use Test::MockTime ':all'; + +package FixMyStreet::Cobrand::Tester; +use parent 'FixMyStreet::Cobrand::Default'; +# Allow access if CSV export for a body, otherwise deny +sub dashboard_permission { + my $self = shift; + my $c = $self->{c}; + return 0 unless $c->get_param('export'); + return $c->get_param('body') || 0; +} + +package main; + use strict; use warnings; @@ -43,9 +56,13 @@ foreach my $problem (@fixed_problems) { $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'fixed'); } +my $first_problem_id; +my $first_update_id; foreach my $problem (@closed_problems) { $problem->update({ state => 'closed' }); - $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' }); + my ($update) = $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' }); + $first_problem_id = $problem->id unless $first_problem_id; + $first_update_id = $update->id unless $first_update_id; } my $categories = scraper { @@ -96,7 +113,7 @@ FixMyStreet::override_config { }; subtest 'area user can only see their area' => sub { - $counciluser->update({area_id => $area_id}); + $counciluser->update({area_ids => [ $area_id ]}); $mech->get_ok("/dashboard"); $mech->content_contains('<h1>Trowbridge</h1>'); @@ -105,7 +122,11 @@ FixMyStreet::override_config { $mech->get_ok("/dashboard?ward=$alt_area_id"); $mech->content_contains('<h1>Trowbridge</h1>'); - $counciluser->update({area_id => undef}); + $counciluser->update({area_ids => [ $area_id, $alt_area_id ]}); + $mech->get_ok("/dashboard"); + $mech->content_contains('<h1>Bradford-on-Avon / Trowbridge</h1>'); + + $counciluser->update({area_ids => undef}); }; subtest 'The correct categories and totals shown by default' => sub { @@ -146,15 +167,10 @@ FixMyStreet::override_config { areas => ",$alt_area_id,2651,", }); $mech->get_ok('/dashboard?export=1'); - open my $data_handle, '<', \$mech->content; - my $csv = Text::CSV->new( { binary => 1 } ); - my @rows; - while ( my $row = $csv->getline( $data_handle ) ) { - push @rows, $row; - } + my @rows = $mech->content_as_csv; is scalar @rows, 19, '1 (header) + 18 (reports) = 19 lines'; - is scalar @{$rows[0]}, 18, '18 columns present'; + is scalar @{$rows[0]}, 20, '20 columns present'; is_deeply $rows[0], [ @@ -176,6 +192,8 @@ FixMyStreet::override_config { 'Easting', 'Northing', 'Report URL', + 'Site Used', + 'Reported As', ], 'Column headers look correct'; @@ -184,6 +202,27 @@ FixMyStreet::override_config { is $rows[5]->[16], '179716', 'Correct Northing conversion'; }; + subtest 'export updates as csv' => sub { + $mech->get_ok('/dashboard?updates=1&export=1'); + my @rows = $mech->content_as_csv; + is scalar @rows, 15, '1 (header) + 14 (updates) = 15 lines'; + is scalar @{$rows[0]}, 8, '8 columns present'; + + is_deeply $rows[0], + [ + 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state', + 'Text', 'User Name', 'Reported As', + ], + 'Column headers look correct'; + + is $rows[1]->[0], $first_problem_id, 'Correct report ID'; + is $rows[1]->[1], $first_update_id, 'Correct update ID'; + is $rows[1]->[3], 'confirmed', 'Correct state'; + is $rows[1]->[4], 'closed', 'Correct problem state'; + is $rows[1]->[5], 'text', 'Correct text'; + is $rows[1]->[6], 'Title', 'Correct name'; + }; + subtest 'export as csv using token' => sub { $mech->log_out_ok; @@ -198,21 +237,37 @@ FixMyStreet::override_config { $mech->get_ok('/dashboard?export=1'); like $mech->res->header('Content-type'), qr'text/csv'; $mech->content_contains('Report ID'); + $mech->delete_header('Authorization'); + }; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'tester', + MAPIT_URL => 'http://mapit.uk/', +}, sub { + subtest 'no body or export, 404' => sub { + $mech->get('/dashboard'); + is $mech->status, '404', 'No parameters, 404'; + $mech->get('/dashboard?export=1'); + is $mech->status, '404', 'If no body, 404'; + $mech->get("/dashboard?body=$body_id"); + is $mech->status, '404', 'If no export, 404'; + }; + + subtest 'body and export, okay' => sub { + $mech->get_ok("/dashboard?body=$body_id&export=1"); }; }; sub test_table { my ($content, @expected) = @_; my $res = $categories->scrape( $mech->content ); - my $i = 0; + my @actual; foreach my $row ( @{ $res->{rows} }[1 .. 11] ) { - foreach my $col ( @{ $row->{cols} } ) { - is $col, $expected[$i++]; - } + push @actual, @{$row->{cols}} if $row->{cols}; } + is_deeply \@actual, \@expected; } -END { - restore_time; - done_testing(); -} +restore_time; +done_testing(); diff --git a/t/app/controller/develop.t b/t/app/controller/develop.t index 92aa86721..7fde5ef83 100644 --- a/t/app/controller/develop.t +++ b/t/app/controller/develop.t @@ -1,19 +1,28 @@ use FixMyStreet::TestMech; +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); my ($problem) = $mech->create_problems_for_body(1, 2504, 'title'); my $update = $mech->create_comment_for_problem($problem, $problem->user, 'Name', 'Text', 'f', 'confirmed', 'confirmed'); subtest 'not visible on live site' => sub { - FixMyStreet::override_config { - STAGING_SITE => 0 - }, sub { - $mech->get('/_dev/email/'); - is $mech->res->code, 404; - $mech->get('/_dev/email/login'); - is $mech->res->code, 404; - }; + $mech->get('/_dev/'); + is $mech->res->code, 404; + $mech->get('/_dev/email'); + is $mech->res->code, 404; + $mech->get('/_dev/email/login'); + is $mech->res->code, 404; +}; + +$problem->user->update({ is_superuser => 1 }); +$mech->log_in_ok($problem->user->email); + +subtest 'dev index' => sub { + $mech->get_ok('/_dev/'); + $mech->content_contains('<h1>/_dev</h1>'); }; subtest 'dev email index page' => sub { @@ -30,4 +39,27 @@ subtest 'individual email previews' => sub { $mech->get_ok('/_dev/email/update-confirm?update=' . $update->id); }; +subtest 'problem confirmation page preview' => sub { + $mech->get_ok('/_dev/confirm_problem/' . $problem->id ); +}; + +subtest 'update confirmation page preview' => sub { + $mech->get_ok('/_dev/confirm_update/' . $problem->id); +}; + +subtest 'alert confirmation page preview' => sub { + $mech->get_ok('/_dev/confirm_alert/subscribe'); +}; + +subtest 'contact form submission page preview' => sub { + $mech->get_ok('/_dev/contact_submit/1'); +}; + +subtest 'questionnaire completion page previews' => sub { + $mech->get_ok('/_dev/questionnaire_completed?been_fixed=Yes'); + $mech->get_ok('/_dev/questionnaire_completed?been_fixed=Unknown'); + $mech->get_ok('/_dev/questionnaire_completed?new_state=confirmed'); + $mech->get_ok('/_dev/questionnaire_creator_fixed'); +}; + done_testing(); diff --git a/t/app/controller/index.t b/t/app/controller/index.t index 9be6dfa1e..bd268b3d7 100644 --- a/t/app/controller/index.t +++ b/t/app/controller/index.t @@ -29,15 +29,15 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub { }, { in => { lat => 51.50100, lon => -0.14158 }, - out => { lat => 51.50100, lon => -0.14158, zoom => 3 }, + out => { lat => 51.50100, lon => -0.14158 }, }, { in => { x => 3281, y => 1113, }, - out => { lat => 51.499825, lon => -0.140137, zoom => 3 }, + out => { lat => 51.499825, lon => -0.140137 }, }, { in => { e => 1234, n => 4567 }, - out => { lat => 49.808509, lon => -7.544784, zoom => 3 }, + out => { lat => 49.808509, lon => -7.544784 }, }, ) { diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t index 4b2f0cfe3..7ef24bbe8 100644 --- a/t/app/controller/moderate.t +++ b/t/app/controller/moderate.t @@ -4,6 +4,12 @@ use parent 'FixMyStreet::Cobrand::Default'; sub send_moderation_notifications { 0 } +package FixMyStreet::Cobrand::TestTitle; + +use parent 'FixMyStreet::Cobrand::Default'; + +sub moderate_permission_title { 0 } + package main; use FixMyStreet::TestMech; @@ -15,6 +21,7 @@ $mech->host('www.example.org'); my $BROMLEY_ID = 2482; my $body = $mech->create_body_ok( $BROMLEY_ID, 'Bromley Council' ); +$mech->create_contact_ok( body => $body, category => 'Lost toys', email => 'losttoys@example.net' ); my $dt = DateTime->now; @@ -43,11 +50,11 @@ sub create_report { latitude => '51.4129', longitude => '0.007831', user_id => $user2->id, - photo => $mech->get_photo_data, + photo => '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', + extra => { moon => 'waxing full' }, }); } my $report = create_report(); -my $report2 = create_report(); my $REPORT_URL = '/report/' . $report->id ; @@ -57,6 +64,9 @@ subtest 'Auth' => sub { $mech->get_ok($REPORT_URL); $mech->content_lacks('Moderat'); + $mech->get_ok("$REPORT_URL/moderate"); + $mech->content_lacks('Moderat'); + $mech->log_in_ok( $user->email ); $mech->get_ok($REPORT_URL); @@ -86,7 +96,7 @@ subtest 'Auth' => sub { my %problem_prepopulated = ( problem_show_name => 1, - problem_show_photo => 1, + problem_photo => 1, problem_title => 'Good bad good', problem_detail => 'Good bad bad bad good bad', ); @@ -95,6 +105,9 @@ subtest 'Problem moderation' => sub { subtest 'Post modify title and text' => sub { $mech->get_ok($REPORT_URL); + $mech->content_lacks('show-moderation'); + $mech->follow_link_ok({ text_regex => qr/^Moderate$/ }); + $mech->content_contains('show-moderation'); $mech->submit_form_ok({ with_fields => { %problem_prepopulated, problem_title => 'Good good', @@ -119,6 +132,25 @@ subtest 'Problem moderation' => sub { $report->discard_changes; is $report->title, 'Good bad good'; is $report->detail, 'Good bad bad bad good bad'; + + my @history = $report->moderation_original_datas->search(undef, { order_by => 'id' })->all; + is @history, 2, 'Right number of entries'; + is $history[0]->title, 'Good bad good', 'Correct original title'; + is $history[1]->title, 'Good good', 'Correct second title'; + }; + + subtest 'Post modified title after edited elsewhere' => sub { + $mech->submit_form_ok({ with_fields => { + %problem_prepopulated, + problem_title => 'Good good', + form_started => 1, # January 1970! + }}); + $mech->base_like( qr{\Q/moderate$REPORT_URL\E} ); + $mech->content_contains('Good bad good'); # Displayed title + $mech->content_contains('Good good'); # Form edit + + $report->discard_changes; + is $report->title, 'Good bad good', 'title unchanged'; }; subtest 'Make anonymous' => sub { @@ -146,7 +178,7 @@ subtest 'Problem moderation' => sub { $mech->submit_form_ok({ with_fields => { %problem_prepopulated, - problem_show_photo => 0, + problem_photo => 0, }}); $mech->base_like( qr{\Q$REPORT_URL\E} ); @@ -154,7 +186,7 @@ subtest 'Problem moderation' => sub { $mech->submit_form_ok({ with_fields => { %problem_prepopulated, - problem_show_photo => 1, + problem_photo => 1, }}); $mech->base_like( qr{\Q$REPORT_URL\E} ); @@ -208,34 +240,124 @@ subtest 'Problem moderation' => sub { $report->update({ state => 'confirmed' }); } }; + + subtest 'Try and moderate title when not allowed' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'testtitle' + }, sub { + $mech->get_ok($REPORT_URL); + $mech->submit_form_ok({ with_fields => { + problem_show_name => 1, + problem_photo => 1, + problem_detail => 'Changed detail', + }}); + $mech->base_like( qr{\Q$REPORT_URL\E} ); + $mech->content_like(qr/Moderated by Bromley Council/); + + $report->discard_changes; + is $report->title, 'Good bad good'; + is $report->detail, 'Changed detail'; + } + }; + + subtest 'Moderate extra data' => sub { + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + 'extra.weather' => 'snow', + 'extra.moon' => 'waning full', + token => $csrf, + }); + $report->discard_changes; + is $report->get_extra_metadata('weather'), 'snow'; + is $report->get_extra_metadata('moon'), 'waning full'; + my $mod = $report->moderation_original_data; + is $mod->get_extra_metadata('moon'), 'waxing full'; + is $mod->get_extra_metadata('weather'), undef; + + my $diff = $mod->extra_diff($report, 'moon'); + is $diff, "wa<del style='background-color:#fcc'>x</del><ins style='background-color:#cfc'>n</ins>ing full", 'Correct diff'; + }; + + subtest 'Moderate category' => sub { + $report->update; + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + 'category' => 'Lost toys', + token => $csrf, + }); + $report->discard_changes; + is $report->category, 'Lost toys'; + }; + + subtest 'Moderate state' => sub { + my $mods_count = $report->moderation_original_datas->count; + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + state => 'confirmed', + token => $csrf, + }); + $report->discard_changes; + is $report->state, 'confirmed', 'state has not changed'; + is $report->comments->count, 0, 'same state, no update'; + is $report->moderation_original_datas->count, $mods_count, 'No moderation entry either'; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + state => 'in progress', + token => $csrf, + }); + $report->discard_changes; + is $report->state, 'in progress', 'state has changed'; + is $report->comments->count, 1, 'a new update added'; + $report->update({ state => 'confirmed' }); + is $report->moderation_original_datas->count, $mods_count, 'No moderation entry, only state changed'; + }; + + subtest 'Moderate location' => sub { + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + ALLOWED_COBRANDS => 'fixmystreet', + }, sub { + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + latitude => '53', + longitude => '0.01578', + token => $csrf, + }); + $report->discard_changes; + is $report->latitude, 51.4129, 'No change when moved out of area'; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { + %problem_prepopulated, + latitude => '51.4021', + longitude => '0.01578', + token => $csrf, + }); + $report->discard_changes; + is $report->latitude, 51.4021, 'Updated when same body'; + }; + }; }; $mech->content_lacks('Posted anonymously', 'sanity check'); +my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; -subtest 'Problem 2' => sub { - my $REPORT2_URL = '/report/' . $report2->id ; - $mech->get_ok($REPORT2_URL); - $mech->submit_form_ok({ with_fields => { +subtest 'Edit photos' => sub { + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { %problem_prepopulated, - problem_title => 'Good good', - problem_detail => 'Good good improved', - }}); - $mech->base_like( qr{\Q$REPORT2_URL\E} ); - - $report2->discard_changes; - is $report2->title, 'Good good'; - is $report2->detail, 'Good good improved'; - - $mech->submit_form_ok({ with_fields => { + photo1 => 'something-wrong', + token => $csrf, + }); + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id, { %problem_prepopulated, - problem_revert_title => 1, - problem_revert_detail => 1, - }}); - $mech->base_like( qr{\Q$REPORT2_URL\E} ); - - $report2->discard_changes; - is $report2->title, 'Good bad good'; - is $report2->detail, 'Good bad bad bad good bad'; + photo1 => '', + upload_fileid => '', + token => $csrf, + }); + $report->discard_changes; + is $report->photo, undef; }; sub create_update { @@ -243,16 +365,17 @@ sub create_update { user => $user2, name => 'Test User 2', anonymous => 'f', - photo => $mech->get_photo_data, + photo => '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', text => 'update good good bad good', state => 'confirmed', mark_fixed => 0, + confirmed => $dt, }); } my %update_prepopulated = ( update_show_name => 1, - update_show_photo => 1, - update_detail => 'update good good bad good', + update_photo => 1, + update_text => 'update good good bad good', ); my $update = create_update(); @@ -261,9 +384,12 @@ subtest 'updates' => sub { subtest 'Update modify text' => sub { $mech->get_ok($REPORT_URL); + $mech->content_lacks('show-moderation'); + $mech->follow_link_ok({ text_regex => qr/^Moderate this update$/ }); + $mech->content_contains('show-moderation'); $mech->submit_form_ok({ with_fields => { %update_prepopulated, - update_detail => 'update good good good', + update_text => 'update good good good', }}) or die $mech->content; $mech->base_like( qr{\Q$REPORT_URL\E} ); @@ -274,12 +400,11 @@ subtest 'updates' => sub { subtest 'Revert text' => sub { $mech->submit_form_ok({ with_fields => { %update_prepopulated, - update_revert_detail => 1, + update_revert_text => 1, }}); $mech->base_like( qr{\Q$REPORT_URL\E} ); $update->discard_changes; - $update->discard_changes; is $update->text, 'update good good bad good', }; @@ -304,6 +429,20 @@ subtest 'updates' => sub { $mech->content_lacks('Posted anonymously'); }; + subtest 'Moderate extra data' => sub { + $update->set_extra_metadata('moon', 'waxing full'); + $update->update; + my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/; + $mech->post_ok('http://www.example.org/moderate/report/' . $report->id . '/update/' . $update->id, { + %update_prepopulated, + 'extra.weather' => 'snow', + 'extra.moon' => 'waxing full', + token => $csrf, + }); + $update->discard_changes; + is $update->get_extra_metadata('weather'), 'snow'; + }; + subtest 'Hide photo' => sub { $report->update({ photo => undef }); # hide the main photo so we can just look for text in comment @@ -314,7 +453,7 @@ subtest 'updates' => sub { $mech->submit_form_ok({ with_fields => { %update_prepopulated, - update_show_photo => 0, + update_photo => 0, }}); $mech->base_like( qr{\Q$REPORT_URL\E} ); @@ -322,7 +461,7 @@ subtest 'updates' => sub { $mech->submit_form_ok({ with_fields => { %update_prepopulated, - update_show_photo => 1, + update_photo => 1, }}); $mech->base_like( qr{\Q$REPORT_URL\E} ); @@ -348,7 +487,7 @@ subtest 'Update 2' => sub { $mech->get_ok($REPORT_URL); $mech->submit_form_ok({ with_fields => { %update_prepopulated, - update_detail => 'update good good good', + update_text => 'update good good good', }}) or die $mech->content; $update2->discard_changes; @@ -359,6 +498,9 @@ subtest 'Now stop being a staff user' => sub { $user->update({ from_body => undef }); $mech->get_ok($REPORT_URL); $mech->content_contains('Moderated by Bromley Council'); + + $mech->get_ok("$REPORT_URL/moderate/" . $update->id); + $mech->content_lacks('Moderate this update'); }; subtest 'And do it as a superuser' => sub { @@ -372,4 +514,7 @@ subtest 'And do it as a superuser' => sub { $mech->content_contains('Moderated by an administrator'); }; +subtest 'Check moderation history in admin' => sub { + $mech->get_ok('/admin/report_edit/' . $report->id); +}; done_testing(); diff --git a/t/app/controller/my_planned.t b/t/app/controller/my_planned.t index 67d59e148..a6a47a798 100644 --- a/t/app/controller/my_planned.t +++ b/t/app/controller/my_planned.t @@ -1,4 +1,5 @@ use FixMyStreet::TestMech; +use Test::MockModule; my $mech = FixMyStreet::TestMech->new; $mech->get_ok('/my/planned'); @@ -187,6 +188,13 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire' ], BASE_URL => 'http://oxfordshire.fixmystreet.site', }, sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cobrand->mock('available_permissions', sub { + my $self = shift; + + return FixMyStreet::Cobrand::Default->available_permissions; + }); + subtest "can remove problems not displayed in cobrand from shortlist" => sub { $user->user_planned_reports->remove(); my ($problem1) = $mech->create_problems_for_body(2, $body->id, 'New Problem'); diff --git a/t/app/controller/open311.t b/t/app/controller/open311.t index 9f4f594fe..79fe159a3 100644 --- a/t/app/controller/open311.t +++ b/t/app/controller/open311.t @@ -6,7 +6,7 @@ my $mech = FixMyStreet::TestMech->new; $mech->get_ok('/open311.cgi/v2/requests.rss?jurisdiction_id=fiksgatami.no&status=open&agency_responsible=1854'); like $mech->uri, qr[/open311/v2/requests\.rss\?.{65}]; # Don't know order parameters will be in now -$mech->create_problems_for_body(2, 2237, 'Around page'); +my ($problem1, $problem2) = $mech->create_problems_for_body(2, 2237, 'Around page'); $mech->get_ok('/open311/v2/requests.xml?jurisdiction_id=foo&status=open&agency_responsible=2237'); $mech->content_contains('<description>Around page Test 2 for 2237: Around page Test 2 for 2237 Detail</description>'); $mech->content_contains('<interface_used>Web interface</interface_used>'); @@ -18,4 +18,43 @@ my $problems = $json->{requests}[0]{request}; is @$problems, 2; like $problems->[0]{description}, qr/Around page Test/; +subtest "non_public reports aren't available" => sub { + $problem1->update({ + non_public => 1, + detail => 'This report is now private', + }); + $mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo'); + $json = decode_json($mech->content); + $problems = $json->{requests}[0]{request}; + is @$problems, 1; + like $problems->[0]{description}, qr/Around page Test/; + $mech->content_lacks('This report is now private'); + + my $problem_id = $problem1->id; + $mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo"); + $json = decode_json($mech->content); + $problems = $json->{requests}[0]{request}; + is @$problems, 0; +}; + +subtest "hidden reports aren't available" => sub { + $problem1->update({ + non_public => 0, + detail => 'This report is now hidden', + state => "hidden", + }); + $mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo'); + $json = decode_json($mech->content); + $problems = $json->{requests}[0]{request}; + is @$problems, 1; + like $problems->[0]{description}, qr/Around page Test/; + $mech->content_lacks('This report is now hidden'); + + my $problem_id = $problem1->id; + $mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo"); + $json = decode_json($mech->content); + $problems = $json->{requests}[0]{request}; + is @$problems, 0; +}; + done_testing(); diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t index e9183836b..842daa0dc 100644 --- a/t/app/controller/photo.t +++ b/t/app/controller/photo.t @@ -24,7 +24,10 @@ subtest "Check multiple upload worked" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], MAPIT_URL => 'http://mapit.uk/', - UPLOAD_DIR => $UPLOAD_DIR, + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { $mech->log_in_ok('test@example.com'); @@ -72,12 +75,15 @@ subtest "Check multiple upload worked" => sub { }; }; -subtest "Check photo uploading URL works" => sub { +subtest "Check photo uploading URL and endpoints work" => sub { my $UPLOAD_DIR = tempdir( CLEANUP => 1 ); # submit initial pc form FixMyStreet::override_config { - UPLOAD_DIR => $UPLOAD_DIR, + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { $mech->post( '/photo/upload', Content_Type => 'form-data', @@ -89,20 +95,21 @@ subtest "Check photo uploading URL works" => sub { is $mech->content, '{"id":"74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg"}'; my $image_file = path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg'); ok $image_file->exists, 'File uploaded to temp'; - }; -}; -subtest "Check photo URL endpoints work" => sub { - my $p = FixMyStreet::DB->resultset("Problem")->first; - - $mech->get_ok('/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg'); - my $image_file = FixMyStreet->path_to('web/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg'); - ok -e $image_file, 'File uploaded to temp'; - $mech->get_ok('/photo/' . $p->id . '.jpeg'); - $image_file = FixMyStreet->path_to('web/photo/' . $p->id . '.jpeg'); - ok -e $image_file, 'File uploaded to temp'; - my $res = $mech->get('/photo/0.jpeg'); - is $res->code, 404, "got 404"; + my $p = FixMyStreet::DB->resultset("Problem")->first; + + foreach my $i ( + '/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', + '/photo/fulltemp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', + '/photo/' . $p->id . '.jpeg', + '/photo/' . $p->id . '.full.jpeg') { + $mech->get_ok($i); + $image_file = FixMyStreet->path_to("web$i"); + ok -e $image_file, 'File uploaded to temp'; + } + my $res = $mech->get('/photo/0.jpeg'); + is $res->code, 404, "got 404"; + }; }; done_testing(); diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index 75542d759..05aed7262 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -40,6 +40,26 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( my $report_id = $report->id; ok $report, "created test report - $report_id"; +# Make sure questionnaires aren't sent if the report is closed. +foreach my $state ( + 'closed', 'duplicate', 'not responsible', 'unable to fix', 'internal referral' +) { + subtest "questionnaire not sent for $state state" => sub { + $report->update( { send_questionnaire => 1, state => $state } ); + $report->questionnaires->delete; + FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( { + site => 'fixmystreet' + } ); + + $mech->email_count_is(0); + + $report->discard_changes; + is $report->send_questionnaire, 0; + } +} +$report->update( { send_questionnaire => 1, state => 'confirmed' } ); +$report->questionnaires->delete; + # Call the questionaire sending function... FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( { site => 'fixmystreet' @@ -85,10 +105,16 @@ foreach my $test ( }, { desc => 'User goes to questionnaire URL for an already answered questionnaire', - answered => \'current_timestamp', + answered => \"current_timestamp - '10 minutes'::interval", content => 'already answered this questionnaire', code => 400, }, + { + desc => 'User goes to questionnaire URL for a very recently answered questionnaire', + answered => \"current_timestamp - '10 seconds'::interval", + content_lacks => 'already answered this questionnaire', + code => 200, + }, ) { subtest $test->{desc} => sub { $report->state( $test->{state} || 'confirmed' ); @@ -99,7 +125,8 @@ foreach my $test ( $token .= $test->{token_extra} if $test->{token_extra}; $mech->get("/Q/$token"); is $mech->res->code, $test->{code}, "Right status received"; - $mech->content_contains( $test->{content} ); + $mech->content_contains( $test->{content} ) if $test->{content}; + $mech->content_lacks( $test->{content_lacks} ) if $test->{content_lacks}; # Reset, no matter what test did $report->state( 'confirmed' ); $report->update; diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t index 367d9a1d4..0c8b7d995 100644 --- a/t/app/controller/report_as_other.t +++ b/t/app/controller/report_as_other.t @@ -16,6 +16,8 @@ my $test_email = 'body-user@example.net'; my $user = $mech->log_in_ok($test_email); $user->update({ from_body => $body->id, name => 'Body User' }); +my $superuser = $mech->create_user_ok('superuser@example.net', name => "Super", is_superuser => 1); + my ($report_to_update) = $mech->create_problems_for_body(1, $body->id, 'Title', { category => 'Potholes' }); subtest "Body user, no permissions, no special reporting tools shown" => sub { @@ -123,7 +125,7 @@ subtest "Body user, has permission to add report as another (existing) user with my $send_confirmation_mail_override = Sub::Override->new( "FixMyStreet::Cobrand::Default::report_sent_confirmation_email", - sub { return 1; } + sub { return 'external_id'; } ); FixMyStreet::Script::Reports::send(); $mech->email_count_is(2); @@ -150,10 +152,11 @@ subtest "Body user, has permission to add report as another (existing) user with push @users, $report->user; }; -subtest "Body user, has permission to add report as anonymous user" => sub { +subtest "Superuser, can add report as anonymous user" => sub { FixMyStreet::Script::Reports::send(); $mech->clear_emails_ok; + my $user = $mech->log_in_ok($superuser->email); my $report = add_report( 'contribute_as_anonymous_user', form_as => 'anonymous_user', @@ -161,23 +164,23 @@ subtest "Body user, has permission to add report as anonymous user" => sub { detail => 'Test report details.', category => 'Street lighting', ); - is $report->name, 'Oxfordshire County Council', 'report name is body'; - is $report->user->name, 'Body User', 'user name unchanged'; + is $report->name, 'an administrator', 'report name is admin'; + is $report->user->name, 'Super', 'user name unchanged'; is $report->user->id, $user->id, 'user matches'; is $report->anonymous, 1, 'report anonymous'; my $send_confirmation_mail_override = Sub::Override->new( "FixMyStreet::Cobrand::Default::report_sent_confirmation_email", - sub { return 1; } + sub { return 'external_id'; } ); FixMyStreet::Script::Reports::send(); - # No report sent email is sent - $mech->email_count_is(1); my $email = $mech->get_email; like $email->header('Subject'), qr/Problem Report: Test Report/, 'report email title correct'; $mech->clear_emails_ok; $send_confirmation_mail_override->restore(); + + $mech->log_in_ok($test_email); }; subtest "Body user, has permission to add update as council" => sub { @@ -282,6 +285,24 @@ subtest "Body user, has permission to add update as anonymous user" => sub { is $update->anonymous, 1, 'update anonymous'; }; +for my $test_permission ( qw/planned_reports default_to_body/ ) { + subtest "$test_permission user defaults to reporting as body" => sub { + $_->delete for $user->user_body_permissions; + for my $permission ( 'contribute_as_another_user', 'contribute_as_anonymous_user', 'contribute_as_body', $test_permission ) { + $user->user_body_permissions->create({ body => $body, permission_type => $permission }) + } + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', + PHONE_COUNTRY => 'GB', + }, sub { + $mech->get_ok('/report/new?latitude=51.7549262252&longitude=-1.25617899435'); + }; + + is $mech->visible_form_values()->{form_as}, 'body', 'report as body is default'; + }; +} + done_testing(); sub start_report { @@ -311,7 +332,9 @@ sub add_report { with_fields => \%fields, }, "submit details"); }; - $mech->content_contains('Thank you for reporting this issue'); + # Anonymous test done as superuser, which redirects + $mech->content_contains('Thank you for reporting this issue') + unless $permission eq 'contribute_as_anonymous_user'; my $report = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first; ok $report, "Found the report"; is $report->state, 'confirmed', "report is now confirmed"; diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t index 17b9180c1..bde090dd1 100644 --- a/t/app/controller/report_display.t +++ b/t/app/controller/report_display.t @@ -129,6 +129,7 @@ subtest "test a good report" => sub { 'Reported by Test User at 15:47, Sat 16 April 2011', 'correct problem meta information'; $mech->content_contains('Test 2 Detail'); + $mech->content_lacks('Sent to'); my $update_form = $mech->form_name('updateForm'); @@ -142,6 +143,18 @@ subtest "test a good report" => sub { is $update_form->value($_), $fields{$_}, "$_ value" for keys %fields; }; +subtest "test duration string" => sub { + $report->update({ whensent => \'current_timestamp' }); + $mech->get_ok("/report/$report_id"); + $mech->content_contains('Sent to Westminster'); + FixMyStreet::override_config { + AREA_LINKS_FROM_PROBLEMS => 1, + }, sub { + $mech->get_ok("/report/$report_id"); + $mech->content_contains('Sent to <a href="/reports/Westminster+City+Council">Westminster'); + }; +}; + foreach my $meta ( { anonymous => 'f', @@ -361,7 +374,12 @@ for my $test ( $banner->{text} =~ s/ $//g; } - is $banner->{id}, $test->{banner_id}, 'banner id'; + if ( $test->{banner_id} ) { + ok $banner->{class} =~ /banner--$test->{banner_id}/i, 'banner class'; + } else { + is $banner->{class}, $test->{banner_id}, 'banner class'; + } + if ($test->{banner_text}) { ok $banner->{text} =~ /$test->{banner_text}/i, 'banner text'; } else { diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t index e4a202db7..223979d1b 100644 --- a/t/app/controller/report_import.t +++ b/t/app/controller/report_import.t @@ -89,6 +89,15 @@ subtest "Test creating bad partial entries" => sub { }; +for my $test ( + { + desc => 'Submit a correct entry', + }, + { + desc => 'Submit a correct web entry', + web => 1, + } +) { subtest "Submit a correct entry" => sub { $mech->get_ok('/import'); @@ -101,13 +110,18 @@ subtest "Submit a correct entry" => sub { subject => 'Test report', detail => 'This is a test report', photo => $sample_file, + web => $test->{web}, } }, "fill in form" ); is_deeply( $mech->import_errors, [], "got no errors" ); - is $mech->content, 'SUCCESS', "Got success response"; + if ( $test->{web} ) { + $mech->content_contains('Nearly done! Now check', "Got email confirmation page"); + } else { + is $mech->content, 'SUCCESS', "Got success response"; + } # check that we have received the email my $token_url = $mech->get_link_from_email; @@ -223,6 +237,7 @@ subtest "Submit a correct entry" => sub { $mech->delete_user($user); }; +} subtest "Submit a correct entry (with location)" => sub { diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t index 6a001225d..ef05288c7 100644 --- a/t/app/controller/report_inspect.t +++ b/t/app/controller/report_inspect.t @@ -1,4 +1,5 @@ use FixMyStreet::TestMech; +use Test::MockModule; my $mech = FixMyStreet::TestMech->new; @@ -7,6 +8,14 @@ my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', { can_be_de my $contact = $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' ); my $contact2 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Sheep', email => 'SHEEP', send_method => 'Open311' ); my $contact3 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Badgers', email => 'badgers@example.net' ); +my $dt = FixMyStreet::DB->resultset("DefectType")->create({ + body => $oxon, + name => 'Small Defect', description => "Teeny", +}); +FixMyStreet::DB->resultset("ContactDefectType")->create({ + contact => $contact, + defect_type => $dt, +}); my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({ body => $oxon, name => 'High Priority', @@ -23,14 +32,14 @@ FixMyStreet::DB->resultset("ContactResponsePriority")->create({ contact => $contact3, response_priority => $rp2, }); -my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council'); -$mech->create_contact_ok( body_id => $wodc->id, category => 'Horses', email => 'horses@example.net' ); +my $oxfordcity = $mech->create_body_ok(2421, 'Oxford City Council'); +$mech->create_contact_ok( body_id => $oxfordcity->id, category => 'Horses', email => 'horses@example.net' ); my ($report, $report2, $report3) = $mech->create_problems_for_body(3, $oxon->id, 'Test', { - category => 'Cows', cobrand => 'fixmystreet', areas => ',2237,2420', + category => 'Cows', cobrand => 'fixmystreet', areas => ',2237,2421,', whensent => \'current_timestamp', - latitude => 51.847693, longitude => -1.355908, + latitude => 51.754926, longitude => -1.256179, }); my $report_id = $report->id; my $report2_id = $report2->id; @@ -48,12 +57,22 @@ FixMyStreet::override_config { subtest "test inspect page" => sub { $mech->get_ok("/report/$report_id"); $mech->content_lacks('Save changes'); + $mech->content_lacks('Private'); + $mech->content_lacks('Priority'); + $mech->content_lacks('Traffic management'); + $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)'); + + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_mark_private' }); + $mech->get_ok("/report/$report_id"); + $mech->content_contains('Private'); + $mech->content_contains('Save changes'); $mech->content_lacks('Priority'); $mech->content_lacks('Traffic management'); $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)'); $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); $mech->get_ok("/report/$report_id"); + $mech->content_contains('Private'); $mech->content_contains('Save changes'); $mech->content_contains('Priority'); $mech->content_lacks('Traffic management'); @@ -62,6 +81,7 @@ FixMyStreet::override_config { $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' }); $mech->get_ok("/report/$report_id"); $mech->content_contains('Save changes'); + $mech->content_contains('Private'); $mech->content_contains('Priority'); $mech->content_contains('Traffic management'); $mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)'); @@ -82,7 +102,28 @@ FixMyStreet::override_config { $user->update({is_superuser => 0}); }; + subtest "test mark private submission" => sub { + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_mark_private' }); + + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ button => 'save', with_fields => { non_public => 1 } }); + $report->discard_changes; + my $alert = FixMyStreet::App->model('DB::Alert')->find( + { user => $user, alert_type => 'new_updates', confirmed => 1, } + ); + + is $report->state, 'confirmed', 'report state not changed'; + ok $report->non_public, 'report not public'; + ok !defined( $alert ) , 'not signed up for alerts'; + + $report->update( { non_public => 0 } ); + }; subtest "test basic inspect submission" => sub { + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' }); + + $mech->get_ok("/report/$report_id"); $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Yes', state => 'Action scheduled', include_update => undef } }); $report->discard_changes; my $alert = FixMyStreet::App->model('DB::Alert')->find( @@ -144,6 +185,19 @@ FixMyStreet::override_config { $mech->content_lacks('Invalid location'); }; + subtest "test areas update when location changes" => sub { + $report->discard_changes; + my ($lat, $lon, $areas) = ($report->latitude, $report->longitude, $report->areas); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 52.038712, longitude => -1.346397, include_update => undef } }); + $mech->content_lacks('Invalid location'); + $report->discard_changes; + is $report->areas, ",151767,2237,2419,", 'Areas set correctly'; + $mech->submit_form_ok({ button => 'save', with_fields => { latitude => $lat, longitude => $lon, include_update => undef } }); + $report->discard_changes; + is $report->areas, $areas, 'Areas reset correctly'; + }; + subtest "test duplicate reports are shown" => sub { my $old_state = $report->state; $report->set_extra_metadata('duplicate_of' => $report2->id); @@ -394,6 +448,24 @@ FixMyStreet::override_config { is $report->response_priority->id, $rp->id, 'response priority set'; }; + subtest "check can set defect type for category when changing from category with no defect types" => sub { + $report->update({ category => 'Sheep', defect_type_id => undef }); + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ + button => 'save', + with_fields => { + include_update => 0, + defect_type => $dt->id, + category => 'Cows', + } + }); + $report->discard_changes; + is $report->defect_type->id, $dt->id, 'defect type set'; + $report->update({ defect_type_id => undef }); + }; + subtest "check can't set priority that isn't for a category" => sub { $report->discard_changes; $report->update({ category => 'Cows', response_priority_id => $rp->id }); @@ -414,6 +486,26 @@ FixMyStreet::override_config { is $report->response_priority, undef, 'response priority set'; }; + subtest "check can unset priority" => sub { + $report->discard_changes; + $report->update({ category => 'Cows', response_priority_id => $rp->id }); + $report->discard_changes; + is $report->response_priority->id, $rp->id, 'response priority set'; + $user->user_body_permissions->delete; + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_category' }); + $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' }); + $mech->get_ok("/report/$report_id"); + $mech->submit_form_ok({ + button => 'save', + with_fields => { + priority => "", + } + }); + + $report->discard_changes; + is $report->response_priority, undef, 'response priority unset'; + }; + subtest "check nearest address display" => sub { $mech->get_ok("/report/$report_id"); $mech->content_lacks('Nearest calculated address', 'No address displayed'); @@ -460,6 +552,14 @@ foreach my $test ( FixMyStreet::override_config { ALLOWED_COBRANDS => $test->{cobrand}, }, sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cobrand->mock('available_permissions', sub { + my $self = shift; + + my $perms = FixMyStreet::Cobrand::Default->available_permissions; + + return $perms; + }); subtest $test->{desc} => sub { $user->user_body_permissions->delete; $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' }); @@ -506,6 +606,14 @@ foreach my $test ( FixMyStreet::override_config { ALLOWED_COBRANDS => 'oxfordshire', }, sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cobrand->mock('available_permissions', sub { + my $self = shift; + + my $perms = FixMyStreet::Cobrand::Default->available_permissions; + + return $perms; + }); subtest "test negative reputation" => sub { my $reputation = $report->user->get_extra_metadata("reputation") || 0; @@ -641,7 +749,7 @@ FixMyStreet::override_config { # set the timezone on this so the date comparison below doesn't fail due to mismatched # timezones my $now = DateTime->now( - time_zone => FixMyStreet->time_zone || FixMyStreet->local_time_zone + time_zone => FixMyStreet->local_time_zone )->subtract(days => 1); $mech->submit_form(button => 'save', form_id => 'report_inspect_form', fields => { include_update => 1, public_update => 'An update', saved_at => $now->epoch }); @@ -655,6 +763,14 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'oxfordshire', 'fixmystreet' ], BASE_URL => 'http://fixmystreet.site', }, sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire'); + $cobrand->mock('available_permissions', sub { + my $self = shift; + + my $perms = FixMyStreet::Cobrand::Default->available_permissions; + + return $perms; + }); subtest "test report not resent when category changes if send_method doesn't change" => sub { $mech->get_ok("/report/$report3_id"); $mech->submit_form(button => 'save', with_fields => { category => 'Badgers', include_update => undef, }); @@ -690,7 +806,7 @@ FixMyStreet::override_config { $report->discard_changes; is $report->category, "Horses", "Report in correct category"; is $report->whensent, undef, "Report marked as unsent"; - is $report->bodies_str, $wodc->id, "Reported to WODC"; + is $report->bodies_str, $oxfordcity->id, "Reported to Oxford City"; is $mech->uri->path, "/report/$report_id", "redirected to correct page"; is $mech->res->code, 200, "got 200 for final destination"; diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t index 04f567615..330d844d0 100644 --- a/t/app/controller/report_interest_count.t +++ b/t/app/controller/report_interest_count.t @@ -109,7 +109,7 @@ FixMyStreet::override_config { $mech->content_contains( '1 supporter' ); $mech->log_out_ok( $user->email ); - $mech->post_ok("/report/support", { id => $report_id } ); + $mech->post_ok("/report/$report_id/support"); is $mech->uri->path, "/report/$report_id", 'add support redirects to report page'; diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index dff04176b..af18c39b9 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -24,10 +24,15 @@ subtest "test that bare requests to /report/new get redirected" => sub { MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->get_ok('/report/new?pc=SW1A%201AA'); + is $mech->uri->path, '/around', "went to /around"; + is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' }, + "pc correctly transferred"; + + $mech->get_ok('/report/new?pc_override=SW1A%201AA&latitude=51&longitude=-2'); + is $mech->uri->path, '/around', "went to /around"; + is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' }, + "pc correctly transferred, lat/lon gone"; }; - is $mech->uri->path, '/around', "went to /around"; - is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' }, - "pc correctly transferred"; }; my %body_ids; @@ -40,6 +45,13 @@ for my $body ( { area_id => 2482, name => 'Bromley Council' }, { area_id => 2227, name => 'Hampshire County Council' }, { area_id => 2333, name => 'Hart Council' }, + { area_id => 2535, name => 'Sandwell Borough Council' }, + { area_id => 1000, name => 'Highways England' }, + { area_id => 2217, name => 'Buckinghamshire County Council' }, + { area_id => 2232, name => 'Lincolnshire County Council' }, + { area_id => 2237, name => 'Oxfordshire County Council' }, + { area_id => 2600, name => 'Rutland County Council' }, + { area_id => 2234, name => 'Northamptonshire County Council' }, ) { my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name}); push @bodies, $body_obj; @@ -97,6 +109,36 @@ my $contact10 = $mech->create_contact_ok( category => 'Street lighting', email => 'streetlights-2326@example.com', ); +my $contact11 = $mech->create_contact_ok( + body_id => $body_ids{1000}, # Highways + category => 'Pothole', + email => 'pothole-1000@example.com', +); +my $contact12 = $mech->create_contact_ok( + body_id => $body_ids{2217}, # Buckinghamshire + category => 'Street lighting', + email => 'streetlights-2217@example.com', +); +my $contact13 = $mech->create_contact_ok( + body_id => $body_ids{2232}, # Lincolnshire + category => 'Trees', + email => 'trees-2232@example.com', +); +my $contact14 = $mech->create_contact_ok( + body_id => $body_ids{2237}, # Oxfordshire + category => 'Trees', + email => 'trees-2247@example.com', +); +my $contact15 = $mech->create_contact_ok( + body_id => $body_ids{2600}, # Rutland + category => 'Trees', + email => 'trees-2600@example.com', +); +my $contact16 = $mech->create_contact_ok( + body_id => $body_ids{2234}, # Northamptonshire + category => 'Trees', + email => 'trees-2234@example.com', +); # test that the various bit of form get filled in and errors correctly # generated. @@ -113,11 +155,9 @@ foreach my $test ( name => '', may_show_name => '1', username => '', - email => '', phone => '', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -140,12 +180,10 @@ foreach my $test ( name => '', may_show_name => '1', username => '', - email => '', phone => '', category => 'Something bad', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { category => '-- Pick a category --', @@ -170,12 +208,10 @@ foreach my $test ( name => '', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -197,12 +233,10 @@ foreach my $test ( name => '', may_show_name => undef, username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -224,12 +258,10 @@ foreach my $test ( name => 'Bob Jones', may_show_name => undef, username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -250,12 +282,10 @@ foreach my $test ( name => 'Bob Jones', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -276,12 +306,10 @@ foreach my $test ( name => 'Bob Jones', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { title => 'Dog poo on walls', @@ -302,12 +330,10 @@ foreach my $test ( name => 'DUDE', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -327,12 +353,10 @@ foreach my $test ( name => 'anonymous', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => {}, errors => [ @@ -352,14 +376,12 @@ foreach my $test ( name => 'Joe Smith', may_show_name => '1', username => 'not an email', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, - changes => { username => 'notanemail', email => 'notanemail' }, + changes => { username => 'notanemail' }, errors => [ 'Please enter a valid email', ], }, { @@ -374,12 +396,10 @@ foreach my $test ( name => '', may_show_name => '1', username => '', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { title => 'Test title', @@ -402,17 +422,14 @@ foreach my $test ( name => ' Bob Jones ', may_show_name => '1', username => ' BOB @ExAmplE.COM ', - email => '', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { name => 'Bob Jones', username => 'bob@example.com', - email => 'bob@example.com', }, errors => [ 'Please enter a subject', 'Please enter some details', ], }, @@ -428,12 +445,10 @@ foreach my $test ( name => 'Bob Jones', may_show_name => '1', username => 'bob@example.com', - email => 'bob@example.com', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { photo1 => '', @@ -452,12 +467,10 @@ foreach my $test ( name => 'Bob Jones', may_show_name => '1', username => 'bob@example.com', - email => 'bob@example.com', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { photo1 => '', @@ -476,18 +489,157 @@ foreach my $test ( name => 'Bob Jones', may_show_name => '1', username => 'bob@example.com', - email => 'bob@example.com', phone => '', category => 'Street lighting', password_sign_in => '', password_register => '', - remember_me => undef, }, changes => { photo1 => '', }, errors => [ "Please enter a subject" ], }, + { + msg => 'Bromley long detail', + pc => 'BR1 3UH', + fields => { + fms_extra_title => 'MR', + title => '', + detail => 'X' . 'x' x 1751, + photo1 => '', + photo2 => '', + photo3 => '', + name => 'Bob Example', + may_show_name => '1', + username => 'bob@example.com', + phone => '', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Reports are limited to 1750 characters in length. Please shorten your report' ], + }, + { + msg => 'Oxfordshire long detail', + pc => 'OX20 1SZ', + fields => { + title => '', + detail => 'X' . 'x' x 1701, + photo1 => '', + photo2 => '', + photo3 => '', + name => 'Bob Example', + may_show_name => '1', + username => 'bob@example.com', + phone => '', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Reports are limited to 1700 characters in length. Please shorten your report' ], + }, + { + msg => 'Lincolnshire long phone', + pc => 'PE9 2GX', + fields => { + title => '', + detail => 'Detail', + photo1 => '', + photo2 => '', + photo3 => '', + name => 'Bob Example', + may_show_name => '1', + username => 'bob@example.com', + phone => '123456789 12345678910', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Phone numbers are limited to 20 characters in length.' ], + }, + { + msg => 'Buckinghamshire long name', + pc => 'RG9 6TL', + fields => { + title => '', + detail => '', + photo1 => '', + photo2 => '', + photo3 => '', + name => 'This is a very long name that should fail validation', + may_show_name => '1', + username => 'bob@example.com', + phone => '', + category => 'Street lighting', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 50 characters in length.' ], + }, + { + msg => 'Rutland long name', + pc => 'LE15 0GJ', + fields => { + title => '', + detail => '', + photo1 => '', + photo2 => '', + photo3 => '', + name => 'This is a very long name that should fail validation', + may_show_name => '1', + username => 'bob@example.com', + phone => '', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 40 characters in length.' ], + }, + { + msg => 'Oxfordshire validation', + pc => 'OX20 1SZ', + fields => { + title => '', + detail => '', + photo1 => '', + photo2 => '', + photo3 => '', + name => 'This is a really extraordinarily long name that definitely should fail validation', + may_show_name => '1', + username => 'bob.has.a.very.long.email@thisisalonghostname.example.com', + phone => '01234 5678910 09876 54321 ext 203', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Please enter a subject', 'Please enter some details', 'Emails are limited to 50 characters in length.', 'Phone numbers are limited to 20 characters in length.', 'Names are limited to 50 characters in length.'], + }, + { + msg => 'Northamptonshire validation', + pc => 'NN1 1NS', + fields => { + title => 'This is a very long title that should fail the validation as it is really much too long to pass the validation of 120 characters', + detail => '', + photo1 => '', + photo2 => '', + photo3 => '', + name => 'A User', + may_show_name => '1', + username => 'user@example.org', + phone => '', + category => 'Trees', + password_sign_in => '', + password_register => '', + }, + changes => { }, + errors => [ 'Summaries are limited to 120 characters in length. Please shorten your summary', 'Please enter some details'], + }, ) { subtest "check form errors where $test->{msg}" => sub { @@ -495,7 +647,7 @@ foreach my $test ( # submit initial pc form FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + ALLOWED_COBRANDS => [ { fixmystreet => '.' }, 'bromley', 'oxfordshire', 'rutland', 'lincolnshire', 'buckinghamshire', 'northamptonshire' ], MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, @@ -679,6 +831,7 @@ subtest "test password errors for a user who is signing in as they report" => su name => 'Joe Bloggs', phone => '01234 567 890', password => 'secret2', + phone_verified => 1, } ), "set user details"; # submit initial pc form @@ -714,6 +867,8 @@ subtest "test password errors for a user who is signing in as they report" => su is_deeply $mech->page_errors, [ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.", ], "check there were errors"; + + $mech->content_lacks('1234', 'phone number not shown'); }; foreach my $test ( @@ -960,12 +1115,26 @@ foreach my $test ( email_count => 1, }, { - desc => "test invalid single_body_only means multiple report bodies", + desc => "test invalid single_body_only means no report bodies", category => 'Street lighting', - councils => [ 2226, 2326 ], + councils => [], extra_fields => { single_body_only => 'Invalid council' }, email_count => 1, }, + { + desc => "test do_not_send means body is ignored", + category => 'Street lighting', + councils => [ 2326 ], + extra_fields => { do_not_send => 'Gloucestershire County Council' }, + email_count => 1, + }, + { + desc => "test single_body_only with Highways England", + category => 'Street lighting', + councils => [ 1000 ], + extra_fields => { single_body_only => 'Highways England' }, + email_count => 1, + }, ) { subtest $test->{desc} => sub { @@ -1036,7 +1205,7 @@ foreach my $test ( ok $report, "Found the report"; # Check the report has been assigned appropriately - is $report->bodies_str, join(',', @body_ids{@{$test->{councils}}}); + is $report->bodies_str, join(',', @body_ids{@{$test->{councils}}}) || undef; $mech->content_contains('Thank you for reporting this issue'); @@ -1177,24 +1346,48 @@ subtest "test report creation for a category that is non public" => sub { $contact2->category( "Pothol\xc3\xa9s" ); $contact2->update; -my $extra_details; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], - MAPIT_URL => 'http://mapit.uk/', -}, sub { - $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon ); -}; -$mech->content_contains( "Pothol\xc3\xa9s" ); -like $extra_details->{councils_text}, qr/<strong>Cheltenham/; -ok !$extra_details->{titles_list}, 'Non Bromley does not send back list of titles'; - -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], - MAPIT_URL => 'http://mapit.uk/', -}, sub { - $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.4021&longitude=0.01578'); +subtest "check map click ajax response" => sub { + my $extra_details; + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon ); + }; + # this order seems to be random so check individually/sort + like $extra_details->{councils_text}, qr/Cheltenham Borough Council/, 'correct council text for two tier'; + like $extra_details->{councils_text}, qr/Gloucestershire County Council/, 'correct council text for two tier'; + like $extra_details->{category}, qr/Pothol\x{00E9}s.*Street lighting/, 'category looks correct for two tier council'; + my @sorted_bodies = sort @{ $extra_details->{bodies} }; + is_deeply \@sorted_bodies, [ "Cheltenham Borough Council", "Gloucestershire County Council" ], 'correct bodies for two tier'; + ok !$extra_details->{titles_list}, 'Non Bromley does not send back list of titles'; + + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.4021&longitude=0.01578'); + }; + ok $extra_details->{titles_list}, 'Bromley sends back list of titles'; + like $extra_details->{councils_text}, qr/Bromley Council/, 'correct council text'; + like $extra_details->{councils_text_private}, qr/^These details will be sent to the council, but will never be shown online/, 'correct private council text'; + like $extra_details->{category}, qr/Trees/, 'category looks correct'; + is_deeply $extra_details->{bodies}, [ "Bromley Council" ], 'correct bodies'; + ok !$extra_details->{contribute_as}, 'no contribute as section'; + ok !$extra_details->{top_message}, 'no top message'; + ok $extra_details->{extra_name_info}, 'extra name info'; + + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=52.563074&longitude=-1.991032' ); + }; + like $extra_details->{councils_text}, qr/^These will be published online for others to see/, 'correct council text for council with no contacts'; + is $extra_details->{category}, '', 'category is empty for council with no contacts'; + is_deeply $extra_details->{bodies}, [ "Sandwell Borough Council" ], 'correct bodies for council with no contacts'; + ok !$extra_details->{extra_name_info}, 'no extra name info'; }; -ok $extra_details->{titles_list}, 'Bromley sends back list of titles'; #### test uploading an image @@ -1552,7 +1745,7 @@ subtest "test Hart" => sub { if ( $test->{confirm} ) { is $mech->uri->path, "/report/new"; my $base = 'www.fixmystreet.com'; - $base = "hart.fixmystreet.com" unless $test->{national}; + $base = '"' unless $test->{national}; $mech->content_contains("$base/report/" . $report->id, "links to correct site"); } else { # receive token @@ -1579,7 +1772,7 @@ subtest "test Hart" => sub { }; my $base = 'www.fixmystreet.com'; - $base = 'hart.fixmystreet.com' unless $test->{national}; + $base = '"' unless $test->{national}; $mech->content_contains( $base . '/report/' . $report->id, 'confirm page links to correct site' ); @@ -1637,9 +1830,12 @@ subtest "unresponsive body handling works" => sub { # Test body-level send method my $old_send = $contact1->body->send_method; $contact1->body->update( { send_method => 'Refused' } ); - $mech->get_ok('/report/new/ajax?latitude=55.952055&longitude=-3.189579'); # Edinburgh my $body_id = $contact1->body->id; - ok $mech->content_like( qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id} ); + my $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=55.952055&longitude=-3.189579'); + like $extra_details->{top_message}, qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id}; + is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set"; + $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Street%20lighting&latitude=55.952055&longitude=-3.189579'); + is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set"; my $test_email = 'test-2@example.com'; $mech->log_out_ok; @@ -1713,8 +1909,10 @@ subtest "unresponsive body handling works" => sub { # And test per-category refusing my $old_email = $contact3->email; $contact3->update( { email => 'REFUSED' } ); - $mech->get_ok('/report/new/category_extras?category=Trees&latitude=51.896268&longitude=-2.093063'); - ok $mech->content_like( qr/Cheltenham.*Trees.*unresponsive.*category=Trees/ ); + $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=51.896268&longitude=-2.093063'); + like $extra_details->{by_category}{$contact3->category}{category_extra}, qr/Cheltenham.*Trees.*unresponsive.*category=Trees/s; + $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Trees&latitude=51.896268&longitude=-2.093063'); + is_deeply $extra_details->{unresponsive}, { $contact3->body->id => 1 }, "unresponsive json set"; $mech->get_ok('/around'); $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } }, "submit location" ); @@ -1879,6 +2077,51 @@ subtest "extra google analytics code displayed on email confirmation problem cre }; }; + +my $private_perms = $mech->create_user_ok('private_perms@example.org', name => 'private', from_body => $bodies[0]); +subtest "report_mark_private allows users to mark reports as private" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + BASE_URL => 'https://www.fixmystreet.com', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->log_out_ok; + + $private_perms->user_body_permissions->find_or_create({ + body => $bodies[0], + permission_type => 'report_mark_private', + }); + + $mech->log_in_ok('private_perms@example.org'); + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } }, + "submit location" ); + $mech->follow_link_ok( + { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" + ); + + $mech->submit_form_ok( + { + with_fields => { + title => "Private report", + detail => 'Private report details.', + photo1 => '', + name => 'Joe Bloggs', + may_show_name => '1', + phone => '07903 123 456', + category => 'Trees', + non_public => 1, + } + }, + "submit good details" + ); + + $mech->content_contains('Great work. Now spread the word', 'shown confirmation page'); + } +}; + +my $inspector = $mech->create_user_ok('inspector@example.org', name => 'inspector', from_body => $bodies[0]); foreach my $test ( { non_public => 0 }, { non_public => 1 }, @@ -1891,12 +2134,11 @@ foreach my $test ( }, sub { $mech->log_out_ok; - my $user = $mech->create_user_ok('inspector@example.org', name => 'inspector', from_body => $bodies[0]); - $user->user_body_permissions->find_or_create({ + $inspector->user_body_permissions->find_or_create({ body => $bodies[0], permission_type => 'planned_reports', }); - $user->user_body_permissions->find_or_create({ + $inspector->user_body_permissions->find_or_create({ body => $bodies[0], permission_type => 'report_inspect', }); @@ -1931,4 +2173,111 @@ foreach my $test ( }; } +subtest "check map click ajax response for inspector" => sub { + $mech->log_out_ok; + + my $extra_details; + $inspector->user_body_permissions->find_or_create({ + body => $bodies[0], + permission_type => 'planned_reports', + }); + $inspector->user_body_permissions->find_or_create({ + body => $bodies[0], + permission_type => 'report_inspect', + }); + + $mech->log_in_ok('inspector@example.org'); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' ); + }; + like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set'; + ok !$extra_details->{contribute_as}, 'no contribute as section'; +}; + +subtest "check map click ajax response for inspector and uk cobrand" => sub { + $mech->log_out_ok; + + my $extra_details; + $inspector->user_body_permissions->find_or_create({ + body => $bodies[4], + permission_type => 'planned_reports', + }); + $inspector->user_body_permissions->find_or_create({ + body => $bodies[4], + permission_type => 'report_inspect', + }); + + $mech->log_in_ok('inspector@example.org'); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { bromley => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.402096&longitude=0.015784' ); + }; + like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set'; +}; + +for my $test ( + { + desc => 'map click ajax for contribute_as_another_user', + permissions => { + contribute_as_another_user => 1, + contribute_as_anonymous_user => undef, + contribute_as_body => undef, + } + }, + { + desc => 'map click ajax for contribute_as_anonymous_user', + permissions => { + contribute_as_another_user => undef, + contribute_as_anonymous_user => 1, + contribute_as_body => undef, + } + }, + { + desc => 'map click ajax for contribute_as_body', + permissions => { + contribute_as_another_user => undef, + contribute_as_anonymous_user => undef, + contribute_as_body => 1, + } + }, +) { + subtest $test->{desc} => sub { + $mech->log_out_ok; + my $extra_details; + (my $name = $test->{desc}) =~ s/.*(contri.*)/$1/; + my $user = $mech->create_user_ok("$name\@example.org", name => 'test user', from_body => $bodies[0]); + for my $p ( keys %{$test->{permissions}} ) { + next unless $test->{permissions}->{$p}; + $user->user_body_permissions->find_or_create({ + body => $bodies[0], + permission_type => $p, + }); + } + $mech->log_in_ok("$name\@example.org"); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' ); + }; + for my $p ( keys %{$test->{permissions}} ) { + (my $key = $p) =~ s/contribute_as_//; + is $extra_details->{contribute_as}->{$key}, $test->{permissions}->{$p}, "$key correctly set"; + } + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.754926&longitude=-1.256179' ); + }; + ok !$extra_details->{contribute_as}, 'no contribute as section for other council'; + }; +} + done_testing(); diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t index 17b489447..dc9a26791 100644 --- a/t/app/controller/report_new_open311.t +++ b/t/app/controller/report_new_open311.t @@ -73,12 +73,10 @@ my $empty_form = { name => '', may_show_name => '1', username => '', - email => '', phone => '', category => '', password_sign_in => '', password_register => '', - remember_me => undef, }; foreach my $test ( { @@ -249,13 +247,18 @@ subtest "Category extras omits description label when all fields are hidden" => ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], MAPIT_URL => 'http://mapit.uk/', }, sub { - my $json = $mech->get_ok_json('/report/new/category_extras?category=Pothole&latitude=55.952055&longitude=-3.189579'); - my $category_extra = $json->{category_extra}; - contains_string($category_extra, "usrn"); - contains_string($category_extra, "central_asset_id"); - lacks_string($category_extra, "USRN", "Lacks 'USRN' label"); - lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label"); - lacks_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Lacks description text"); + for ( + { url => '/report/new/ajax?' }, + { url => '/report/new/category_extras?category=Pothole' }, + ) { + my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579'); + my $category_extra = $json->{by_category} ? $json->{by_category}{Pothole}{category_extra} : $json->{category_extra}; + contains_string($category_extra, "usrn"); + contains_string($category_extra, "central_asset_id"); + lacks_string($category_extra, "USRN", "Lacks 'USRN' label"); + lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label"); + lacks_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Lacks description text"); + } }; }; @@ -264,17 +267,22 @@ subtest "Category extras includes description label for user" => sub { ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], MAPIT_URL => 'http://mapit.uk/', }, sub { - $contact4->push_extra_fields({ description => 'Size?', code => 'size', required => 'true', automated => '', variable => 'true', order => '3' }); + $contact4->push_extra_fields({ description => 'Size?', code => 'size', required => 'true', automated => '', variable => 'true', order => '3', values => undef }); $contact4->update; - - my $json = $mech->get_ok_json('/report/new/category_extras?category=Pothole&latitude=55.952055&longitude=-3.189579'); - my $category_extra = $json->{category_extra}; - contains_string($category_extra, "usrn"); - contains_string($category_extra, "central_asset_id"); - lacks_string($category_extra, "USRN", "Lacks 'USRN' label"); - lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label"); - contains_string($category_extra, "Size?"); - contains_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Contains description text"); + for ( + { url => '/report/new/ajax?' }, + { url => '/report/new/category_extras?category=Pothole' }, + ) { + my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579'); + my $category_extra = $json->{by_category} ? $json->{by_category}{Pothole}{category_extra} : $json->{category_extra}; + contains_string($category_extra, "usrn"); + contains_string($category_extra, "central_asset_id"); + lacks_string($category_extra, "USRN", "Lacks 'USRN' label"); + lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label"); + contains_string($category_extra, "Size?"); + lacks_string($category_extra, '<option value=""'); + contains_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Contains description text"); + } }; }; diff --git a/t/app/controller/report_new_text.t b/t/app/controller/report_new_text.t index cb07e57ee..fad7fb6ab 100644 --- a/t/app/controller/report_new_text.t +++ b/t/app/controller/report_new_text.t @@ -23,7 +23,7 @@ foreach my $test ( username => '0121 4960000000', email => '', phone => '', title => 'Title', detail => 'Detail', name => 'Bob Jones', category => 'Street lighting', - may_show_name => '1', remember_me => undef, + may_show_name => '1', photo1 => '', photo2 => '', photo3 => '', password_register => '', password_sign_in => '', }, @@ -40,7 +40,7 @@ foreach my $test ( username => '0121 4960000', email => '', phone => '', title => 'Title', detail => 'Detail', name => 'Bob Jones', category => 'Street lighting', - may_show_name => '1', remember_me => undef, + may_show_name => '1', photo1 => '', photo2 => '', photo3 => '', password_register => '', password_sign_in => '', }, @@ -222,6 +222,8 @@ subtest "test password errors for a user who is signing in as they report" => su ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], MAPIT_URL => 'http://mapit.uk/', SMS_AUTHENTICATION => 1, + phone_verified => 1, + email_verified => 1, }, sub { $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" ); $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); @@ -245,6 +247,8 @@ subtest "test password errors for a user who is signing in as they report" => su is_deeply $mech->page_errors, [ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.", ], "check there were errors"; + + $mech->content_lacks($user->email, 'email not displayed'); }; subtest "test report creation for a user who is signing in as they report" => sub { @@ -320,7 +324,7 @@ subtest "test report creation for a user who is logged in" => sub { { title => '', detail => '', - may_show_name => '1', + may_show_name => undef, name => 'Joe Bloggs', email => 'joe@example.net', photo1 => '', diff --git a/t/app/controller/report_update_text.t b/t/app/controller/report_update_text.t index a3b767221..4ab8e4bae 100644 --- a/t/app/controller/report_update_text.t +++ b/t/app/controller/report_update_text.t @@ -71,7 +71,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_sign_in => '', password_register => '', }, @@ -90,7 +89,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t index aba7340b0..8ff5b4d24 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -1,3 +1,14 @@ +use strict; +use warnings; + +package FixMyStreet::Cobrand::NoUpdates; + +use parent 'FixMyStreet::Cobrand::FixMyStreet'; + +sub updates_disallowed { 1 } + +package main; + use FixMyStreet::TestMech; use Web::Scraper; use Path::Class; @@ -175,6 +186,20 @@ subtest "several updates shown in correct order" => sub { old_state => 'confirmed', new_state => 'fixed - user', }, + { # One reopening, no associated update + problem_id => $report_id, + whensent => '2011-03-16 08:12:36', + whenanswered => '2011-03-16 08:12:36', + old_state => 'fixed - user', + new_state => 'confirmed', + }, + { # One marking fixed, no associated update + problem_id => $report_id, + whensent => '2011-03-17 08:12:36', + whenanswered => '2011-03-17 08:12:36', + old_state => 'confirmed', + new_state => 'fixed - user', + }, ) { my $q = FixMyStreet::App->model('DB::Questionnaire')->find_or_create( $fields @@ -229,13 +254,15 @@ subtest "several updates shown in correct order" => sub { $mech->get_ok("/report/$report_id"); my $meta = $mech->extract_update_metas; - is scalar @$meta, 6, 'number of updates'; + is scalar @$meta, 8, 'number of updates'; is $meta->[0], 'Posted by Other User at 12:23, Thu 10 March 2011', 'first update'; is $meta->[1], 'Posted by Main User at 12:23, Thu 10 March 2011 Still open, via questionnaire', 'second update'; is $meta->[2], 'Still open, via questionnaire, 12:23, Fri 11 March 2011', 'questionnaire'; is $meta->[3], 'Still open, via questionnaire, 12:23, Sat 12 March 2011', 'questionnaire'; is $meta->[4], 'State changed to: Fixed', 'third update, part 1'; is $meta->[5], 'Posted anonymously at 08:12, Tue 15 March 2011', 'third update, part 2'; + is $meta->[6], 'Still open, via questionnaire, 08:12, Wed 16 March 2011', 'reopen questionnaire'; + is $meta->[7], 'Questionnaire filled in by problem reporter; State changed to: Fixed, 08:12, Thu 17 March 2011', 'fix questionnaire'; $report->questionnaires->delete; }; @@ -252,7 +279,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -271,7 +297,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_sign_in => '', password_register => '', }, @@ -290,7 +315,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -311,7 +335,6 @@ for my $test ( fixed => undef, add_alert => 1, may_show_name => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -345,14 +368,13 @@ for my $test ( initial_values => { name => '', username => '', - may_show_name => 1, + may_show_name => undef, add_alert => 1, photo1 => '', photo2 => '', photo3 => '', update => '', fixed => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -371,14 +393,13 @@ for my $test ( initial_values => { name => '', username => '', - may_show_name => 1, + may_show_name => undef, add_alert => 1, photo1 => '', photo2 => '', photo3 => '', update => '', fixed => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -475,14 +496,13 @@ for my $test ( initial_values => { name => '', username => '', - may_show_name => 1, + may_show_name => undef, add_alert => 1, photo1 => '', photo2 => '', photo3 => '', update => '', fixed => undef, - remember_me => undef, password_register => '', password_sign_in => '', }, @@ -577,7 +597,6 @@ subtest 'check non authority user cannot change set state' => sub { for my $state ( qw/unconfirmed hidden partial/ ) { subtest "check that update cannot set state to $state" => sub { - $mech->log_in_ok( $user->email ); $user->from_body( $body->id ); $user->update; @@ -726,8 +745,6 @@ for my $test ( $report->update; } - $mech->log_in_ok( $user->email ); - if ($test->{view_username}) { ok $user->user_body_permissions->create({ body => $body, @@ -809,7 +826,6 @@ subtest 'check meta correct for comments marked confirmed but not marked open' = }; subtest "check first comment with no status change has no status in meta" => sub { - $mech->log_in_ok( $user->email ); $user->from_body( undef ); $user->update; @@ -823,7 +839,6 @@ subtest "check first comment with no status change has no status in meta" => sub }; subtest "check comment with no status change has not status in meta" => sub { - $mech->log_in_ok( $user->email ); $user->from_body( undef ); $user->update; @@ -1066,8 +1081,6 @@ subtest $test->{desc} => sub { extra => $extra, } ); - $mech->log_in_ok( $user->email ); - ok $user->user_body_permissions->search({ body_id => $body->id, @@ -1132,7 +1145,6 @@ subtest $test->{desc} => sub { extra => $extra, } ); - $mech->log_in_ok( $user->email ); $mech->get_ok("/report/$report_id"); my $update_meta = $mech->extract_update_metas; @@ -1186,7 +1198,6 @@ subtest $test->{desc} => sub { } ); } - $mech->log_in_ok( $user->email ); $mech->get_ok("/report/$report_id"); my $update_meta = $mech->extract_update_metas; @@ -2150,4 +2161,20 @@ subtest 'check cannot answer other user\'s creator fixed questionnaire' => sub { $mech->content_contains( "I'm afraid we couldn't locate your problem in the database." ) }; +subtest 'updates can be provided' => sub { + $mech->log_out_ok(); + $mech->get( "/report/$report_id" ); + $mech->content_contains("Provide an update"); +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { 'noupdates' => '.' } ], +}, sub { + subtest 'test cobrand updates_disallowed' => sub { + $mech->log_out_ok(); + $mech->get( "/report/$report_id" ); + $mech->content_lacks("Provide an update"); + }; +}; + done_testing(); diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t index 8cdfddd1b..ac230ef95 100644 --- a/t/app/controller/reports.t +++ b/t/app/controller/reports.t @@ -1,7 +1,7 @@ use Test::MockTime qw(:all); use FixMyStreet::TestMech; use mySociety::MaPit; -use FixMyStreet::App; +use FixMyStreet::DB; use FixMyStreet::Script::UpdateAllReports; use DateTime; @@ -95,8 +95,19 @@ $fife_problems[10]->update( { state => 'hidden', }); -# Run the cron script old-data (for the table no longer used by default) -FixMyStreet::Script::UpdateAllReports::generate(1); +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', +}, sub { + subtest 'Test the cron script old-data (for the table no longer used by default)' => sub { + FixMyStreet::Script::UpdateAllReports::generate(1); + + # Old style page no longer exists in core, but let's just check the code works okay + my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('fixmystreet')->new(); + FixMyStreet::DB->schema->cobrand($cobrand); + my @bodies = FixMyStreet::DB->resultset('Body')->active->translated->all_sorted; + is $bodies[0]->{url}->(), '/reports/Birmingham'; + }; +}; # Run the cron script that makes the data for /reports so we don't get an error. my $data = FixMyStreet::Script::UpdateAllReports::generate_dashboard(); @@ -115,19 +126,20 @@ $mech->content_contains('5,9,10,22'); $mech->content_contains('2,3,4,4'); FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fixmystreet', MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { with_fields => { body => $body_edin_id } }, 'Submitted dropdown okay' ); - is $mech->uri->path, '/reports/City+of+Edinburgh+Council'; + is $mech->uri->path, '/reports/City+of+Edinburgh'; subtest "test ward pages" => sub { $mech->get_ok('/reports/Birmingham/Bad-Ward'); - is $mech->uri->path, '/reports/Birmingham+City+Council'; - $mech->get_ok('/reports/Birmingham/Aston'); - is $mech->uri->path, '/reports/Birmingham+City+Council/Aston'; - $mech->get_ok('/reports/Birmingham/Aston|Bournville'); - is $mech->uri->path, '/reports/Birmingham+City+Council/Aston%7CBournville'; - $mech->content_contains('Aston, Bournville'); + is $mech->uri->path, '/reports/Birmingham'; + $mech->get_ok('/reports/Birmingham/Bordesley+and+Highgate'); + is $mech->uri->path, '/reports/Birmingham/Bordesley+and+Highgate'; + $mech->get_ok('/reports/Birmingham/Bordesley+and+Highgate|Birchfield'); + is $mech->uri->path, '/reports/Birmingham/Bordesley+and+Highgate%7CBirchfield'; + $mech->content_contains('Birchfield, Bordesley & Highgate'); }; $mech->get_ok('/reports/Westminster'); @@ -203,6 +215,93 @@ is scalar @$problems, 4, 'only public problems are displayed'; $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible'); +for my $permission( qw/ report_inspect report_mark_private / ) { + subtest "user with $permission permission can see non public reports" => sub { + my $body = FixMyStreet::DB->resultset('Body')->find( $body_west_id ); + my $body2 = FixMyStreet::DB->resultset('Body')->find( $body_edin_id ); + my $user = $mech->log_in_ok( 'test@example.com' ); + + # from body, no permission + $user->user_body_permissions->delete(); + $user->update({ from_body => $body }); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 4, 'only public problems are displayed if no permission'; + $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible if no permission'); + $mech->content_lacks('<option value="non_public">Private only</option>'); + + # from body, no permission, limited to private in url + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster?status=non_public'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 4, 'only public problems are displayed if no permission, despite override'; + $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible despite override'); + + # from body, has permission + $user->user_body_permissions->find_or_create({ + body => $body, + permission_type => $permission, + }); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 5, 'public and non-public problems are displayed if permission'; + $mech->content_contains('All reports Test 3 for ' . $body_west_id, 'non public problem is visible if permission'); + $mech->content_contains('<option value="non_public">Private only</option>'); + + # From body, limited to private only + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster?status=non_public'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 1, 'only non-public problems are displayed with non_public filter'; + $mech->content_contains('All reports Test 3 for ' . $body_west_id, 'non public problem is visible with non_public filter'); + $mech->content_lacks('All reports Test 4 for ' . $body_west_id, 'public problem is not visible with non_public filter'); + + # from other body, has permission + $user->user_body_permissions->delete(); + $user->update({ from_body => $body2 }); + $user->user_body_permissions->find_or_create({ + body => $body2, + permission_type => $permission, + }); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 4, 'only public problems are displayed for other body user'; + $mech->content_contains('<option value="non_public">Private only</option>'); + $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible for other body user'); + + # From other body, limited to private only + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/reports/Westminster?status=non_public'); + }; + $problems = $mech->extract_problem_list; + is scalar @$problems, 4, 'non-public problems are not displayed for other body with override'; + $mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible for other body with override'); + }; +} + # No change to numbers if report is non-public FixMyStreet::override_config { TEST_DASHBOARD_DATA => $data, @@ -253,7 +352,7 @@ subtest "it lists shortlisted reports" => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/' }, sub { - my $body = FixMyStreet::App->model('DB::Body')->find( $body_edin_id ); + my $body = FixMyStreet::DB->resultset('Body')->find( $body_edin_id ); my $user = $mech->log_in_ok( 'test@example.com' ); $user->update({ from_body => $body }); $user->user_body_permissions->find_or_create({ @@ -303,7 +402,7 @@ subtest "it allows body users to filter by subtypes" => sub { FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/' }, sub { - my $body = FixMyStreet::App->model('DB::Body')->find( $body_edin_id ); + my $body = FixMyStreet::DB->resultset('Body')->find( $body_edin_id ); my $user = $mech->log_in_ok( 'test@example.com' ); $user->update({ from_body => $body }); @@ -362,7 +461,7 @@ subtest "it does not allow body users to filter subcategories for other bodies" FixMyStreet::override_config { MAPIT_URL => 'http://mapit.uk/' }, sub { - my $body = FixMyStreet::App->model('DB::Body')->find( $body_west_id ); + my $body = FixMyStreet::DB->resultset('Body')->find( $body_west_id ); my $user = $mech->log_in_ok( 'test@example.com' ); $user->update({ from_body => $body }); diff --git a/t/app/controller/root.t b/t/app/controller/root.t index ddf659b77..85119da24 100644 --- a/t/app/controller/root.t +++ b/t/app/controller/root.t @@ -1,4 +1,5 @@ use FixMyStreet::TestMech; +use Test::MockModule; ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); @@ -73,4 +74,17 @@ FixMyStreet::override_config { }; }; +subtest "check_login_disallowed cobrand hook" => sub { + my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Default'); + $cobrand->mock('check_login_disallowed', sub { + my $self = shift; + return 0 if $self->{c}->req->path eq 'auth'; + return 1; + } + ); + + $mech->get_ok('/'); + is $mech->uri->path_query, '/auth?r=', 'redirects to auth page'; +}; + done_testing(); diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t index c978b5ccf..124e838ee 100644 --- a/t/app/model/alert_type.t +++ b/t/app/model/alert_type.t @@ -22,6 +22,8 @@ my $user3 = ->find_or_create( { email => 'bystander@example.com', name => 'Bystander' } ); ok $user3, "created bystander"; +my $body = $mech->create_body_ok(2504, 'Westminster'); + my $dt = DateTime->new( year => 2011, month => 04, @@ -34,7 +36,7 @@ my $dt = DateTime->new( my $report = FixMyStreet::DB->resultset('Problem')->find_or_create( { postcode => 'SW1A 1AA', - bodies_str => '2504', + bodies_str => $body->id, areas => ',105255,11806,11828,2247,2504,', category => 'Other', title => 'Test 2', @@ -165,8 +167,8 @@ $report->update(); my $council_alert = FixMyStreet::DB->resultset('Alert')->find_or_create( { user => $user2, - parameter => 2504, - parameter2 => 2504, + parameter => $body->id, + parameter2 => $body->id, alert_type => 'council_problems', whensubscribed => $dt->ymd . ' ' . $dt->hms, confirmed => 1, diff --git a/t/app/model/photoset.t b/t/app/model/photoset.t index d171ba88b..29a28d232 100644 --- a/t/app/model/photoset.t +++ b/t/app/model/photoset.t @@ -15,7 +15,10 @@ my $db = FixMyStreet::DB->schema; my $user = $db->resultset('User')->find_or_create({ name => 'Bob', email => 'bob@example.com' }); FixMyStreet::override_config { - UPLOAD_DIR => $UPLOAD_DIR, + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { my $image_path = path('t/app/controller/sample.jpg'); @@ -69,4 +72,29 @@ subtest 'Photoset with 3 referenced photo' => sub { }; +subtest 'Correct storage backends are instantiated' => sub { + FixMyStreet::override_config { + PHOTO_STORAGE_BACKEND => 'FileSystem' + }, sub { + my $photoset = FixMyStreet::App::Model::PhotoSet->new; + isa_ok $photoset->storage, 'FixMyStreet::PhotoStorage::FileSystem'; + }; + + FixMyStreet::override_config { + PHOTO_STORAGE_BACKEND => undef + }, sub { + my $photoset = FixMyStreet::App::Model::PhotoSet->new; + isa_ok $photoset->storage, 'FixMyStreet::PhotoStorage::FileSystem'; + }; + + FixMyStreet::override_config { + PHOTO_STORAGE_BACKEND => 'S3' + }, sub { + my $photoset = FixMyStreet::App::Model::PhotoSet->new; + isa_ok $photoset->storage, 'FixMyStreet::PhotoStorage::S3'; + }; + +}; + + done_testing(); diff --git a/t/app/model/problem.t b/t/app/model/problem.t index b9bbe4682..503fa9276 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -633,7 +633,7 @@ subtest 'check can set multiple emails as a single contact' => sub { subtest 'check can turn on report sent email alerts' => sub { my $send_confirmation_mail_override = Sub::Override->new( "FixMyStreet::Cobrand::Default::report_sent_confirmation_email", - sub { return 1; } + sub { return 'external_id'; } ); $mech->clear_emails_ok; diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t index 169895f95..aa684a68c 100644 --- a/t/app/model/questionnaire.t +++ b/t/app/model/questionnaire.t @@ -1,3 +1,14 @@ +package FixMyStreet::Cobrand::Tester; + +use parent 'FixMyStreet::Cobrand::Default'; + +sub send_questionnaire { + my ($self, $row) = @_; + return $row->latitude == 1; +} + +package main; + use FixMyStreet; use FixMyStreet::TestMech; @@ -27,7 +38,7 @@ my $problem = FixMyStreet::DB->resultset('Problem')->create( my $mech = FixMyStreet::TestMech->new; -for my $test ( +for my $test ( { state => 'unconfirmed', send_email => 0, @@ -74,22 +85,22 @@ for my $test ( }, { state => 'duplicate', - send_email => 1, + send_email => 0, }, { state => 'unable to fix', - send_email => 1, + send_email => 0, }, { state => 'not responsible', - send_email => 1, + send_email => 0, }, { state => 'closed', - send_email => 1, + send_email => 0, }, ) { - subtest "correct questionnaire behviour for state $test->{state}" => sub { + subtest "correct questionnaire behaviour for state $test->{state}" => sub { $problem->discard_changes; $problem->state( $test->{state} ); $problem->send_questionnaire( 1 ); @@ -108,4 +119,29 @@ for my $test ( } } +for my $test ( + { latitude => 2, emails => 0, }, + { latitude => 1, emails => 1, }, +) { + subtest "test cobrand questionnaire send override, expecting $test->{emails} email" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'tester', + }, sub { + $problem->latitude($test->{latitude}); + $problem->send_questionnaire(1); + $problem->state('confirmed'); + $problem->update; + $problem->questionnaires->delete; + + $mech->email_count_is(0); + FixMyStreet::DB->resultset('Questionnaire')->send_questionnaires( { site => 'tester' } ); + $mech->email_count_is($test->{emails}); + $mech->clear_emails_ok(); + + $problem->discard_changes; + is $problem->send_questionnaire, 0; + }; + }; +} + done_testing(); diff --git a/t/app/sendreport/angus.t b/t/app/sendreport/angus.t deleted file mode 100644 index 41379b4ff..000000000 --- a/t/app/sendreport/angus.t +++ /dev/null @@ -1,56 +0,0 @@ -use FixMyStreet::Test; - -use_ok("FixMyStreet::SendReport::Angus"); - -my $u = FixMyStreet::DB->resultset('User')->new( { email => 'test@example.org', name => 'A User' } ); - -my $p = FixMyStreet::DB->resultset('Problem')->new( { - latitude => 1, - longitude => 1, - title => 'title', - detail => 'detail', - user => $u, - id => 1, - name => 'A User', - cobrand => 'fixmystreet', -} ); - -my $angus = FixMyStreet::SendReport::Angus->new(); - -subtest 'parses authentication token correctly' => sub { - my $authxml = <<EOT; - <AuthenticateResponse> - - <AuthenticateResult> - TVRreUxqRTJPQzR5TlRVdU1qSjhNakF4Tmpvd01Ub3lNam94TlRvME16b3pPUT09VGhvdVNoYWx0Tm90UGFzcw== - </AuthenticateResult> - <success> - True - </success> - <message></message> - - </AuthenticateResponse> -EOT -; - is $angus->get_auth_token($authxml), 'TVRreUxqRTJPQzR5TlRVdU1qSjhNakF4Tmpvd01Ub3lNam94TlRvME16b3pPUT09VGhvdVNoYWx0Tm90UGFzcw==', 'token correct'; -}; - -subtest 'parses report external id correctly' => sub { - my $respxml = <<EOT; -<CreateRequestResponse> - - <CreateRequestResult> - <RequestId>7245</RequestId> - </CreateRequestResult> - - <success>True</success> - <message></message> - -</CreateRequestResponse> -EOT -; - is $angus->get_external_id($respxml), '7245', 'external id correct'; -}; - - -done_testing(); diff --git a/t/app/sendreport/blackhole.t b/t/app/sendreport/blackhole.t new file mode 100644 index 000000000..4335f3675 --- /dev/null +++ b/t/app/sendreport/blackhole.t @@ -0,0 +1,42 @@ +use FixMyStreet; +use FixMyStreet::DB; +use FixMyStreet::TestMech; +use FixMyStreet::Script::Reports; + +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); + +my $user = $mech->create_user_ok( 'user@example.com' ); + +my $body = $mech->create_body_ok( 2551, 'Bath and North East Somerset Council'); +$body->update({ can_be_devolved => 1 }); + +my $contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Play area safety issue', + email => 'test@example.org', + send_method => 'Blackhole', +); + +my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', { + cobrand => 'bathnes', + category => $contact->category, + user => $user, +}); +my $report = $reports[0]; + +FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, +}, sub { + subtest "Report isn't sent anywhere" => sub { + $mech->clear_emails_ok; + + FixMyStreet::Script::Reports::send(); + + ok $mech->email_count_is(0), "Report email wasn't sent"; + + $report->discard_changes; + ok $report->whensent, "Report has been marked as sent"; + }; +}; + +done_testing(); diff --git a/t/app/sendreport/email.t b/t/app/sendreport/email.t index 6b292725b..3e6db4f67 100644 --- a/t/app/sendreport/email.t +++ b/t/app/sendreport/email.t @@ -20,6 +20,8 @@ my $contact = $mech->create_contact_ok( ); my $row = FixMyStreet::DB->resultset('Problem')->new( { + latitude => 51.023569, + longitude => -3.099055, bodies_str => '1000', category => 'category', cobrand => '', @@ -67,4 +69,19 @@ foreach my $test ( { }; } +$body->body_areas->delete; +$body->body_areas->create({ area_id => 2429 }); + +subtest 'Test special behaviour' => sub { + my $e = FixMyStreet::SendReport::Email->new; + $contact->update( { state => 'confirmed', email => 'SPECIAL' } ); + $e->add_body( $body ); + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/' + }, sub { + my ($e) = $e->build_recipient_list( $row, {} ); + like $e->[0], qr/tauntondeane/, 'correct recipient'; + }; +}; + done_testing(); diff --git a/t/app/sendreport/email/highways.t b/t/app/sendreport/email/highways.t new file mode 100644 index 000000000..f53062336 --- /dev/null +++ b/t/app/sendreport/email/highways.t @@ -0,0 +1,32 @@ +use FixMyStreet::SendReport::Email::Highways; +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); +my $highways = $mech->create_body_ok(2482, 'Highways England'); + +$mech->create_contact_ok(email => 'council@example.com', body_id => $bromley->id, category => 'Graffiti'); +$mech->create_contact_ok(email => 'council@example.com', body_id => $bromley->id, category => 'Faulty street light'); +$mech->create_contact_ok(email => 'highways@example.com', body_id => $highways->id, category => 'Pothole'); + +my $row = FixMyStreet::DB->resultset('Problem')->new( { + bodies_str => '1000', + category => 'Pothole', + cobrand => '', +} ); + +my $e = FixMyStreet::SendReport::Email::Highways->new; +is $e->build_recipient_list($row), undef, 'no recipients if no body'; + +$e = FixMyStreet::SendReport::Email::Highways->new; +$e->add_body($bromley); +is $e->build_recipient_list($row), undef, 'no recipients if category missing'; + +$e = FixMyStreet::SendReport::Email::Highways->new; +$e->add_body($highways); +is $e->build_recipient_list($row), 1, 'correct recipient list count'; +is_deeply $e->to, [ [ 'highways@example.com', 'Highways England' ] ], 'correct To line'; + +done_testing(); + diff --git a/t/app/sendreport/email/tfl.t b/t/app/sendreport/email/tfl.t new file mode 100644 index 000000000..0322de551 --- /dev/null +++ b/t/app/sendreport/email/tfl.t @@ -0,0 +1,32 @@ +use FixMyStreet::SendReport::Email::TfL; +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +my $bromley = $mech->create_body_ok(2482, 'Bromley Council'); +my $tfl = $mech->create_body_ok(2482, 'TfL'); + +$mech->create_contact_ok(email => 'council@example.com', body_id => $bromley->id, category => 'Graffiti'); +$mech->create_contact_ok(email => 'council@example.com', body_id => $bromley->id, category => 'Faulty street light'); +$mech->create_contact_ok(email => 'tfl@example.com', body_id => $tfl->id, category => 'Traffic lights'); + +my $row = FixMyStreet::DB->resultset('Problem')->new( { + bodies_str => '1000', + category => 'Faulty street light', + cobrand => '', +} ); + +my $e = FixMyStreet::SendReport::Email::TfL->new; +is $e->build_recipient_list($row), undef, 'no recipients if no body'; + +$e = FixMyStreet::SendReport::Email::TfL->new; +$e->add_body($bromley); +is $e->build_recipient_list($row), undef, 'no recipients if category missing'; + +$e = FixMyStreet::SendReport::Email::TfL->new; +$e->add_body($tfl); +is $e->build_recipient_list($row), 1, 'correct recipient list count'; +is_deeply $e->to, [ [ 'tfl@example.com', 'TfL' ] ], 'correct To line'; + +done_testing(); + diff --git a/t/app/sendreport/open311.t b/t/app/sendreport/open311.t index 32564dbd8..54aaa39d0 100644 --- a/t/app/sendreport/open311.t +++ b/t/app/sendreport/open311.t @@ -14,7 +14,6 @@ sub test_overrides; # defined below use constant TEST_USER_EMAIL => 'fred@example.com'; my %standard_open311_parameters = ( - 'use_extended_updates' => 0, 'send_notpinpointed' => 0, 'extended_description' => 1, 'use_service_as_deviceid' => 0, @@ -49,9 +48,6 @@ test_overrides oxfordshire => 'open311' => noclass(superhashof({ %standard_open311_parameters, 'extended_description' => 'oxfordshire', - 'endpoints' => { - 'requests' => 'open311_service_request.cgi' - }, })), problem_extra => bag( { name => 'northing', value => 100 }, diff --git a/t/app/uri_for.t b/t/app/uri_for.t index 7d9c8dc07..61713f8b7 100644 --- a/t/app/uri_for.t +++ b/t/app/uri_for.t @@ -13,7 +13,6 @@ use URI; use_ok('FixMyStreet::App'); my $fms_c = ctx_request('http://www.fixmystreet.com/'); -my $fgm_c = ctx_request('http://www.fiksgatami.no/'); is( $fms_c->uri_for('/bar/baz') . "", @@ -33,11 +32,4 @@ is( 'URI with query' ); -# fiksgatami -is( - $fgm_c->uri_for( '/foo', { lat => 1.23, } ) . "", - 'http://www.fiksgatami.no/foo?lat=1.23&zoom=3', - 'FiksGataMi url with lat not zoom' -); - done_testing(); diff --git a/t/cobrand/bathnes.t b/t/cobrand/bathnes.t index e0ad07c16..6586dcb96 100644 --- a/t/cobrand/bathnes.t +++ b/t/cobrand/bathnes.t @@ -64,15 +64,10 @@ subtest 'extra CSV columns are absent if permission not granted' => sub { $mech->get_ok('/dashboard?export=1'); - open my $data_handle, '<', \$mech->content; - my $csv = Text::CSV->new( { binary => 1 } ); - my @rows; - while ( my $row = $csv->getline( $data_handle ) ) { - push @rows, $row; - } + my @rows = $mech->content_as_csv; is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines'; - is scalar @{$rows[0]}, 18, '18 columns present'; + is scalar @{$rows[0]}, 20, '20 columns present'; is_deeply $rows[0], [ @@ -94,6 +89,8 @@ subtest 'extra CSV columns are absent if permission not granted' => sub { 'Easting', 'Northing', 'Report URL', + 'Site Used', + 'Reported As', ], 'Column headers look correct'; }; @@ -103,7 +100,7 @@ subtest "Custom CSV fields permission can be granted" => sub { is $counciluser->user_body_permissions->count, 0, 'counciluser has no permissions'; - $mech->get_ok("/admin/user_edit/" . $counciluser->id); + $mech->get_ok("/admin/users/" . $counciluser->id); $mech->content_contains('Extra columns in CSV export'); $mech->submit_form_ok( { with_fields => { @@ -123,12 +120,7 @@ subtest 'extra CSV columns are present if permission granted' => sub { $mech->get_ok('/dashboard?export=1'); - open my $data_handle, '<', \$mech->content; - my $csv = Text::CSV->new( { binary => 1 } ); - my @rows; - while ( my $row = $csv->getline( $data_handle ) ) { - push @rows, $row; - } + my @rows = $mech->content_as_csv; is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines'; is scalar @{$rows[0]}, 24, '24 columns present'; @@ -153,42 +145,55 @@ subtest 'extra CSV columns are present if permission granted' => sub { 'Easting', 'Northing', 'Report URL', + 'Site Used', + 'Reported As', 'User Email', 'User Phone', - 'Reported As', 'Staff User', 'Attribute Data', - 'Site Used', ], 'Column headers look correct'; - is $rows[1]->[18], 'normaluser@example.com', 'User email is correct'; - is $rows[1]->[19], '+447123456789', 'User phone number is correct'; - is $rows[1]->[20], '', 'Reported As is empty if not made on behalf of another user/body'; - is $rows[1]->[21], '', 'Staff User is empty if not made on behalf of another user'; - is $rows[1]->[22], 'width = 10cm; depth = 25cm', 'Attribute Data is correct'; - is $rows[1]->[23], 'iOS', 'Site Used shows whether report made via app'; - - is $rows[2]->[18], 'counciluser@example.com', 'User email is correct'; - is $rows[2]->[19], '', 'User phone number is correct'; - is $rows[2]->[20], 'body', 'Reported As is correct if made on behalf of body'; - is $rows[2]->[21], '', 'Staff User is empty if not made on behalf of another user'; - is $rows[2]->[22], '', 'Attribute Data is correct'; - is $rows[2]->[23], 'bathnes', 'Site Used shows correct cobrand'; - - is $rows[3]->[18], 'normaluser@example.com', 'User email is correct'; - is $rows[3]->[19], '+447123456789', 'User phone number is correct'; - is $rows[3]->[20], 'another_user', 'Reported As is set if reported on behalf of another user'; - is $rows[3]->[21], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user'; - is $rows[3]->[22], '', 'Attribute Data is correct'; - is $rows[3]->[23], 'bathnes', 'Site Used shows correct cobrand'; - - is $rows[4]->[18], 'counciluser@example.com', 'User email is correct'; - is $rows[4]->[19], '', 'User phone number is correct'; - is $rows[4]->[20], 'anonymous_user', 'Reported As is set if reported on behalf of another user'; - is $rows[4]->[21], '', 'Staff User is empty if not made on behalf of another user'; - is $rows[4]->[22], '', 'Attribute Data is correct'; - is $rows[4]->[23], 'bathnes', 'Site Used shows correct cobrand'; + is $rows[1]->[18], 'iOS', 'Site Used shows whether report made via app'; + is $rows[1]->[19], '', 'Reported As is empty if not made on behalf of another user/body'; + is $rows[1]->[20], 'normaluser@example.com', 'User email is correct'; + is $rows[1]->[21], '+447123456789', 'User phone number is correct'; + is $rows[1]->[22], '', 'Staff User is empty if not made on behalf of another user'; + is $rows[1]->[23], 'width = 10cm; depth = 25cm', 'Attribute Data is correct'; + + is $rows[2]->[18], 'bathnes', 'Site Used shows correct cobrand'; + is $rows[2]->[19], 'body', 'Reported As is correct if made on behalf of body'; + is $rows[2]->[20], 'counciluser@example.com', 'User email is correct'; + is $rows[2]->[21], '', 'User phone number is correct'; + is $rows[2]->[22], '', 'Staff User is empty if not made on behalf of another user'; + is $rows[2]->[23], '', 'Attribute Data is correct'; + + is $rows[3]->[18], 'bathnes', 'Site Used shows correct cobrand'; + is $rows[3]->[19], 'another_user', 'Reported As is set if reported on behalf of another user'; + is $rows[3]->[20], 'normaluser@example.com', 'User email is correct'; + is $rows[3]->[21], '+447123456789', 'User phone number is correct'; + is $rows[3]->[22], 'counciluser@example.com', 'Staff User is correct if made on behalf of another user'; + is $rows[3]->[23], '', 'Attribute Data is correct'; + + is $rows[4]->[18], 'bathnes', 'Site Used shows correct cobrand'; + is $rows[4]->[19], 'anonymous_user', 'Reported As is set if reported on behalf of another user'; + is $rows[4]->[20], 'counciluser@example.com', 'User email is correct'; + is $rows[4]->[21], '', 'User phone number is correct'; + is $rows[4]->[22], '', 'Staff User is empty if not made on behalf of another user'; + is $rows[4]->[23], '', 'Attribute Data is correct'; + + $mech->get_ok('/dashboard?export=1&updates=1'); + + @rows = $mech->content_as_csv; + is scalar @rows, 1, '1 (header) + 0 (updates)'; + is scalar @{$rows[0]}, 10, '10 columns present'; + is_deeply $rows[0], + [ + 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state', + 'Text', 'User Name', 'Reported As', 'Staff User', + 'User Email', + ], + 'Column headers look correct'; }; diff --git a/t/cobrand/bristol.t b/t/cobrand/bristol.t index b4b6ed4ac..b2b8cff13 100644 --- a/t/cobrand/bristol.t +++ b/t/cobrand/bristol.t @@ -1,6 +1,8 @@ use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; +use Open311::PopulateServiceList; + # Create test data my $body = $mech->create_body_ok( 2561, 'Bristol County Council', { send_method => 'Open311', @@ -41,4 +43,68 @@ subtest 'All categories are shown on FMS cobrand', sub { }; }; +subtest 'check services override' => sub { + my $processor = Open311::PopulateServiceList->new(); + + my $meta_xml = '<?xml version="1.0" encoding="utf-8"?> +<service_definition> + <service_code>LIGHT</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>easting</code> + <datatype>string</datatype> + <required>true</required> + <order>1</order> + <description>Easting</description> + </attribute> + <attribute> + <variable>true</variable> + <code>size</code> + <datatype>string</datatype> + <required>true</required> + <order>2</order> + <description>How big is the pothole</description> + </attribute> + </attributes> +</service_definition> + '; + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/LIGHT.xml' => $meta_xml } + ); + + $processor->_current_open311( $o ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'bristol' ], + }, sub { + $processor->_current_body( $body ); + }; + $processor->_current_service( { service_code => 'LIGHT' } ); + $processor->_add_meta_to_contact( $open311_contact ); + + my $extra = [ { + automated => 'server_set', + variable => 'true', + code => 'easting', + datatype => 'string', + required => 'true', + order => 1, + description => 'Easting', + }, { + variable => 'true', + code => 'size', + datatype => 'string', + required => 'true', + order => 2, + description => 'How big is the pothole', + } ]; + + $open311_contact->discard_changes; + is_deeply $open311_contact->get_extra_fields, $extra, 'Easting has automated set'; +}; + done_testing(); diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t index b3fb3564b..6750d3183 100644 --- a/t/cobrand/bromley.t +++ b/t/cobrand/bromley.t @@ -4,7 +4,7 @@ use FixMyStreet::Script::Reports; my $mech = FixMyStreet::TestMech->new; # Create test data -my $user = $mech->create_user_ok( 'bromley@example.com' ); +my $user = $mech->create_user_ok( 'bromley@example.com', name => 'Bromley' ); my $body = $mech->create_body_ok( 2482, 'Bromley Council'); my $contact = $mech->create_contact_ok( body_id => $body->id, @@ -16,10 +16,19 @@ $contact->set_extra_fields( { code => 'easting', datatype => 'number', }, { code => 'northing', datatype => 'number', }, { code => 'service_request_id_ext', datatype => 'number', }, + { code => 'service_sub_code', values => [ { key => 'RED', name => 'Red' }, { key => 'BLUE', name => 'Blue' } ], }, ); $contact->update; +my $tfl = $mech->create_body_ok( 2482, 'TfL'); +$mech->create_contact_ok( + body_id => $tfl->id, + category => 'Traffic Lights', + email => 'tfl@example.org', +); my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', { + latitude => 51.402096, + longitude => 0.015784, cobrand => 'bromley', user => $user, }); @@ -51,8 +60,8 @@ for my $test ( desc => 'testing special Open311 behaviour', updates => {}, expected => { - 'attribute[easting]' => 529025, - 'attribute[northing]' => 179716, + 'attribute[easting]' => 540315, + 'attribute[northing]' => 168935, 'attribute[service_request_id_ext]' => $report->id, 'attribute[report_title]' => 'Test Test 1 for ' . $body->id, 'jurisdiction_id' => 'FMS', @@ -66,8 +75,8 @@ for my $test ( postcode => '' }, expected => { - 'attribute[easting]' => 529025, - 'attribute[northing]' => 179716, + 'attribute[easting]' => 540315, + 'attribute[northing]' => 168935, 'attribute[service_request_id_ext]' => $report->id, 'jurisdiction_id' => 'FMS', 'address_id' => '#NOTPINPOINTED#', @@ -168,4 +177,67 @@ for my $test ( }; } +subtest 'check display of TfL reports' => sub { + $mech->create_problems_for_body( 1, $tfl->id, 'TfL Test', { + latitude => 51.402096, + longitude => 0.015784, + cobrand => 'bromley', + user => $user, + }); + $mech->get_ok( '/report/' . $report->id ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->follow_link_ok({ text_regex => qr/Back to all reports/i }); + }; + $mech->content_like(qr{<a title="TfL Test[^>]*www.example.org[^>]*><img[^>]*grey}); + $mech->content_like(qr{<a title="Test Test[^>]*href="/[^>]*><img[^>]*yellow}); +}; + +subtest 'check geolocation overrides' => sub { + my $cobrand = FixMyStreet::Cobrand::Bromley->new; + foreach my $test ( + { query => 'Main Rd, BR1', town => 'Bromley', string => 'Main Rd' }, + { query => 'Main Rd, BR3', town => 'Beckenham', string => 'Main Rd' }, + { query => 'Main Rd, BR4', town => 'West Wickham', string => 'Main Rd' }, + { query => 'Main Rd, BR5', town => 'Orpington', string => 'Main Rd' }, + { query => 'Main Rd, BR7', town => 'Chislehurst', string => 'Main Rd' }, + { query => 'Main Rd, BR8', town => 'Swanley', string => 'Main Rd' }, + { query => 'Old Priory Avenue', town => 'BR6 0PL', string => 'Old Priory Avenue' }, + ) { + my $res = $cobrand->disambiguate_location($test->{query}); + is $res->{town}, $test->{town}, "Town matches $test->{town}"; + is $res->{string}, $test->{string}, "String matches $test->{string}"; + } +}; + +subtest 'check special subcategories in admin' => sub { + $mech->create_user_ok('superuser@example.com', is_superuser => 1); + $mech->log_in_ok('superuser@example.com'); + $user->update({ from_body => $body->id }); + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok('/admin/users/' . $user->id); + $mech->submit_form_ok({ with_fields => { 'contacts['.$contact->id.']' => 1, 'contacts[BLUE]' => 1 } }); + }; + $user->discard_changes; + is_deeply $user->get_extra_metadata('categories'), [ $contact->id ]; + is_deeply $user->get_extra_metadata('subcategories'), [ 'BLUE' ]; +}; + +subtest 'check heatmap page' => sub { + $user->update({ area_ids => [ 60705 ] }); + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->log_in_ok($user->email); + $mech->get_ok('/about/heatmap?end_date=2018-12-31'); + $mech->get_ok('/about/heatmap?filter_category=RED&ajax=1'); + }; +}; + done_testing(); diff --git a/t/cobrand/bucks.t b/t/cobrand/bucks.t new file mode 100644 index 000000000..965b90107 --- /dev/null +++ b/t/cobrand/bucks.t @@ -0,0 +1,245 @@ +use Test::MockModule; +use FixMyStreet::TestMech; +use FixMyStreet::Script::Reports; + +my $mech = FixMyStreet::TestMech->new; + +my $body = $mech->create_body_ok(2217, 'Buckinghamshire', { + send_method => 'Open311', api_key => 'key', endpoint => 'endpoint', jurisdiction => 'fms' }); +my $counciluser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body); + +$mech->create_contact_ok(body_id => $body->id, category => 'Flytipping', email => "FLY"); +$mech->create_contact_ok(body_id => $body->id, category => 'Potholes', email => "POT"); +$mech->create_contact_ok(body_id => $body->id, category => 'Blocked drain', email => "DRA"); + +my $district = $mech->create_body_ok(2257, 'Chiltern'); +$mech->create_contact_ok(body_id => $district->id, category => 'Flytipping', email => "flytipping\@chiltern"); +$mech->create_contact_ok(body_id => $district->id, category => 'Graffiti', email => "graffiti\@chiltern"); + +my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Buckinghamshire'); +$cobrand->mock('lookup_site_code', sub { + my ($self, $row, $buffer) = @_; + return "Road ID" if $row->latitude == 51.812244; +}); + +FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'buckinghamshire', 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', + STAGING_FLAGS => { send_reports => 1, skip_checks => 0 }, +}, sub { + +subtest 'cobrand displays council name' => sub { + ok $mech->host("buckinghamshire.fixmystreet.com"), "change host to bucks"; + $mech->get_ok('/'); + $mech->content_contains('Buckinghamshire'); +}; + +subtest 'cobrand displays correct categories' => sub { + my $json = $mech->get_ok_json('/report/new/ajax?latitude=51.615559&longitude=-0.556903'); + is @{$json->{bodies}}, 2, 'Both Chiltern and Bucks returned'; + like $json->{category}, qr/Flytipping/, 'Flytipping displayed'; + like $json->{category}, qr/Blocked drain/, 'Blocked drain displayed'; + unlike $json->{category}, qr/Graffiti/, 'Graffiti not displayed'; + $json = $mech->get_ok_json('/report/new/category_extras?latitude=51.615559&longitude=-0.556903'); + is @{$json->{bodies}}, 2, 'Still both Chiltern and Bucks returned'; +}; + +my ($report) = $mech->create_problems_for_body(1, $body->id, 'On Road', { + category => 'Flytipping', cobrand => 'fixmystreet', + latitude => 51.812244, longitude => -0.827363, +}); + +subtest 'flytipping on road sent to extra email' => sub { + FixMyStreet::Script::Reports::send(); + my @email = $mech->get_email; + my $tfb = join('', 'illegaldumpingcosts', '@', 'buckscc.gov.uk'); + is $email[0]->header('To'), '"TfB" <' . $tfb . '>'; + like $mech->get_text_body_from_email($email[1]), qr/report's reference number/; + $report->discard_changes; + is $report->external_id, 248, 'Report has right external ID'; +}; + +($report) = $mech->create_problems_for_body(1, $body->id, 'On Road', { + category => 'Potholes', cobrand => 'fixmystreet', + latitude => 51.812244, longitude => -0.827363, + extra => { + contributed_as => 'another_user', + contributed_by => $counciluser->id, + }, +}); + +subtest 'pothole on road not sent to extra email, only confirm sent' => sub { + $mech->clear_emails_ok; + FixMyStreet::Script::Reports::send(); + $mech->email_count_is(1); + like $mech->get_text_body_from_email, qr/report's reference number/; + $report->discard_changes; + is $report->external_id, 248, 'Report has right external ID'; +}; + +($report) = $mech->create_problems_for_body(1, $district->id, 'Off Road', { + category => 'Flytipping', cobrand => 'buckinghamshire', + latitude => 51.813173, longitude => -0.826741, +}); +subtest 'flytipping off road sent to extra email' => sub { + FixMyStreet::Script::Reports::send(); + my @email = $mech->get_email; + is $email[0]->header('To'), '"Chiltern" <flytipping@chiltern>'; + like $mech->get_text_body_from_email($email[1]), qr/Please note that Buckinghamshire County Council is not responsible/; + $report->discard_changes; + is $report->external_id, undef, 'Report has right external ID'; +}; + +my ($report2) = $mech->create_problems_for_body(1, $body->id, 'Drainage problem', { + category => 'Blocked drain', cobrand => 'fixmystreet', + latitude => 51.812244, longitude => -0.827363, +}); + +subtest 'blocked drain sent to extra email' => sub { + $mech->clear_emails_ok; + FixMyStreet::Script::Reports::send(); + my @email = $mech->get_email; + my $e = join('@', 'floodmanagement', 'buckscc.gov.uk'); + is $email[0]->header('To'), '"Flood Management" <' . $e . '>'; + like $mech->get_text_body_from_email($email[1]), qr/report's reference number/; +}; + +$cobrand = FixMyStreet::Cobrand::Buckinghamshire->new(); + +subtest 'Flytipping extra question used if necessary' => sub { + my $errors = { 'road-placement' => 'This field is required' }; + + $report->update({ bodies_str => $body->id }); + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $errors->{'road-placement'}, 'This field is required', 'Error stays if sent to county'; + + $report->update({ bodies_str => $district->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $errors->{'road-placement'}, undef, 'Error removed if sent to district'; + + $report->update({ bodies_str => $body->id . ',' . $district->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'road', $errors); + is $report->bodies_str, $body->id, 'Sent to both becomes sent to county on-road'; + + $report->update({ bodies_str => $district->id . ',' . $body->id }); + $report->discard_changes; # As e.g. ->bodies has been remembered. + $cobrand->flytipping_body_fix($report, 'off-road', $errors); + is $report->bodies_str, $district->id, 'Sent to both becomes sent to district off-road'; +}; + +for my $test ( + { + desc => 'filters basic emails', + in => 'email: test@example.com', + out => 'email: ', + }, + { + desc => 'filters emails in brackets', + in => 'email: <test@example.com>', + out => 'email: <>', + }, + { + desc => 'filters emails from hosts', + in => 'email: test@mail.example.com', + out => 'email: ', + }, + { + desc => 'filters multiple emails', + in => 'email: test@example.com and user@fixmystreet.com', + out => 'email: and ', + }, + { + desc => 'filters basic phone numbers', + in => 'number: 07700 900000', + out => 'number: ', + }, + { + desc => 'filters multiple phone numbers', + in => 'number: 07700 900000 and 07700 900001', + out => 'number: and ', + }, + { + desc => 'filters 3 part phone numbers', + in => 'number: 0114 496 0999', + out => 'number: ', + }, + { + desc => 'filters international phone numbers', + in => 'number: +44 114 496 0999', + out => 'number: ', + }, + { + desc => 'filters 020 phone numbers', + in => 'number: 020 7946 0999', + out => 'number: ', + }, + { + desc => 'filters no area phone numbers', + in => 'number: 01632 01632', + out => 'number: ', + }, + { + desc => 'does not filter normal numbers', + in => 'number: 16320163236', + out => 'number: 16320163236', + }, + { + desc => 'does not filter short numbers', + in => 'number: 0163 1632', + out => 'number: 0163 1632', + }, +) { + subtest $test->{desc} => sub { + is $cobrand->filter_report_description($test->{in}), $test->{out}, "filtered correctly"; + }; +} + +subtest 'extra CSV columns are present' => sub { + $mech->log_in_ok( $counciluser->email ); + + $mech->get_ok('/dashboard?export=1'); + + my @rows = $mech->content_as_csv; + is scalar @rows, 5, '1 (header) + 4 (reports) = 5 lines'; + is scalar @{$rows[0]}, 21, '21 columns present'; + + is_deeply $rows[0], + [ + 'Report ID', 'Title', 'Detail', 'User Name', 'Category', + 'Created', 'Confirmed', 'Acknowledged', 'Fixed', 'Closed', + 'Status', 'Latitude', 'Longitude', 'Query', 'Ward', + 'Easting', 'Northing', 'Report URL', 'Site Used', + 'Reported As', 'Staff User', + ], + 'Column headers look correct'; + + is $rows[1]->[20], '', 'Staff User is empty if not made on behalf of another user'; + is $rows[2]->[20], $counciluser->email, 'Staff User is correct if made on behalf of another user'; + is $rows[3]->[20], '', 'Staff User is empty if not made on behalf of another user'; + + $mech->create_comment_for_problem($report, $counciluser, 'Staff User', 'Some update text', 'f', 'confirmed', undef, { + extra => { contributed_as => 'body' }}); + $mech->create_comment_for_problem($report, $counciluser, 'Other User', 'Some update text', 'f', 'confirmed', undef, { + extra => { contributed_as => 'another_user', contributed_by => $counciluser->id }}); + + $mech->get_ok('/dashboard?export=1&updates=1'); + + @rows = $mech->content_as_csv; + is scalar @rows, 3, '1 (header) + 2 (updates)'; + is scalar @{$rows[0]}, 9, '9 columns present'; + is_deeply $rows[0], + [ + 'Report ID', 'Update ID', 'Date', 'Status', 'Problem state', + 'Text', 'User Name', 'Reported As', 'Staff User', + ], + 'Column headers look correct'; + + is $rows[1]->[8], '', 'Staff User is empty if not made on behalf of another user'; + is $rows[2]->[8], $counciluser->email, 'Staff User is correct if made on behalf of another user'; +}; + +}; + +done_testing(); diff --git a/t/cobrand/fiksgatami.t b/t/cobrand/fiksgatami.t new file mode 100644 index 000000000..6510f5ebe --- /dev/null +++ b/t/cobrand/fiksgatami.t @@ -0,0 +1,30 @@ +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +my $oslo = $mech->create_body_ok(3, 'Oslo'); +my $vestfold = $mech->create_body_ok(7, 'Vestfold'); +my $larvik = $mech->create_body_ok(709, 'Larvik'); + +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'fiksgatami', + MAPIT_URL => 'http://mapit.uk/', + GEOCODER => '', +}, sub { + $mech->get_ok('/alert/list?pc=0045'); + $mech->content_contains('rss/l/59.9,10.9/2'); + $mech->content_contains('/rss/reports/Oslo'); + $mech->content_contains('council:' . $oslo->id . ':Oslo'); + + $mech->get_ok('/alert/list?pc=3290'); + $mech->content_contains('rss/l/59,10/5'); + $mech->content_contains('/rss/area/Larvik'); + $mech->content_contains('/rss/area/Vestfold'); + $mech->content_contains('/rss/reports/Larvik'); + $mech->content_contains('/rss/reports/Vestfold'); + $mech->content_contains('area:7:Vestfold'); + $mech->content_contains('area:709:Larvik'); + $mech->content_contains('council:' . $vestfold->id . ':Vestfold'); + $mech->content_contains('council:' . $larvik->id . ':Larvik'); +}; + +done_testing(); diff --git a/t/cobrand/fixamingata.t b/t/cobrand/fixamingata.t index 0aa264660..9644e0f44 100644 --- a/t/cobrand/fixamingata.t +++ b/t/cobrand/fixamingata.t @@ -5,7 +5,6 @@ use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; use t::Mock::Nominatim; -LWP::Protocol::PSGI->register(t::Mock::Nominatim->to_psgi_app, host => 'nominatim.openstreetmap.org'); # Front page test @@ -107,6 +106,18 @@ subtest "Test ajax decimal points" => sub { }; }; +subtest "check user details always shown" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'fixamingata' ], + }, sub { + $user2->update({ from_body => $body }); + $mech->get_ok('/report/' . $report->id); + my $update_meta = $mech->extract_update_metas; + like $update_meta->[0], qr/Body \(Commenter\) /; + $user2->update({ from_body => undef }); + }; +}; + END { ok $mech->host("www.fixmystreet.com"), "change host back"; done_testing(); diff --git a/t/cobrand/fixmystreet.t b/t/cobrand/fixmystreet.t index 57ab51198..b47269db4 100644 --- a/t/cobrand/fixmystreet.t +++ b/t/cobrand/fixmystreet.t @@ -59,12 +59,7 @@ FixMyStreet::override_config { }); $mech->get_ok('/reports/Birmingham/summary?csv=1'); - open my $data_handle, '<', \$mech->content; - my $csv = Text::CSV->new( { binary => 1 } ); - my @rows; - while ( my $row = $csv->getline( $data_handle ) ) { - push @rows, $row; - } + my @rows = $mech->content_as_csv; is scalar @rows, 101, '1 (header) + 100 (reports) = 101 lines'; is scalar @{$rows[0]}, 10, '10 columns present'; diff --git a/t/cobrand/greenwich.t b/t/cobrand/greenwich.t new file mode 100644 index 000000000..e6aaca973 --- /dev/null +++ b/t/cobrand/greenwich.t @@ -0,0 +1,114 @@ +use CGI::Simple; +use FixMyStreet::TestMech; +use FixMyStreet::Script::Reports; +use Open311::PopulateServiceList; + +my $mech = FixMyStreet::TestMech->new; + +my $body = $mech->create_body_ok( 2493, 'Greenwich Council', { + send_method => 'Open311', + endpoint => 'endpoint', + api_key => 'key', + jurisdiction => 'greenwich', +}); + +my $contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Pothole', + email => 'HOLE', +); + +my $user = $mech->create_user_ok( 'greenwich@example.com' ); +my @reports = $mech->create_problems_for_body( 1, $body->id, 'Test', { + category => 'Pothole', + cobrand => 'greenwich', + user => $user, +}); +my $report = $reports[0]; + +subtest 'check services override' => sub { + my $processor = Open311::PopulateServiceList->new(); + + my $meta_xml = '<?xml version="1.0" encoding="utf-8"?> +<service_definition> + <service_code>HOLE</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>easting</code> + <datatype>string</datatype> + <required>true</required> + <order>1</order> + <description>Easting</description> + </attribute> + <attribute> + <variable>true</variable> + <code>size</code> + <datatype>string</datatype> + <required>true</required> + <order>2</order> + <description>How big is the pothole</description> + </attribute> + </attributes> +</service_definition> + '; + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/HOLE.xml' => $meta_xml } + ); + + $processor->_current_open311( $o ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'greenwich' ], + }, sub { + $processor->_current_body( $body ); + }; + $processor->_current_service( { service_code => 'HOLE' } ); + $processor->_add_meta_to_contact( $contact ); + + my $extra = [ { + automated => 'server_set', + variable => 'true', + code => 'easting', + datatype => 'string', + required => 'true', + order => 1, + description => 'Easting', + }, { + variable => 'true', + code => 'size', + datatype => 'string', + required => 'true', + order => 2, + description => 'How big is the pothole', + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'Easting has automated set'; +}; + +subtest 'testing special Open311 behaviour', sub { + my $test_data; + FixMyStreet::override_config { + STAGING_FLAGS => { send_reports => 1 }, + ALLOWED_COBRANDS => [ 'greenwich' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $test_data = FixMyStreet::Script::Reports::send(); + }; + $report->discard_changes; + ok $report->whensent, 'Report marked as sent'; + is $report->send_method_used, 'Open311', 'Report sent via Open311'; + is $report->external_id, 248, 'Report has right external ID'; + + my $req = $test_data->{test_req_used}; + my $c = CGI::Simple->new($req->content); + is $c->param('attribute[external_id]'), $report->id, 'Request had correct ID'; + is $c->param('attribute[easting]'), 529025, 'Request had correct easting'; +}; + +done_testing(); + diff --git a/t/cobrand/national_assets.t b/t/cobrand/national_assets.t new file mode 100644 index 000000000..378425193 --- /dev/null +++ b/t/cobrand/national_assets.t @@ -0,0 +1,30 @@ +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +# Create test data +my $body = $mech->create_body_ok( 2561, 'Bristol County Council' ); + + +subtest 'cobrand assets includes cobrand assets javascript', sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'fixmystreet' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $mech->get_ok("/report/new?latitude=51.494885&longitude=-2.602237"); + $mech->content_contains('buckinghamshire/assets.js'); + }; +}; + +subtest 'cobrand assets includes not applied on cobrand sites', sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'bathnes' ], + MAPIT_URL => 'http://mapit.uk/', + MAP_TYPE => 'FMS,OSM,BathNES,Buckinghamshire', + }, sub { + $mech->get_ok("/report/new?latitude=51.494885&longitude=-2.602237"); + $mech->content_lacks('buckinghamshire/assets.js'); + $mech->content_contains('bathnes/assets.js'); + }; +}; + +done_testing(); diff --git a/t/cobrand/oxfordshire.t b/t/cobrand/oxfordshire.t index 19a82742a..2625aa0d5 100644 --- a/t/cobrand/oxfordshire.t +++ b/t/cobrand/oxfordshire.t @@ -186,6 +186,21 @@ subtest 'Reports are marked as inspected correctly' => sub { }; }; +subtest 'can use customer reference to search for reports' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + my $problem = $problems[0]; + $problem->set_extra_metadata( customer_reference => 'ENQ12456' ); + $problem->update; + + $mech->log_out_ok; + $mech->get_ok('/around?pc=ENQ12456'); + is $mech->uri->path, '/report/' . $problem->id, 'redirects to report'; + }; +}; + END { done_testing(); } diff --git a/t/cobrand/restriction.t b/t/cobrand/restriction.t index 9e3018625..63fe326b1 100644 --- a/t/cobrand/restriction.t +++ b/t/cobrand/restriction.t @@ -47,7 +47,7 @@ is($c->model('DB::Problem')->count, 4, 'Four reports in database'); is($cobrand->problems->count, 2, 'Two reports in the right cobrand'); is($cobrand->updates->count, 1, 'One update in the right cobrand'); -my $nearby = $c->model('DB::Nearby')->nearby($c, 5, [], 10, 0.003, 0.004); +my $nearby = $c->model('DB::Nearby')->nearby($c, distance => 5, ids => [], limit => 10, latitude => 0.003, longitude => 0.004); is(@$nearby, 1, 'One report close to the origin point'); done_testing(); diff --git a/t/cobrand/warwickshire.t b/t/cobrand/warwickshire.t new file mode 100644 index 000000000..79c9f31e0 --- /dev/null +++ b/t/cobrand/warwickshire.t @@ -0,0 +1,84 @@ +#!/usr/bin/env perl + +use FixMyStreet::Test; +use FixMyStreet::DB; + +use_ok( 'Open311::PopulateServiceList' ); +use_ok( 'Open311' ); + +my $processor = Open311::PopulateServiceList->new(); +ok $processor, 'created object'; + +my $warks = FixMyStreet::DB->resultset('Body')->create({ + name => 'Warwickshire County Council', +}); +$warks->body_areas->create({ area_id => 2243 }); + +subtest 'check Warwickshire override' => sub { + my $processor = Open311::PopulateServiceList->new(); + + my $meta_xml = '<?xml version="1.0" encoding="utf-8"?> +<service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>closest_address</code> + <datatype>string</datatype> + <required>true</required> + <order>1</order> + <description>Closest address</description> + </attribute> + <attribute> + <variable>true</variable> + <code>size</code> + <datatype>string</datatype> + <required>true</required> + <order>2</order> + <description>How big is the pothole</description> + </attribute> + </attributes> +</service_definition> + '; + + my $contact = FixMyStreet::DB->resultset('Contact')->create({ + body_id => $warks->id, + email => '100', + category => 'Pothole', + state => 'confirmed', + editor => $0, + whenedited => \'current_timestamp', + note => 'test contact', + }); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + $processor->_current_open311( $o ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'warwickshire' ], + }, sub { + $processor->_current_body( $warks ); + }; + $processor->_current_service( { service_code => 100, service_name => 'Pothole' } ); + $processor->_add_meta_to_contact( $contact ); + + my $extra = [ { + variable => 'true', + code => 'size', + datatype => 'string', + required => 'true', + order => 2, + description => 'How big is the pothole', + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'No closest_address field returned for Warks'; + is $contact->get_extra_metadata('id_field'), 'external_id', 'id_field set correctly'; +}; + +done_testing(); diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t index eccb0c8eb..ee2724a07 100644 --- a/t/cobrand/zurich.t +++ b/t/cobrand/zurich.t @@ -196,7 +196,12 @@ subtest "Banners are displayed correctly" => sub { $banner->{text} =~ s/ $//g; } - is $banner->{id}, $test->{banner_id}, 'banner id'; + if ( $test->{banner_id} ) { + ok $banner->{class} =~ /banner--$test->{banner_id}/i, 'banner class'; + } else { + is $banner->{class}, $test->{banner_id}, 'banner class'; + } + if ($test->{banner_text}) { like_string( $banner->{text}, qr/$test->{banner_text}/i, 'banner text is ' . $test->{banner_text} ); } else { @@ -416,7 +421,10 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], MAPIT_URL => 'http://mapit.zurich/', MAP_TYPE => 'Zurich,OSM', - UPLOAD_DIR => $UPLOAD_DIR, + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { # Photo publishing $mech->get_ok( '/admin/report_edit/' . $report->id ); @@ -830,6 +838,7 @@ subtest "only superuser can see 'Add body' form" => sub { }, sub { $mech->get_ok( '/admin/bodies' ); }; + $mech->content_contains('External Body'); $mech->content_lacks( '<form method="post" action="bodies"' ); $mech->log_out_ok; }; @@ -956,7 +965,6 @@ subtest "test stats" => sub { }; subtest "test admin_log" => sub { - diag $report->id; my @entries = FixMyStreet::DB->resultset('AdminLog')->search({ object_type => 'problem', object_id => $report->id, @@ -1084,7 +1092,7 @@ FixMyStreet::override_config { }, sub { subtest 'users at the top level can be edited' => sub { $mech->log_in_ok( $superuser->email ); - $mech->get_ok('/admin/user_edit/' . $superuser->id ); + $mech->get_ok('/admin/users/' . $superuser->id ); }; }; @@ -1,5 +1,6 @@ use strict; use warnings; +use utf8; use Test::More; diff --git a/t/map/google.t b/t/map/google.t new file mode 100644 index 000000000..e2877f53c --- /dev/null +++ b/t/map/google.t @@ -0,0 +1,21 @@ +use FixMyStreet::Map::Google; +use FixMyStreet::Test; + +use Catalyst::Test 'FixMyStreet::App'; + +my $c = ctx_request('/'); + +FixMyStreet::Map::Google->display_map($c, any_zoom => 1); + +is_deeply $c->stash->{map}, { + any_zoom => 1, + zoomToBounds => 1, + type => 'google', + zoom => 15, + zoomOffset => 0, + numZoomLevels => 19, + zoom_act => 15, +}; + +done_testing(); + diff --git a/t/map/tests.t b/t/map/tests.t index e6749b813..728aa5125 100644 --- a/t/map/tests.t +++ b/t/map/tests.t @@ -2,12 +2,12 @@ use FixMyStreet::Map; use Test::More; my $requires = { - 'Angus' => 'angus/js.js', - 'BathNES' => 'bathnes/js.js', + 'BathNES' => 'bathnes/assets.js', 'Bing' => 'map-bing-ol.js', - 'Bristol' => 'bristol/js.js', - 'Bromley' => 'bromley/map.js', - 'Buckinghamshire' => 'buckinghamshire/js.js', + 'Bristol' => 'bristol/assets.js', + 'Bromley' => 'bromley/assets.js', + 'Buckinghamshire' => 'buckinghamshire/assets.js', + 'Lincolnshire' => 'lincolnshire/assets.js', 'FMS' => 'map-fms.js', 'Google' => 'map-google.js', 'GoogleOL' => 'map-google-ol.js', diff --git a/t/map/tilma/original.t b/t/map/tilma/original.t index e89251285..9a404a2c9 100644 --- a/t/map/tilma/original.t +++ b/t/map/tilma/original.t @@ -91,13 +91,12 @@ for my $test ( subtest "pin colour for state $test->{state}" => sub { $report->state($test->{state}); $report->update; + $c->stash->{report_age_field} = 'lastupdate'; - my ( $on_map, $nearby, $dist ) = - FixMyStreet::Map::map_features($c, bbox => "0,0,0,0"); + my ($on_map, $nearby) = FixMyStreet::Map::map_features($c, bbox => "0,0,0,0"); ok $on_map; ok $nearby; - ok $dist; my $id = $report->id; my $colour = $test->{colour}; diff --git a/t/open311.t b/t/open311.t index 4dc1b2959..85176ff0d 100644 --- a/t/open311.t +++ b/t/open311.t @@ -70,6 +70,8 @@ my $problem = FixMyStreet::DB->resultset('Problem')->new( { cobrand => 'fixmystreet', } ); +my $bromley = FixMyStreet::DB->resultset('Body')->new({ name => 'Bromley' }); + subtest 'posting service request' => sub { my $extra = { url => 'http://example.com/report/1', @@ -261,19 +263,39 @@ for my $test ( }; } +subtest 'test always_send_email' => sub { + my $email = $user->email; + $user->email(undef); + my $extra = { url => 'http://example.com/report/1', }; -my $comment = FixMyStreet::DB->resultset('Comment')->new( { - id => 38362, - user => $user, - problem => $problem, - anonymous => 0, - text => 'this is a comment', - confirmed => $dt, - problem_state => 'confirmed', - extra => { title => 'Mr', email_alerts_requested => 0 }, -} ); + my $results = make_service_req( + $problem, $extra, $problem->category, + '<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>', + { always_send_email => 1 } + ); + my $c = CGI::Simple->new( $results->{req}->content ); + + is $c->param('email'), 'do-not-reply@example.org', 'correct email'; + $user->email($email); +}; + +sub make_comment { + my $cobrand = shift; + FixMyStreet::DB->resultset('Comment')->new( { + id => 38362, + user => $user, + problem => $problem, + anonymous => 0, + text => 'this is a comment', + confirmed => $dt, + problem_state => 'confirmed', + cobrand => $cobrand || 'default', + extra => { title => 'Mr', email_alerts_requested => 0 }, + } ); +} subtest 'basic request update post parameters' => sub { + my $comment = make_comment(); my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); is $results->{ res }, 248, 'got update id'; @@ -292,7 +314,13 @@ subtest 'basic request update post parameters' => sub { }; subtest 'extended request update post parameters' => sub { - my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { use_extended_updates => 1 } ); + my $comment = make_comment('bromley'); + my $results; + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + }, sub { + $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + }; is $results->{ res }, 248, 'got update id'; @@ -318,11 +346,14 @@ subtest 'check media url set' => sub { my $image_path = path('t/app/controller/sample.jpg'); $image_path->copy( path( $UPLOAD_DIR, '0123456789012345678901234567890123456789.jpeg' ) ); + my $comment = make_comment('fixmystreet'); $comment->photo("0123456789012345678901234567890123456789"); - $comment->cobrand('fixmystreet'); FixMyStreet::override_config { - UPLOAD_DIR => $UPLOAD_DIR, + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); @@ -332,7 +363,6 @@ subtest 'check media url set' => sub { my $expected_path = '/c/' . $comment->id . '.0.full.jpeg'; like $c->param('media_url'), qr/$expected_path/, 'image url included'; }; - $comment->photo(undef); }; foreach my $test ( @@ -412,10 +442,27 @@ foreach my $test ( status => 'OPEN', extended => 'IN_PROGRESS', }, + { + desc => 'comment that marks problem open sends OPEN if not mark_reopen', + state => 'confirmed', + status => 'OPEN', + extended => 'OPEN', + mark_open => 1, + }, + { + desc => 'comment that marks problem open sends REOPEN if mark_reopen', + state => 'confirmed', + status => 'OPEN', + extended => 'REOPEN', + mark_open => 1, + mark_reopen => 1, + }, ) { subtest $test->{desc} => sub { + my $comment = make_comment(); $comment->problem_state( $test->{state} ); $comment->problem->state( $test->{state} ); + $comment->mark_open(1) if $test->{mark_open}; my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); @@ -423,7 +470,9 @@ foreach my $test ( is $c->param('status'), $test->{status}, 'correct status'; if ( $test->{extended} ) { - my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_statuses => 1 } ); + my $params = { extended_statuses => 1 }; + $params->{mark_reopen} = 1 if $test->{mark_reopen}; + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', $params ); my $c = CGI::Simple->new( $results->{ req }->content ); is $c->param('status'), $test->{extended}, 'correct extended status'; } @@ -445,11 +494,17 @@ for my $test ( }, ) { subtest $test->{desc} => sub { + my $comment = make_comment('bromley'); $comment->problem_state( $test->{state} ); $comment->problem->state( $test->{state} ); $comment->anonymous( $test->{anon} ); - my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { use_extended_updates => 1 } ); + my $results; + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'bromley', + }, sub { + $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + }; my $c = CGI::Simple->new( $results->{ req }->content ); is $c->param('public_anonymity_required'), $test->{anon} ? 'TRUE' : 'FALSE', 'correct anonymity'; @@ -459,17 +514,6 @@ for my $test ( my $dt2 = $dt->clone; $dt2->add( 'minutes' => 1 ); -my $comment2 = FixMyStreet::DB->resultset('Comment')->new( { - id => 38363, - user => $user, - problem => $problem, - anonymous => 0, - text => 'this is a comment', - confirmed => $dt, - problem_state => 'confirmed', - extra => { title => 'Mr', email_alerts_requested => 0 }, -} ); - for my $test ( { desc => 'comment with fixed - council state sends status of CLOSED even if problem is open', @@ -494,6 +538,7 @@ for my $test ( }, ) { subtest $test->{desc} => sub { + my $comment = make_comment(); $comment->problem_state( $test->{state} ); $comment->problem->state( $test->{problem_state} ); my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); @@ -538,6 +583,7 @@ for my $test ( ) { subtest $test->{desc} => sub { + my $comment = make_comment(); $comment->name( $test->{comment_name} ); $user->name( $test->{user_name} ); $comment->extra( $test->{ extra } ); @@ -626,6 +672,7 @@ for my $test ( } $problem->send_fail_count(1); +my $comment = make_comment(); $comment->send_fail_count(1); subtest 'No request id in reponse' => sub { @@ -791,6 +838,7 @@ sub _make_req { $open311_conf{'test_mode'} = 1; $open311_conf{'end_point'} = 'http://localhost/o311'; + $open311_conf{fixmystreet_body} = $bromley; my $o = Open311->new( %open311_conf ); diff --git a/t/open311/getservicerequests.t b/t/open311/getservicerequests.t index 57f112e2f..55bb9ba11 100644 --- a/t/open311/getservicerequests.t +++ b/t/open311/getservicerequests.t @@ -14,6 +14,9 @@ my $user = $mech->create_user_ok('system_user@example.com', name => 'test users' my $body = $mech->create_body_ok(2482, 'Bromley'); my $contact = $mech->create_contact_ok( body_id => $body->id, category => 'Sidewalk and Curb Issues', email => 'sidewalks' ); +my $body2 = $mech->create_body_ok(2217, 'Buckinghamshire'); +my $contact2 = $mech->create_contact_ok( body_id => $body2->id, category => 'Sidewalk and Curb Issues', email => 'sidewalks' ); + my $dtf = DateTime::Format::W3CDTF->new; my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> @@ -48,6 +51,20 @@ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> <lat>51.4021</lat> <long>0.01578</long> </request> +<request> +<service_request_id>638346</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>sidewalks</service_code> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>2010-04-14T06:37:38-08:00</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>51.4021</lat> +<long>0.01578</long> +</request> </service_requests> }; @@ -59,13 +76,9 @@ my $o = Open311->new( ); my $p1_date = $dtf->parse_datetime('2010-04-14T06:37:38-08:00') - ->set_time_zone( - FixMyStreet->time_zone || FixMyStreet->local_time_zone - ); + ->set_time_zone(FixMyStreet->local_time_zone); my $p2_date = $dtf->parse_datetime('2010-04-15T06:37:38-08:00') - ->set_time_zone( - FixMyStreet->time_zone || FixMyStreet->local_time_zone - ); + ->set_time_zone(FixMyStreet->local_time_zone); my $start_date = $p1_date->clone; $start_date->add( hours => -2); my $end_date = $p2_date->clone; @@ -79,6 +92,7 @@ subtest 'basic parsing checks' => sub { end_date => $end_date ); FixMyStreet::override_config { + TIME_ZONE => 'Asia/Tokyo', MAPIT_URL => 'http://mapit.uk/', }, sub { $update->create_problems( $o, $body ); @@ -104,6 +118,13 @@ subtest 'basic parsing checks' => sub { ok $p2->whensent, 'second problem marked sent'; is $p2->state, 'investigating', 'second problem correct state'; is $p2->category, 'Other', 'category falls back to Other'; + + my $p3 = FixMyStreet::DB->resultset('Problem')->search( { external_id => 638346 } )->first; + ok $p3, 'third problem found'; + ok $p3->whensent, 'third problem marked sent'; + is $p3->state, 'confirmed', 'second problem correct state'; + is $p3->category, 'Sidewalk and Curb Issues', 'correct problem category'; + is $p3->detail, 'Sidewalk and Curb Issues problem', 'problem detail based on category name'; }; subtest 'check problems not re-created' => sub { @@ -384,6 +405,118 @@ subtest "check options passed through from body" => sub { ok $props->{convert_latlong}, "convert latlong set" }; +my $non_public_xml = qq[<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>123456</service_request_id> +<status>open</status> +<status_notes></status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>sidewalks</service_code> +<description>this is a problem</description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>2010-04-14T06:37:38-08:00</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>51.4021</lat> +<long>0.01578</long> +<non_public>1</non_public> +</request> +</service_requests> +]; + +for my $test ( + { + desc => 'non public is set', + non_public => 1, + }, + { + desc => 'non public is not set', + non_public => 0, + }, +) { + subtest $test->{desc} => sub { + (my $xml = $non_public_xml) =~ s/non_public>1/non_public>$test->{non_public}/; + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $update = Open311::GetServiceRequests->new( + system_user => $user, + start_date => $start_date, + end_date => $end_date + ); + + FixMyStreet::override_config { + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body ); + }; + + my $p = FixMyStreet::DB->resultset('Problem')->search( + { external_id => 123456 } + )->first; + + ok $p, 'problem created'; + is $p->non_public, $test->{non_public}, "report non_public is set correctly"; + + $p->delete; + }; +} + +for my $test ( + { + test_desc => 'filters out phone numbers', + desc => 'This has a description with values:0117 469 0123 and more 07700 900123', + }, + { + test_desc => 'filters out emails', + desc => 'This has a description with values:test@example.org and more user@council.gov.uk', + }, +) { + subtest $test->{test_desc} => sub { + my $xml = prepare_xml({ + desc => $test->{desc}, + lat => 51.615559, + long => -0.556903, + }); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'requests.xml' => $xml} + ); + + my $update = Open311::GetServiceRequests->new( + system_user => $user, + start_date => $start_date, + end_date => $end_date + ); + + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'FixMyStreet', 'Buckinghamshire' ], + MAPIT_URL => 'http://mapit.uk/', + }, sub { + $update->create_problems( $o, $body2 ); + }; + + my $p = FixMyStreet::DB->resultset('Problem')->search( + { external_id => 123456 } + )->first; + + ok $p, 'problem created'; + is $p->detail, 'This has a description with values: and more ', "report description filtered"; + + $p->delete; + }; +} + sub prepare_xml { my $replacements = shift; diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index 3c279d776..f680985a4 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -4,6 +4,7 @@ use FixMyStreet::Test; use Test::Output; use CGI::Simple; use LWP::Protocol::PSGI; +use Test::Warn; use t::Mock::Static; use_ok( 'Open311' ); @@ -21,8 +22,15 @@ my $user = FixMyStreet::DB->resultset('User')->find_or_create( my %bodies = ( 2237 => FixMyStreet::DB->resultset("Body")->create({ name => 'Oxfordshire' }), - 2482 => FixMyStreet::DB->resultset("Body")->create({ name=> 'Bromley', id => 2482 }), - 2651 => FixMyStreet::DB->resultset("Body")->new({ id => 2651 }), + 2482 => FixMyStreet::DB->resultset("Body")->create({ + name => 'Bromley', + send_method => 'Open311', + send_comments => 1, + endpoint => 'endpoint', + comment_user_id => $user->id, + blank_updates_permitted => 1, + }), + 2651 => FixMyStreet::DB->resultset("Body")->create({ name => 'Edinburgh' }), ); $bodies{2237}->body_areas->create({ area_id => 2237 }); @@ -32,6 +40,12 @@ my $response_template = $bodies{2482}->response_templates->create({ auto_response => 1, state => "investigating" }); +my $response_template_fixed = $bodies{2482}->response_templates->create({ + title => "fixed template", + text => "We have fixed this report.", + auto_response => 1, + state => "fixed - council" +}); my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> <service_requests_updates> @@ -46,7 +60,7 @@ UPDATED_DATETIME }; -my $dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new); +my $dt = DateTime->now(formatter => DateTime::Format::W3CDTF->new)->add( minutes => -5 ); # basic xml -> perl object tests for my $test ( @@ -134,8 +148,8 @@ my $problem = $problem_rs->new( created => DateTime->now()->subtract( days => 1 ), lastupdate => DateTime->now()->subtract( days => 1 ), anonymous => 1, - external_id => time(), - bodies_str => 2482, + external_id => int(rand(time())), + bodies_str => $bodies{2482}->id, } ); @@ -258,6 +272,18 @@ for my $test ( end_state => 'fixed - council', }, { + desc => 'status of CLOSED marks report as closed when using extended statuses', + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'CLOSED', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'closed', + end_state => 'closed', + extended_statuses => 1, + }, + { desc => 'status of OPEN re-opens fixed report', description => 'This is a note', external_id => 638344, @@ -358,6 +384,19 @@ for my $test ( end_state => 'investigating', }, { + desc => 'change in fixed state does not trigger auto-response template', + description => '', + xml_description => '', + external_id => 638344, + start_state => 'fixed - user', + comment_status => 'FIXED', + mark_fixed => 0, + mark_open => 0, + problem_state => undef, + end_state => 'fixed - user', + comment_state => 'hidden', + }, + { desc => 'unchanging state does not trigger auto-response template', description => '', xml_description => '', @@ -384,14 +423,14 @@ for my $test ( ) { subtest $test->{desc} => sub { my $local_requests_xml = setup_xml($problem->external_id, $problem->id, $test->{comment_status}, $test->{xml_description}); - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', extended_statuses => $test->{extended_statuses}, test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); $problem->state( $test->{start_state} ); $problem->update; - my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{2482} ); + my $update = Open311::GetServiceRequestUpdates->new; + $update->fetch($o); is $problem->comments->count, 1, 'comment count'; $problem->discard_changes; @@ -426,7 +465,7 @@ my $problemOx = $problem_rs->create({ created => DateTime->now()->subtract( days => 1 ), lastupdate => DateTime->now()->subtract( days => 1 ), anonymous => 1, - external_id => time(), + external_id => int(rand(time())), bodies_str => $bodies{2237}->id, }); @@ -490,12 +529,39 @@ subtest 'Update with media_url includes image in update' => sub { $problem->comments->delete; }; +subtest 'Update with customer_reference adds reference to problem' => sub { + my $guard = LWP::Protocol::PSGI->register(t::Mock::Static->to_psgi_app, host => 'example.com'); + + my $local_requests_xml = setup_xml($problem->external_id, 1, ""); + $local_requests_xml =~ s#</service_request_id>#</service_request_id> + <customer_reference>REFERENCE</customer_reference>#; + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); + + $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problem->state('confirmed'); + $problem->update; + + my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); + $update->update_comments( $o, $bodies{2482} ); + + $problem->discard_changes; + is $problem->comments->count, 1, 'comment count'; + my $c = $problem->comments->first; + is $c->external_id, 638344; + is $problem->get_extra_metadata('customer_reference'), 'REFERENCE'; + $problem->comments->delete; +}; + subtest 'date for comment correct' => sub { my $local_requests_xml = setup_xml($problem->external_id, $problem->id, ""); my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $bodies{2482} ); + FixMyStreet::override_config { + TIME_ZONE => 'Australia/Sydney', + }, sub { + $update->update_comments( $o, $bodies{2482} ); + }; my $comment = $problem->comments->first; is $comment->created, $dt, 'created date set to date from XML'; @@ -523,7 +589,7 @@ my $problem2 = $problem_rs->create( lastupdate => DateTime->now(), anonymous => 1, external_id => $problem->external_id, - bodies_str => 2651, + bodies_str => $bodies{2651}->id, } ); @@ -664,6 +730,48 @@ subtest 'check that existing comments are not duplicated' => sub { is $problem->comments->count, 2, 'if comments are deleted then they are added'; }; +subtest 'check that can limit fetching to a body' => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <status>open</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + + is $problem->comments->count, 0, 'one comment before fetching updates'; + + $requests_xml =~ s/UPDATED_DATETIME/$dt/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + body => 'Oxfordshire', + system_user => $user, + ); + + $update->fetch( $o ); + + $problem->discard_changes; + is $problem->comments->count, 0, 'no comments after fetching updates'; + + $update = Open311::GetServiceRequestUpdates->new( + body => 'Bromley', + system_user => $user, + ); + + $update->fetch( $o ); + + $problem->discard_changes; + is $problem->comments->count, 1, '1 comment after fetching updates'; +}; + subtest 'check that external_status_code is stored correctly' => sub { my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> <service_requests_updates> @@ -886,6 +994,7 @@ foreach my $test ( { } } +$response_template_fixed->delete; foreach my $test ( { desc => 'normally blank text produces a warning', num_alerts => 1, @@ -933,6 +1042,94 @@ foreach my $test ( { } } +subtest 'check matching on fixmystreet_id overrides service_request_id' => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>8888888888888</service_request_id> + <fixmystreet_id>@{[ $problem->id ]}</fixmystreet_id> + <status>open</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + <request_update> + <update_id>638354</update_id> + <service_request_id>@{[ $problem->external_id ]}</service_request_id> + <fixmystreet_id>999999999</fixmystreet_id> + <status>open</status> + <description>This is a different note</description> + <updated_datetime>UPDATED_DATETIME2</updated_datetime> + </request_update> + <request_update> + <update_id>638356</update_id> + <service_request_id></service_request_id> + <fixmystreet_id>@{[ $problem->id ]}</fixmystreet_id> + <status>investigating</status> + <description>This is a last note</description> + <updated_datetime>UPDATED_DATETIME3</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + + my $dt2 = $dt->clone->subtract( minutes => 30 ); + my $dt3 = $dt2->clone->subtract( minutes => 30 ); + $requests_xml =~ s/UPDATED_DATETIME3/$dt/; + $requests_xml =~ s/UPDATED_DATETIME2/$dt2/; + $requests_xml =~ s/UPDATED_DATETIME/$dt3/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + ); + + $update->update_comments( $o, $bodies{2482} ); + + $problem->discard_changes; + is $problem->comments->count, 2, 'two comments after fetching updates'; + + my @comments = $problem->comments->search(undef, { order_by => [ 'created' ] } )->all; + + is $comments[0]->external_id, 638344, "correct first comment added"; + is $comments[1]->external_id, 638356, "correct second comment added"; +}; + +subtest 'check bad fixmystreet_id is handled' => sub { + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id>8888888888888</service_request_id> + <fixmystreet_id>123456 654321</fixmystreet_id> + <status>open</status> + <description>This is a note</description> + <updated_datetime>UPDATED_DATETIME</updated_datetime> + </request_update> + </service_requests_updates> + }; + + $problem->comments->delete; + + $requests_xml =~ s/UPDATED_DATETIME/$dt/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); + + my $update = Open311::GetServiceRequestUpdates->new( + system_user => $user, + ); + + warning_like { + $update->update_comments( $o, $bodies{2482} ) + } + qr/skipping bad fixmystreet id in updates for Bromley: \[123456 654321\], external id is 8888888888888/, + "warning emitted for bad fixmystreet id"; + + $problem->discard_changes; + is $problem->comments->count, 0, 'no comments after fetching updates'; +}; done_testing(); sub setup_xml { diff --git a/t/open311/oxfordshire/open311_services.t b/t/open311/oxfordshire/open311_services.t new file mode 100644 index 000000000..c12ce9f43 --- /dev/null +++ b/t/open311/oxfordshire/open311_services.t @@ -0,0 +1,37 @@ +use FixMyStreet::Test; +use POSIX qw(tzset); + +my $d; + +BEGIN { + use File::Basename qw(dirname); + use File::Spec; + $d = dirname(File::Spec->rel2abs(__FILE__)); +} + +use lib "$d/../../../bin/oxfordshire"; + +use_ok 'open311_services'; + +my $old_tz = $ENV{TZ}; +$ENV{TZ} = 'Europe/London'; +tzset; + +is get_utc_iso8601_string('2018-06-01 13:37:42'), '2018-06-01T12:37:42Z', 'convert local to iso UTC'; + +is get_date_or_nothing('2018-06-01T12:37:42Z'), '2018-06-01 12:37:42', 'convert date format'; +is get_date_or_nothing('2018-06-01T12:37Z'), '2018-06-01 12:37:00', 'convert date format add seconds'; +is get_date_or_nothing('2018-06-01T12:37:42Z', 1), '2018-06-01', 'convert date format and ignore time'; +is get_date_or_nothing('2018/06/01 12:37:42'), '', 'convert date returns nothing if no match'; + +is get_date_or_nothing('2018-06-07T12:35:08+01:00'), '2018-06-07 12:35:08', 'convert date format with TZ'; + +$ENV{TZ} = 'Europe/Rome'; +tzset; + +is get_utc_iso8601_string('2018-06-01 14:37:42'), '2018-06-01T12:37:42Z', 'convert local to iso UTC alt TZ'; + +$ENV{TZ} = $old_tz; +tzset; + +done_testing(); diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index b54b1c242..ff4c4cf9d 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -1,7 +1,25 @@ #!/usr/bin/env perl +package FixMyStreet::Cobrand::Tester; + +use parent 'FixMyStreet::Cobrand::Default'; + +sub council_area_id { 1 } + + +package FixMyStreet::Cobrand::TesterGroups; + +use parent 'FixMyStreet::Cobrand::Default'; + +sub council_area_id { 1 } + +sub enable_category_groups { 1 } + + +package main; use FixMyStreet::Test; use FixMyStreet::DB; +use utf8; use_ok( 'Open311::PopulateServiceList' ); use_ok( 'Open311' ); @@ -10,52 +28,67 @@ use_ok( 'Open311' ); my $processor = Open311::PopulateServiceList->new(); ok $processor, 'created object'; -my $body = FixMyStreet::DB->resultset('Body')->find_or_create( { - id => 1, +my $body = FixMyStreet::DB->resultset('Body')->create({ name => 'Body Numero Uno', } ); -$body->body_areas->find_or_create({ +$body->body_areas->create({ area_id => 1 } ); my $BROMLEY = 'Bromley Council'; -my $bromley = FixMyStreet::DB->resultset('Body')->find_or_create( { - id => 2482, +my $bromley = FixMyStreet::DB->resultset('Body')->create( { name => $BROMLEY, } ); -$bromley->update({ name => $BROMLEY }); -$bromley->body_areas->find_or_create({ +$bromley->body_areas->create({ area_id => 2482 } ); -subtest 'check basic functionality' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); - - my $service_list = get_xml_simple_object( get_standard_xml() ); - - my $processor = Open311::PopulateServiceList->new(); - $processor->_current_body( $body ); - $processor->process_services( $service_list ); +my $bucks = FixMyStreet::DB->resultset('Body')->create({ + name => 'Buckinghamshire County Council', +}); +$bucks->body_areas->create({ + area_id => 2217 +}); - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); - is $contact_count, 3, 'correct number of contacts'; - - for my $test ( - { code => "001", group => "sanitation" }, - { code => "002", group => "street" }, - { code => "003", group => "street" }, - ) { - my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1, email => $test->{code} } )->first; - is $contact->get_extra->{group}, $test->{group}, "Group set correctly"; - } -}; +for my $test ( + { desc => 'groups not set for new contacts', cobrand => 'tester', groups => 0, delete => 1 }, + { desc => 'groups set for new contacts', cobrand => 'testergroups', groups => 1, delete => 1}, + { desc => 'groups removed for existing contacts', cobrand => 'tester', groups => 0, delete => 0 }, + { desc => 'groups added for existing contacts', cobrand => 'testergroups', groups => 1, delete => 0}, +) { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ $test->{cobrand} ], + }, sub { + subtest 'check basic functionality, ' . $test->{desc} => sub { + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete() if $test->{delete}; + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $processor = Open311::PopulateServiceList->new(); + $processor->_current_body( $body ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); + is $contact_count, 3, 'correct number of contacts'; + + for my $expects ( + { code => "001", group => $test->{groups} ? "sanitation" : undef }, + { code => "002", group => $test->{groups} ? "street" : undef }, + { code => "003", group => $test->{groups} ? "street" : undef }, + ) { + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, email => $expects->{code} } )->first; + is $contact->get_extra->{group}, $expects->{group}, "Group set correctly"; + } + }; + }; +} subtest 'check non open311 contacts marked as deleted' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => 'contact@example.com', category => 'An old category', state => 'confirmed', @@ -71,19 +104,19 @@ subtest 'check non open311 contacts marked as deleted' => sub { $processor->_current_body( $body ); $processor->process_services( $service_list ); - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 4, 'correct number of contacts'; - $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1, state => 'deleted' } )->count(); + $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id, state => 'deleted' } )->count(); is $contact_count, 1, 'correct number of deleted contacts'; }; subtest 'check email changed if matching category' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '009', category => 'Cans left out 24x7', state => 'confirmed', @@ -105,16 +138,16 @@ subtest 'check email changed if matching category' => sub { is $contact->email, '001', 'email unchanged'; is $contact->state, 'confirmed', 'contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 3, 'correct number of contacts'; }; subtest 'check category name changed if updated' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -137,16 +170,16 @@ subtest 'check category name changed if updated' => sub { is $contact->category, 'Cans left out 24x7', 'category changed'; is $contact->state, 'confirmed', 'contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 3, 'correct number of contacts'; }; subtest 'check conflicting contacts not changed' => sub { - FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->delete(); + FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->delete(); my $contact = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => 'existing@example.com', category => 'Cans left out 24x7', state => 'confirmed', @@ -160,7 +193,7 @@ subtest 'check conflicting contacts not changed' => sub { my $contact2 = FixMyStreet::DB->resultset('Contact')->create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -188,7 +221,7 @@ subtest 'check conflicting contacts not changed' => sub { is $contact2->category, 'Bins left out 24x7', 'second contact category unchanged'; is $contact2->state, 'confirmed', 'second contact still confirmed'; - my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); + my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => $body->id } )->count(); is $contact_count, 4, 'correct number of contacts'; }; @@ -265,6 +298,47 @@ for my $test ( ', }, { + desc => 'check meta data unchanging', + has_meta => 1, + has_no_history => 1, + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Colour of bin', + order => 1, + description => 'Cólour of bin' + + } ], + end_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Colour of bin', + order => 1, + description => 'Cólour of bin' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Colour of bin</datatype_description> + <order>1</order> + <description>Cólour of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { desc => 'check meta data removed', has_meta => 0, end_meta => [], @@ -332,7 +406,7 @@ for my $test ( my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '100', category => 'Cans left out 24x7', state => 'confirmed', @@ -357,11 +431,21 @@ for my $test ( $processor->_current_open311( $o ); $processor->_current_body( $body ); + my $count = FixMyStreet::DB->resultset('ContactsHistory')->search({ + contact_id => $contact->id, + })->count; + $processor->process_services( $service_list ); $contact->discard_changes; is_deeply $contact->get_extra_fields, $test->{end_meta}, 'meta data saved'; + + if ($test->{has_no_history}) { + is +FixMyStreet::DB->resultset('ContactsHistory')->search({ + contact_id => $contact->id, + })->count, $count, 'No new history'; + } }; } @@ -405,7 +489,7 @@ subtest 'check attribute ordering' => sub { my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -500,13 +584,22 @@ subtest 'check Bromley skip code' => sub { <order>1</order> <description>Type of bin</description> </attribute> + <attribute> + <variable>true</variable> + <code>easting</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>String</datatype_description> + <order>1</order> + <description>Easting</description> + </attribute> </attributes> </service_definition> '; my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create( { - body_id => 1, + body_id => $body->id, email => '001', category => 'Bins left out 24x7', state => 'confirmed', @@ -524,7 +617,11 @@ subtest 'check Bromley skip code' => sub { ); $processor->_current_open311( $o ); - $processor->_current_body( $bromley ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'bromley' ], + }, sub { + $processor->_current_body( $bromley ); + }; $processor->_current_service( { service_code => 100 } ); $processor->_add_meta_to_contact( $contact ); @@ -538,6 +635,15 @@ subtest 'check Bromley skip code' => sub { order => 1, description => 'Type of bin' }, { + automated => 'server_set', + variable => 'true', + code => 'easting', + datatype => 'string', + required => 'true', + datatype_description => 'String', + order => 1, + description => 'Easting', + }, { automated => 'hidden_field', variable => 'true', code => 'prow_reference', @@ -583,7 +689,14 @@ subtest 'check Bromley skip code' => sub { datatype_description => 'Type of bin', order => 1, description => 'Type of bin' - + }, { + variable => 'true', + code => 'easting', + datatype => 'string', + required => 'true', + datatype_description => 'String', + order => 1, + description => 'Easting', }, ]; @@ -592,6 +705,93 @@ subtest 'check Bromley skip code' => sub { is_deeply $contact->get_extra_fields, $extra, 'all meta data saved for non bromley'; }; +subtest 'check Buckinghamshire extra code' => sub { + my $processor = Open311::PopulateServiceList->new(); + + my $meta_xml = '<?xml version="1.0" encoding="utf-8"?> +<service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> +</service_definition> + '; + + my $contact = FixMyStreet::DB->resultset('Contact')->find_or_create({ + body_id => $body->id, + email => '001', + category => 'Flytipping', + state => 'confirmed', + editor => $0, + whenedited => \'current_timestamp', + note => 'test contact', + }); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services/100.xml' => $meta_xml } + ); + + $processor->_current_open311( $o ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'buckinghamshire' ], + }, sub { + $processor->_current_body( $bucks ); + }; + $processor->_current_service( { service_code => 100, service_name => 'Flytipping' } ); + $processor->_add_meta_to_contact( $contact ); + + my $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + }, { + variable => 'true', + code => 'road-placement', + datatype => 'singlevaluelist', + required => 'true', + order => 100, + description => 'Is the fly-tip located on', + values => [ + { key => 'road', name => 'The road' }, + { key => 'off-road', name => 'Off the road/on a verge' }, + ], + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'extra Bucks field returned for flytipping'; + + $processor->_current_service( { service_code => 100, service_name => 'Street lights' } ); + $processor->_add_meta_to_contact( $contact ); + + $extra = [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + } ]; + + $contact->discard_changes; + is_deeply $contact->get_extra_fields, $extra, 'no extra Bucks field returned otherwise'; +}; + sub get_standard_xml { return qq{<?xml version="1.0" encoding="utf-8"?> <services> diff --git a/t/open311/post-service-request-updates.t b/t/open311/post-service-request-updates.t new file mode 100644 index 000000000..57b8f9a2a --- /dev/null +++ b/t/open311/post-service-request-updates.t @@ -0,0 +1,112 @@ +#!/usr/bin/env perl + +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +use_ok( 'Open311::PostServiceRequestUpdates' ); + +my $o = Open311::PostServiceRequestUpdates->new( site => 'fixmystreet.com' ); + +my $params = { + send_method => 'Open311', + send_comments => 1, + api_key => 'KEY', + endpoint => 'endpoint', + jurisdiction => 'home', +}; +my $bromley = $mech->create_body_ok(2482, 'Bromley', { %$params, send_extended_statuses => 1, id => 5 }); +my $oxon = $mech->create_body_ok(2237, 'Oxfordshire', { %$params, id => 55 }); +my $bucks = $mech->create_body_ok(2217, 'Buckinghamshire', $params); +my $lewisham = $mech->create_body_ok(2492, 'Lewisham', $params); + +subtest 'Check Open311 params' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => ['fixmystreet', 'bromley', 'buckinghamshire', 'lewisham', 'oxfordshire'], + }, sub { + my $result = { + endpoint => 'endpoint', + jurisdiction => 'home', + api_key => 'KEY', + extended_statuses => undef, + }; + my %conf = $o->open311_params($bromley); + is_deeply \%conf, { + %$result, + extended_statuses => 1, + endpoints => { service_request_updates => 'update.xml', update => 'update.xml' }, + fixmystreet_body => $bromley, + }, 'Bromley params match'; + %conf = $o->open311_params($oxon); + is_deeply \%conf, { + %$result, + use_customer_reference => 1, + fixmystreet_body => $oxon, + }, 'Oxfordshire params match'; + %conf = $o->open311_params($bucks); + is_deeply \%conf, { + %$result, + mark_reopen => 1, + fixmystreet_body => $bucks, + }, 'Bucks params match'; + %conf = $o->open311_params($lewisham); + is_deeply \%conf, { + %$result, + fixmystreet_body => $lewisham, + }, 'Lewisham params match'; + }; +}; + +my $other_user = $mech->create_user_ok('test2@example.com', title => 'MRS'); + +sub c { + my ($p, $user) = @_; + my $c = $mech->create_comment_for_problem($p, $user || $p->user, 'Name', 'Update text', 'f', 'confirmed', 'confirmed', { confirmed => \'current_timestamp' }); + return $c; +} + +sub p_and_c { + my ($body, $user) = @_; + + my $prob_params = { send_method_used => 'Open311', whensent => \'current_timestamp', external_id => 1 }; + my ($p) = $mech->create_problems_for_body(1, $body->id, 'Title', $prob_params); + my $c = c($p, $user); + return ($p, $c); +} + +my ($p1, $c1) = p_and_c($bromley, $other_user); +my ($p2, $c2) = p_and_c($oxon); +my ($p3, $c3a) = p_and_c($bucks); +my $c3b = c($p3, $other_user); +my ($p4, $c4) = p_and_c($lewisham); + +subtest 'Send comments' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => ['fixmystreet', 'bromley', 'buckinghamshire', 'lewisham', 'oxfordshire'], + }, sub { + $o->send; + $c3a->discard_changes; + is $c3a->extra, undef, 'Bucks update by owner was sent'; + $c3b->discard_changes; + is $c3b->extra->{cobrand_skipped_sending}, 1, 'Bucks update by other was not'; + $c1->discard_changes; + is $c1->extra->{title}, "MRS", 'Title set on Bromley update'; + $c2->discard_changes; + is $c2->send_fail_count, 0, 'Oxfordshire update skipped entirely'; + }; +}; + +subtest 'Oxfordshire gets an ID' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => ['fixmystreet', 'bromley', 'buckinghamshire', 'lewisham', 'oxfordshire'], + }, sub { + $p2->set_extra_metadata(customer_reference => 'ABC'); + $p2->update; + $o->send; + $c2->discard_changes; + is $c2->send_fail_count, 1, 'Oxfordshire update tried to send, failed'; + }; +}; + + +done_testing(); diff --git a/t/photostorage/s3.t b/t/photostorage/s3.t new file mode 100644 index 000000000..ec0fadc15 --- /dev/null +++ b/t/photostorage/s3.t @@ -0,0 +1,167 @@ +#!/usr/bin/env perl +use FixMyStreet::Test; + +use Test::MockModule; +use Test::Warn; +use Path::Tiny 'path'; +use Net::Amazon::S3::Client::Bucket; + +use_ok( 'FixMyStreet::PhotoStorage::S3' ); + +FixMyStreet::override_config { + PHOTO_STORAGE_OPTIONS => { + ACCESS_KEY => 'AKIAMYFAKEACCESSKEY', + SECRET_KEY => '1234/fAk35eCrETkEy', + BUCKET => 'fms-test-photos', + PREFIX => '/uploads', + }, +}, sub { + + my $s3 = FixMyStreet::PhotoStorage::S3->new(); + + subtest "basic attributes are configured correctly" => sub { + ok $s3->client, "N::A::S3::Client created"; + is $s3->client->s3->aws_access_key_id, 'AKIAMYFAKEACCESSKEY', "Correct access key used"; + is $s3->client->s3->aws_secret_access_key, '1234/fAk35eCrETkEy', "Correct secret key used"; + + ok $s3->bucket, "N::A::S3::Bucket created"; + is $s3->bucket->name, 'fms-test-photos', "Correct bucket name configured"; + + is $s3->prefix, '/uploads/', "Correct key prefix with trailing slash"; + }; + + subtest "photos can be stored in S3" => sub { + my $photo_blob = path('t/app/controller/sample.jpg')->slurp; + is $s3->get_fileid($photo_blob), '74e3362283b6ef0c48686fb0e161da4043bbcc97', "File ID calculated correctly"; + is $s3->detect_type($photo_blob), 'jpeg', "File type calculated correctly"; + + my $s3_object = Test::MockModule->new('Net::Amazon::S3::Client::Object'); + my $put_called = 0; + $s3_object->mock('put', sub { + my ($self, $photo) = @_; + is $self->key, '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', 'Object created with correct key'; + is $self->bucket->name, 'fms-test-photos', 'Object stored in correct bucket'; + is $photo, $photo_blob, 'Correct photo uploaded'; + $put_called = 1; + }); + + is $s3->store_photo($photo_blob), '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', 'Photo uploaded and correct key returned'; + ok $put_called, "Object::put called"; + }; + + subtest "photos can be retrieved from S3" => sub { + my $photo_blob = path('t/app/controller/sample.jpg')->slurp; + my $key = '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg'; + + my $s3_object = Test::MockModule->new('Net::Amazon::S3::Client::Object'); + my $exists_called = 0; + $s3_object->mock('exists', sub { + my ($self) = @_; + is $self->key, $key, 'Object::exists called with correct key'; + $exists_called = 1; + return 1; + }); + my $get_called = 0; + $s3_object->mock('get', sub { + my ($self) = @_; + is $self->key, $key, 'Object::get called with correct key'; + is $self->bucket->name, 'fms-test-photos', 'Object fetched from correct bucket'; + $get_called = 1; + return $photo_blob; + }); + + my ($photo, $type) = $s3->retrieve_photo($key); + ok $exists_called, "Object::exists called"; + ok $get_called, "Object::get called"; + is $photo, $photo_blob, 'Correct file content returned'; + is $type, 'jpeg', 'Correct file type returned'; + }; + + subtest "init passes if bucket exists" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'fms-test-photos' + ) + ); + }); + + ok $s3->init(), "PhotoStorage::S3::init succeeded"; + ok $buckets_called, "Client::buckets called"; + }; + + subtest "init fails if bucket doesn't exist" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'not-your-bucket' + ) + ); + }); + my $create_bucket_called = 0; + $s3_client->mock('create_bucket', sub { + $create_bucket_called = 1; + }); + + warning_like { + $s3->init(); + } qr/S3 bucket 'fms-test-photos' doesn't exist and CREATE_BUCKET is not set./, 'PhotoStorage::S3::init failed'; + ok $buckets_called, "Client::buckets called"; + ok !$create_bucket_called, "Client::create_bucket not called"; + }; +}; + +FixMyStreet::override_config { + PHOTO_STORAGE_OPTIONS => { + ACCESS_KEY => 'AKIAMYFAKEACCESSKEY', + SECRET_KEY => '1234/fAk35eCrETkEy', + BUCKET => 'fms-test-photos', + CREATE_BUCKET => 1, + REGION => 'eu-west-3', + }, +}, sub { + + my $s3 = FixMyStreet::PhotoStorage::S3->new(); + + subtest "init creates bucket if CREATE_BUCKET set" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $create_bucket_called = 0; + $s3_client->mock('create_bucket', sub { + my ( $self, %conf ) = @_; + $create_bucket_called = 1; + is $conf{name}, "fms-test-photos", "Bucket created with correct name"; + is $conf{location_constraint}, "eu-west-3", "Bucket created in correct region"; + }); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'not-your-bucket' + ), + $create_bucket_called ? Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'fms-test-photos' + ) : (), + ); + }); + + ok $s3->init(), "PhotoStorage::S3::init succeeded"; + ok $buckets_called, "Client::buckets called"; + ok $create_bucket_called, "Client::create_bucket called"; + }; +}; + +done_testing(); diff --git a/t/script/inactive.t b/t/script/inactive.t index 4d78b385f..4667c989b 100644 --- a/t/script/inactive.t +++ b/t/script/inactive.t @@ -55,7 +55,8 @@ subtest 'Closing updates on inactive fixed/closed reports' => sub { $in->reports; $problems[2]->discard_changes; is $problems[2]->get_extra_metadata('closed_updates'), 1, 'Closed to updates'; - # TODO Visit page, check closed for updates + $mech->get_ok("/report/" . $problems[2]->id); + $mech->content_contains('now closed to updates'); }; subtest 'Anonymization of inactive users' => sub { diff --git a/t/sendreport/open311.t b/t/sendreport/open311.t index 26764dc19..e68a0aa3c 100644 --- a/t/sendreport/open311.t +++ b/t/sendreport/open311.t @@ -74,6 +74,10 @@ subtest 'test report with multiple photos only sends one', sub { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'fixmystreet' ], MAPIT_URL => 'http://mapit.uk/', + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; @@ -107,6 +111,10 @@ subtest 'test sending multiple photos', sub { STAGING_FLAGS => { send_reports => 1 }, ALLOWED_COBRANDS => [ 'tester' ], MAPIT_URL => 'http://mapit.uk/', + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { $test_data = FixMyStreet::Script::Reports::send(); }; |