diff options
Diffstat (limited to 't/app/model/problem.t')
-rw-r--r-- | t/app/model/problem.t | 598 |
1 files changed, 470 insertions, 128 deletions
diff --git a/t/app/model/problem.t b/t/app/model/problem.t index baec6baf0..6b1be0a76 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -1,24 +1,24 @@ -#!/usr/bin/perl - use strict; use warnings; use Test::More; +use FixMyStreet::TestMech; use FixMyStreet; use FixMyStreet::App; -use FixMyStreet::TestMech; +use FixMyStreet::DB; use mySociety::Locale; +use Sub::Override; mySociety::Locale::gettext_domain('FixMyStreet'); -my $problem_rs = FixMyStreet::App->model('DB::Problem'); +my $problem_rs = FixMyStreet::DB->resultset('Problem'); my $problem = $problem_rs->new( { postcode => 'EH99 1SP', - latitude => '51.5016605453401', - longitude => '-0.142497580865087', + latitude => '54.5', + longitude => '-1.5', areas => 1, title => '', detail => '', @@ -32,47 +32,40 @@ my $problem = $problem_rs->new( } ); -is $problem->confirmed_local, undef, 'inflating null confirmed ok'; -is $problem->whensent_local, undef, 'inflating null confirmed ok'; -is $problem->lastupdate_local, undef, 'inflating null confirmed ok'; -is $problem->created_local, undef, 'inflating null confirmed ok'; +my $visible_states = $problem->visible_states; +is_deeply $visible_states, { + 'confirmed' => 1, + 'investigating' => 1, + 'in progress' => 1, + 'planned' => 1, + 'action scheduled' => 1, + 'fixed' => 1, + 'fixed - council' => 1, + 'fixed - user' => 1, + 'unable to fix' => 1, + 'not responsible' => 1, + 'duplicate' => 1, + 'closed' => 1, + 'internal referral' => 1, + }, 'visible_states is correct'; + +is $problem->confirmed, undef, 'inflating null confirmed ok'; +is $problem->whensent, undef, 'inflating null confirmed ok'; +is $problem->lastupdate, undef, 'inflating null confirmed ok'; +is $problem->created, undef, 'inflating null confirmed ok'; -for my $test ( +for my $test ( { desc => 'more or less empty problem', changed => {}, errors => { title => 'Please enter a subject', detail => 'Please enter some details', - council => 'No council selected', + bodies => 'No council selected', name => 'Please enter your name', } }, { - desc => 'name too short', - changed => { - name => 'xx', - }, - errors => { - title => 'Please enter a subject', - detail => 'Please enter some details', - council => 'No council selected', - name => 'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below', - } - }, - { - desc => 'name is anonymous', - changed => { - name => 'anonymous', - }, - errors => { - title => 'Please enter a subject', - detail => 'Please enter some details', - council => 'No council selected', - name => 'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below', - } - }, - { desc => 'correct name', changed => { name => 'A User', @@ -80,7 +73,7 @@ for my $test ( errors => { title => 'Please enter a subject', detail => 'Please enter some details', - council => 'No council selected', + bodies => 'No council selected', } }, { @@ -90,7 +83,7 @@ for my $test ( }, errors => { detail => 'Please enter some details', - council => 'No council selected', + bodies => 'No council selected', } }, { @@ -99,22 +92,22 @@ for my $test ( detail => 'Some information about the problem', }, errors => { - council => 'No council selected', + bodies => 'No council selected', } }, { - desc => 'incorrectly formatted council', + desc => 'incorrectly formatted body', changed => { - council => 'my council', + bodies_str => 'my body', }, errors => { - council => 'No council selected', + bodies => 'No council selected', } }, { - desc => 'correctly formatted council', + desc => 'correctly formatted body', changed => { - council => '1001', + bodies_str => '1001', }, errors => { } @@ -153,9 +146,9 @@ for my $test ( }; } -my $user = FixMyStreet::App->model('DB::User')->find_or_create( +my $user = FixMyStreet::DB->resultset('User')->find_or_create( { - email => 'system_user@example.com' + email => 'system_user@example.net' } ); @@ -167,6 +160,10 @@ $problem->insert; my $tz_local = DateTime::TimeZone->new( name => 'local' ); +my $body = FixMyStreet::DB->resultset('Body')->new({ + name => 'Edinburgh City Council' +}); + for my $test ( { desc => 'request older than problem ignored', @@ -174,9 +171,6 @@ for my $test ( request => { updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local )->subtract( days => 2 ) ), }, - council => { - name => 'Edinburgh City Council', - }, created => 0, }, { @@ -187,9 +181,6 @@ for my $test ( status => 'open', status_notes => 'this is an update from the council', }, - council => { - name => 'Edinburgh City Council', - }, created => 1, state => 'confirmed', mark_fixed => 0, @@ -203,9 +194,6 @@ for my $test ( status => 'closed', status_notes => 'the council have fixed this', }, - council => { - name => 'Edinburgh City Council', - }, created => 1, state => 'fixed', mark_fixed => 1, @@ -219,9 +207,6 @@ for my $test ( status => 'open', status_notes => 'the council do not think this is fixed', }, - council => { - name => 'Edinburgh City Council', - }, created => 1, start_state => 'fixed', state => 'fixed', @@ -238,7 +223,7 @@ for my $test ( $problem->update; my $w3c = DateTime::Format::W3CDTF->new(); - my $ret = $problem->update_from_open311_service_request( $test->{request}, $test->{council}, $user ); + my $ret = $problem->update_from_open311_service_request( $test->{request}, $body, $user ); is $ret, $test->{created}, 'return value'; return unless $test->{created}; @@ -258,12 +243,13 @@ for my $test ( }; } -for my $test ( +for my $test ( { state => 'partial', is_visible => 0, is_fixed => 0, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -271,6 +257,7 @@ for my $test ( is_visible => 0, is_fixed => 0, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -278,6 +265,7 @@ for my $test ( is_visible => 0, is_fixed => 0, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -285,6 +273,7 @@ for my $test ( is_visible => 1, is_fixed => 0, is_open => 1, + is_in_progress => 0, is_closed => 0, }, { @@ -292,6 +281,7 @@ for my $test ( is_visible => 1, is_fixed => 0, is_open => 1, + is_in_progress => 1, is_closed => 0, }, { @@ -299,6 +289,15 @@ for my $test ( is_visible => 1, is_fixed => 0, is_open => 1, + is_in_progress => 1, + is_closed => 0, + }, + { + state => 'action scheduled', + is_visible => 1, + is_fixed => 0, + is_open => 1, + is_in_progress => 1, is_closed => 0, }, { @@ -306,13 +305,39 @@ for my $test ( is_visible => 1, is_fixed => 0, is_open => 1, + is_in_progress => 1, is_closed => 0, }, { + state => 'duplicate', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_in_progress => 0, + is_closed => 1, + }, + { + state => 'not responsible', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_in_progress => 0, + is_closed => 1, + }, + { + state => 'unable to fix', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_in_progress => 0, + is_closed => 1, + }, + { state => 'fixed', is_visible => 1, is_fixed => 1, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -320,6 +345,7 @@ for my $test ( is_visible => 1, is_fixed => 1, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -327,6 +353,7 @@ for my $test ( is_visible => 1, is_fixed => 1, is_open => 0, + is_in_progress => 0, is_closed => 0, }, { @@ -334,6 +361,7 @@ for my $test ( is_visible => 1, is_fixed => 0, is_open => 0, + is_in_progress => 0, is_closed => 1, }, ) { @@ -343,64 +371,75 @@ for my $test ( is $problem->is_fixed, $test->{is_fixed}, 'is_fixed'; is $problem->is_closed, $test->{is_closed}, 'is_closed'; is $problem->is_open, $test->{is_open}, 'is_open'; + is $problem->is_in_progress, $test->{is_in_progress}, 'is_in_progress'; }; } my $mech = FixMyStreet::TestMech->new(); -my %contact_params = ( - confirmed => 1, - deleted => 0, - editor => 'Test', - whenedited => \'ms_current_timestamp()', - note => 'Created for test', -); +my %body_ids; +my @bodies; +for my $body ( + { area_id => 2651, name => 'City of Edinburgh Council' }, + { area_id => 2226, name => 'Gloucestershire County Council' }, + { area_id => 2326, name => 'Cheltenham Borough Council' }, + { area_id => 2333, name => 'Hart Council' }, + { area_id => 2227, name => 'Hampshire County Council' }, + { area_id => 14279, name => 'Ballymoney Borough Council' }, + { area_id => 2636, name => 'Isle of Wight Council' }, + { area_id => 2649, name => 'Fife Council' }, + { area_id => 14279, name => 'TransportNI (Western)' }, +) { + my $aid = $body->{area_id}; + my $body = $mech->create_body_ok($aid, $body->{name}); + if ($body_ids{$aid}) { + $body_ids{$aid} = [ $body_ids{$aid}, $body->id ]; + } else { + $body_ids{$aid} = $body->id; + } + push @bodies, $body; +} + # Let's make some contacts to send things to! -FixMyStreet::App->model('DB::Contact')->search( { - email => { 'like', '%example.com' }, -} )->delete; -my @contacts; for my $contact ( { - body_id => 2651, # Edinburgh + body_id => $body_ids{2651}, # Edinburgh category => 'potholes', email => 'test@example.org', }, { - body_id => 2226, # Gloucestershire + body_id => $body_ids{2226}, # Gloucestershire category => 'potholes', email => '2226@example.org', }, { - body_id => 2326, # Cheltenham + body_id => $body_ids{2326}, # Cheltenham category => 'potholes', email => '2326@example.org', }, { - body_id => 2434, # Lichfield + body_id => $body_ids{2333}, # Hart category => 'potholes', email => 'trees@example.com', }, { - body_id => 2240, # Staffordshire + body_id => $body_ids{2227}, # Hampshire category => 'potholes', email => 'highways@example.com', }, { - body_id => 14279, # Ballymoney + body_id => $body_ids{14279}[1], # TransportNI category => 'Street lighting', email => 'roads.western@drdni.example.org', }, { - body_id => 14279, # Ballymoney + body_id => $body_ids{14279}[0], # Ballymoney category => 'Graffiti', - email => 'highways@example.com', + email => 'highways@example.net', }, { confirmed => 0, - body_id => 2636, # Isle of Wight + body_id => $body_ids{2636}, # Isle of Wight category => 'potholes', email => '2636@example.com', } ) { - my $new_contact = FixMyStreet::App->model('DB::Contact')->find_or_create( { %contact_params, %$contact } ); - ok $new_contact, "created test contact"; - push @contacts, $new_contact; + $mech->create_contact_ok( %$contact ); } my %common = ( - email => 'system_user@example.com', + email => 'system_user@example.net', name => 'Andrew Smith', ); foreach my $test ( { @@ -410,21 +449,21 @@ foreach my $test ( { email_count => 1, dear => qr'Dear City of Edinburgh Council', to => qr'City of Edinburgh Council', - council => 2651, + body => $body_ids{2651}, }, { %common, desc => 'no email sent if no unsent problems', unset_whendef => 0, email_count => 0, - council => 2651, + body => $body_ids{2651}, }, { %common, desc => 'email to two tier council', unset_whendef => 1, email_count => 1, - to => qr'Gloucestershire County Council.*Cheltenham Borough Council', - dear => qr'Dear Gloucestershire County Council and Cheltenham Borough', - council => '2226,2326', + to => qr'Cheltenham Borough Council.*Gloucestershire County Council', + dear => qr'Dear Cheltenham Borough Council and Gloucestershire County', + body => $body_ids{2226} . ',' . $body_ids{2326}, multiple => 1, }, { %common, @@ -433,28 +472,29 @@ foreach my $test ( { email_count => 1, to => qr'Gloucestershire County Council" <2226@example', dear => qr'Dear Gloucestershire County Council,', - council => '2226|2649', + body => $body_ids{2226}, + body_missing => $body_ids{2649}, missing => qr'problem might be the responsibility of Fife.*Council'ms, }, { %common, desc => 'email to two tier council that only shows district, district', unset_whendef => 1, email_count => 1, - to => qr'Lichfield District Council', - dear => qr'Dear Lichfield District Council,', - council => '2434', - cobrand => 'lichfielddc', - url => 'lichfielddc.', + to => qr'Hart Council', + dear => qr'Dear Hart Council,', + body => $body_ids{2333}, + cobrand => 'hart', + url => 'hart.', }, { %common, desc => 'email to two tier council that only shows district, county', unset_whendef => 1, email_count => 1, - to => qr'Staffordshire County Council" <highways@example', - dear => qr'Dear Staffordshire County Council,', - council => '2240', - cobrand => 'lichfielddc', - url => '', + to => qr'Hampshire County Council" <highways@example', + dear => qr'Dear Hampshire County Council,', + body => $body_ids{2227}, + cobrand => 'hart', + url => 'www.', }, { %common, desc => 'directs NI correctly, 1', @@ -462,72 +502,96 @@ foreach my $test ( { email_count => 1, dear => qr'Dear Ballymoney Borough Council', to => qr'Ballymoney Borough Council', - council => 14279, + body => $body_ids{14279}[0], category => 'Graffiti', + longitude => -6.5, + # As Ballmoney contact has same domain as reporter, the From line will + # become a unique reply address and Reply-To will become the reporter + reply_to => 1, }, { %common, desc => 'directs NI correctly, 2', unset_whendef => 1, email_count => 1, - dear => qr'Dear Roads Service \(Western\)', - to => qr'Roads Service \(Western\)" <roads', - council => 14279, + dear => qr'Dear TransportNI \(Western\)', + to => qr'TransportNI \(Western\)" <roads', + body => $body_ids{14279}[1], category => 'Street lighting', + longitude => -6.5, }, { %common, desc => 'does not send to unconfirmed contact', unset_whendef => 1, stays_unsent => 1, email_count => 0, - council => 2636, + body => $body_ids{2636}, }, ) { subtest $test->{ desc } => sub { - if ( $test->{cobrand} && $test->{cobrand} =~ /lichfielddc/ && !FixMyStreet::Cobrand->exists('lichfielddc') ) { - plan skip_all => 'Skipping Lichfield tests without Lichfield cobrand'; + my $override = { + ALLOWED_COBRANDS => [ 'fixmystreet' ], + BASE_URL => 'http://www.fixmystreet.com', + MAPIT_URL => 'http://mapit.mysociety.org/', + }; + if ( $test->{cobrand} && $test->{cobrand} =~ /hart/ ) { + $override->{ALLOWED_COBRANDS} = [ 'hart' ]; } $mech->clear_emails_ok; - FixMyStreet::App->model('DB::Problem')->search( + $problem_rs->search( { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { - council => $test->{ council }, + bodies_str => $test->{ body }, + bodies_missing => $test->{ body_missing }, state => 'confirmed', - confirmed => \'ms_current_timestamp()', - whensent => $test->{ unset_whendef } ? undef : \'ms_current_timestamp()', + confirmed => \'current_timestamp', + whensent => $test->{ unset_whendef } ? undef : \'current_timestamp', category => $test->{ category } || 'potholes', name => $test->{ name }, cobrand => $test->{ cobrand } || 'fixmystreet', + longitude => $test->{longitude} || '-1.5', } ); - FixMyStreet::App->model('DB::Problem')->send_reports(); + FixMyStreet::override_config $override, sub { + $problem_rs->send_reports(); + }; $mech->email_count_is( $test->{ email_count } ); if ( $test->{ email_count } ) { my $email = $mech->get_email; like $email->header('To'), $test->{ to }, 'to line looks correct'; - is $email->header('From'), sprintf('"%s" <%s>', $test->{ name }, $test->{ email } ), 'from line looks correct'; + if ($test->{reply_to}) { + is $email->header('Reply-To'), sprintf('"%s" <%s>', $test->{ name }, $test->{ email } ), 'Reply-To line looks correct'; + like $email->header('From'), qr/"$test->{name}" <fms-report-\d+-\w+\@example.org>/, 'from line looks correct'; + } else { + is $email->header('From'), sprintf('"%s" <%s>', $test->{ name }, $test->{ email } ), 'from line looks correct'; + } like $email->header('Subject'), qr/A Title/, 'subject line looks correct'; - like $email->body, qr/A user of FixMyStreet/, 'email body looks a bit like a report'; - like $email->body, qr/Subject: A Title/, 'more email body checking'; - like $email->body, $test->{ dear }, 'Salutation looks correct'; + my $body = $mech->get_text_body_from_email($email); + like $body, qr/A user of FixMyStreet/, 'email body looks a bit like a report'; + like $body, qr/Subject: A Title/, 'more email body checking'; + like $body, $test->{ dear }, 'Salutation looks correct'; + if ($test->{longitude}) { + like $body, qr{Easting/Northing \(IE\): 297279/362371}; + } else { + like $body, qr{Easting/Northing: }; + } if ( $test->{multiple} ) { - like $email->body, qr/This email has been sent to several councils /, 'multiple council text correct'; + like $body, qr/This email has been sent to several councils /, 'multiple body text correct'; } elsif ( $test->{ missing } ) { - like $email->body, $test->{ missing }, 'missing council information correct'; + like $body, $test->{ missing }, 'missing body information correct'; } if ( $test->{url} ) { - (my $base_url = FixMyStreet->config('BASE_URL')) =~ s{http://}{}; my $id = $problem->id; - like $email->body, qr[$test->{url}$base_url/report/$id], 'URL present is correct'; + like $body, qr[$test->{url}fixmystreet.com/report/$id], 'URL present is correct'; } $problem->discard_changes; @@ -540,12 +604,290 @@ foreach my $test ( { }; } -$problem->comments->delete; -$problem->delete; -$user->delete; +subtest 'check can set mutiple emails as a single contact' => sub { + my $override = { + ALLOWED_COBRANDS => [ 'fixmystreet' ], + BASE_URL => 'http://www.fixmystreet.com', + MAPIT_URL => 'http://mapit.mysociety.org/', + }; -foreach (@contacts) { - $_->delete; -} + my $contact = { + body_id => $body_ids{2651}, # Edinburgh + category => 'trees', + email => '2636@example.com,2636-2@example.com', + }; + $mech->create_contact_ok( %$contact ); -done_testing(); + $mech->clear_emails_ok; + + $problem_rs->search( + { + whensent => undef + } + )->update( { whensent => \'current_timestamp' } ); + + $problem->discard_changes; + $problem->update( { + bodies_str => $contact->{ body_id }, + state => 'confirmed', + confirmed => \'current_timestamp', + whensent => undef, + category => 'trees', + name => 'Test User', + cobrand => 'fixmystreet', + send_fail_count => 0, + } ); + + FixMyStreet::override_config $override, sub { + $problem_rs->send_reports(); + }; + + $mech->email_count_is(1); + my $email = $mech->get_email; + is $email->header('To'), '"City of Edinburgh Council" <2636@example.com>, "City of Edinburgh Council" <2636-2@example.com>', 'To contains two email addresses'; +}; + +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; } + ); + $mech->clear_emails_ok; + + $problem_rs->search( + { + whensent => undef + } + )->update( { whensent => \'current_timestamp' } ); + + $problem->discard_changes; + $problem->update( { + bodies_str => $body_ids{2651}, + state => 'confirmed', + confirmed => \'current_timestamp', + whensent => undef, + category => 'potholes', + name => 'Test User', + cobrand => 'fixmystreet', + send_fail_count => 0, + } ); + + $problem_rs->send_reports(); + + $mech->email_count_is( 2 ); + my @emails = $mech->get_email; + my $email = $emails[0]; + + like $email->header('To'),qr/City of Edinburgh Council/, 'to line looks correct'; + is $email->header('From'), '"Test User" <system_user@example.net>', 'from line looks correct'; + like $email->header('Subject'), qr/A Title/, 'subject line looks correct'; + my $body = $mech->get_text_body_from_email($email); + like $body, qr/A user of FixMyStreet/, 'email body looks a bit like a report'; + like $body, qr/Subject: A Title/, 'more email body checking'; + like $body, qr/Dear City of Edinburgh Council/, 'Salutation looks correct'; + + $problem->discard_changes; + ok defined( $problem->whensent ), 'whensent set'; + + $email = $emails[1]; + like $email->header('Subject'), qr/FixMyStreet Report Sent/, 'report sent email title correct'; + $body = $mech->get_text_body_from_email($email); + like $body, qr/to submit your report/, 'report sent body correct'; + + $send_confirmation_mail_override->restore(); +}; + + +subtest 'check iOS app store test reports not sent' => sub { + $mech->clear_emails_ok; + + $problem_rs->search( + { + whensent => undef + } + )->update( { whensent => \'current_timestamp' } ); + + $problem->discard_changes; + $problem->update( { + bodies_str => $body_ids{2651}, + title => 'App store test', + state => 'confirmed', + confirmed => \'current_timestamp', + whensent => undef, + category => 'potholes', + send_fail_count => 0, + } ); + + $problem_rs->send_reports(); + + $mech->email_count_is( 0 ); + + $problem->discard_changes(); + is $problem->state, 'hidden', 'iOS test reports are hidden automatically'; + is $problem->whensent, undef, 'iOS test reports are not sent'; +}; + +subtest 'check reports from abuser not sent' => sub { + $mech->clear_emails_ok; + + $problem_rs->search( + { + whensent => undef + } + )->update( { whensent => \'current_timestamp' } ); + + $problem->discard_changes; + $problem->update( { + bodies_str => $body_ids{2651}, + title => 'Report', + state => 'confirmed', + confirmed => \'current_timestamp', + whensent => undef, + category => 'potholes', + send_fail_count => 0, + } ); + + $problem_rs->send_reports(); + + $mech->email_count_is( 1 ); + + $problem->discard_changes(); + ok $problem->whensent, 'Report has been sent'; + + $problem->update( { + state => 'confirmed', + confirmed => \'current_timestamp', + whensent => undef, + } ); + + my $abuse = FixMyStreet::DB->resultset('Abuse')->create( { email => $problem->user->email } ); + + $mech->clear_emails_ok; + $problem_rs->send_reports(); + + $mech->email_count_is( 0 ); + + $problem->discard_changes(); + is $problem->state, 'hidden', 'reports from abuse user are hidden automatically'; + is $problem->whensent, undef, 'reports from abuse user are not sent'; + + ok $abuse->delete(), 'user removed from abuse table'; +}; + +subtest 'check response templates' => sub { + my $c1 = $mech->create_contact_ok(category => 'Potholes', body_id => $body_ids{2651}, email => 'p'); + my $c2 = $mech->create_contact_ok(category => 'Graffiti', body_id => $body_ids{2651}, email => 'g'); + my $t1 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body_ids{2651}, title => "Title 1", text => "Text 1" }); + my $t2 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body_ids{2651}, title => "Title 2", text => "Text 2" }); + my $t3 = FixMyStreet::DB->resultset('ResponseTemplate')->create({ body_id => $body_ids{2651}, title => "Title 3", text => "Text 3" }); + $t1->add_to_contacts($c1); + $t2->add_to_contacts($c2); + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + is $problem->response_templates, 1, 'Only the global template returned'; + ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE', { category => 'Potholes' }); + is $problem->response_templates, 2, 'Global and pothole templates returned'; +}; + +subtest 'check duplicate reports' => sub { + my ($problem1, $problem2) = $mech->create_problems_for_body(2, $body_ids{2651}, 'TITLE'); + $problem1->set_extra_metadata(duplicate_of => $problem2->id); + $problem1->state('duplicate'); + $problem1->update; + + is $problem1->duplicate_of->title, $problem2->title, 'problem1 returns correct problem from duplicate_of'; + is scalar @{ $problem2->duplicates }, 1, 'problem2 has correct number of duplicates'; + is $problem2->duplicates->[0]->title, $problem1->title, 'problem2 includes problem1 in duplicates'; +}; + +subtest 'generates a tokenised url for a user' => sub { + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + my $url = $problem->tokenised_url($user); + (my $token = $url) =~ s/\/M\///g; + + like $url, qr/\/M\//, 'problem generates tokenised url'; + + my $token_obj = FixMyStreet::App->model('DB::Token')->find( { + scope => 'email_sign_in', token => $token + } ); + is $token, $token_obj->token, 'token is generated in database with correct scope'; + is $token_obj->data->{r}, $problem->url, 'token has correct redirect data'; +}; + +subtest 'stores params in a token' => sub { + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + my $url = $problem->tokenised_url($user, { foo => 'bar', baz => 'boo'}); + (my $token = $url) =~ s/\/M\///g; + + my $token_obj = FixMyStreet::App->model('DB::Token')->find( { + scope => 'email_sign_in', token => $token + } ); + + is_deeply $token_obj->data->{p}, { foo => 'bar', baz => 'boo'}, 'token has correct params'; +}; + +subtest 'get report time ago in appropriate format' => sub { + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + + $problem->update( { + confirmed => DateTime->now->subtract( minutes => 2) + } ); + is $problem->time_ago, '2 minutes', 'problem returns time ago in minutes'; + + $problem->update( { + confirmed => DateTime->now->subtract( hours => 18) + } ); + is $problem->time_ago, '18 hours', 'problem returns time ago in hours'; + + $problem->update( { + confirmed => DateTime->now->subtract( days => 4) + } ); + is $problem->time_ago, '4 days', 'problem returns time ago in days'; + + $problem->update( { + confirmed => DateTime->now->subtract( weeks => 3 ) + } ); + is $problem->time_ago, '3 weeks', 'problem returns time ago in weeks'; + + $problem->update( { + confirmed => DateTime->now->subtract( months => 4 ) + } ); + is $problem->time_ago, '4 months', 'problem returns time ago in months'; + + $problem->update( { + confirmed => DateTime->now->subtract( years => 2 ) + } ); + is $problem->time_ago, '2 years', 'problem returns time ago in years'; +}; + +subtest 'time ago works with other dates' => sub { + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + + $problem->update( { + lastupdate => DateTime->now->subtract( days => 4) + } ); + is $problem->time_ago('lastupdate'), '4 days', 'problem returns last updated time ago in days'; +}; + +subtest 'return how many days ago a problem was reported' => sub { + my ($problem) = $mech->create_problems_for_body(1, $body_ids{2651}, 'TITLE'); + $problem->update( { + confirmed => DateTime->now->subtract( weeks => 2 ) + } ); + is $problem->days_ago, 14, 'days_ago returns the amount of days'; + + $problem->update( { + lastupdate => DateTime->now->subtract( days => 4) + } ); + + is $problem->days_ago('lastupdate'), 4, 'days_ago allows other dates to be specified'; +}; + +END { + $problem->comments->delete if $problem; + $problem->delete if $problem; + $mech->delete_user( $user ) if $user; + + $mech->delete_body($_) for @bodies; + + done_testing(); +} |