aboutsummaryrefslogtreecommitdiffstats
path: root/t/app/model
diff options
context:
space:
mode:
Diffstat (limited to 't/app/model')
-rw-r--r--t/app/model/alert_type.t137
-rw-r--r--t/app/model/comment.t10
-rw-r--r--t/app/model/defecttype.t67
-rw-r--r--t/app/model/extra.t109
-rw-r--r--t/app/model/moderation.t66
-rw-r--r--t/app/model/photoset.t81
-rw-r--r--t/app/model/problem.t598
-rw-r--r--t/app/model/questionnaire.t30
-rw-r--r--t/app/model/rabx_column.t23
-rw-r--r--t/app/model/token.t108
-rw-r--r--t/app/model/user.t61
-rw-r--r--t/app/model/user_planned_report.t52
12 files changed, 1087 insertions, 255 deletions
diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t
index c592e9d3f..5e4fcec0a 100644
--- a/t/app/model/alert_type.t
+++ b/t/app/model/alert_type.t
@@ -9,21 +9,21 @@ my $mech = FixMyStreet::TestMech->new();
# this is the easiest way to make sure we're not going
# to get any emails sent by data kicking about in the database
-FixMyStreet::App->model('DB::AlertType')->email_alerts();
+FixMyStreet::DB->resultset('AlertType')->email_alerts();
$mech->clear_emails_ok;
my $user =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find_or_create( { email => 'test@example.com', name => 'Test User' } );
ok $user, "created test user";
my $user2 =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find_or_create( { email => 'commenter@example.com', name => 'Commenter' } );
ok $user2, "created comment user";
my $user3 =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find_or_create( { email => 'bystander@example.com', name => 'Bystander' } );
ok $user3, "created bystander";
@@ -36,10 +36,10 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
- council => '2504',
+ bodies_str => '2504',
areas => ',105255,11806,11828,2247,2504,',
category => 'Other',
title => 'Test 2',
@@ -62,7 +62,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create(
{
problem_id => $report_id,
user_id => $user2->id,
@@ -74,7 +74,7 @@ my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
anonymous => 'f',
}
);
-my $comment2 = FixMyStreet::App->model('DB::Comment')->find_or_create(
+my $comment2 = FixMyStreet::DB->resultset('Comment')->find_or_create(
{
problem_id => $report_id,
user_id => $user2->id,
@@ -87,26 +87,28 @@ my $comment2 = FixMyStreet::App->model('DB::Comment')->find_or_create(
}
);
-$comment->confirmed( \"ms_current_timestamp() - '3 days'::interval" );
+$comment->confirmed( \"current_timestamp - '3 days'::interval" );
$comment->update;
-my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
user => $user,
parameter => $report_id,
alert_type => 'new_updates',
whensubscribed => $dt->ymd . ' ' . $dt->hms,
confirmed => 1,
+ cobrand => 'default',
}
);
-my $alert3 = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $alert3 = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
user => $user3,
parameter => $report_id,
alert_type => 'new_updates',
whensubscribed => $dt->ymd . ' ' . $dt->hms,
confirmed => 1,
+ cobrand => 'default',
}
);
@@ -127,7 +129,7 @@ for my $test (
subtest "correct summary for state of $test->{state}" => sub {
$mech->clear_emails_ok;
- my $sent = FixMyStreet::App->model('DB::AlertSent')->search(
+ my $sent = FixMyStreet::DB->resultset('AlertSent')->search(
{
alert_id => [ $alert->id, $alert3->id ],
parameter => $comment->id,
@@ -137,18 +139,18 @@ for my $test (
$report->state( $test->{state} );
$report->update;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
$mech->email_count_is( 2 );
my @emails = $mech->get_email;
my $msg = $test->{msg};
for my $email (@emails) {
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email($email);
my $to = $email->header('To');
like $body, qr/$msg/, 'email says problem is ' . $test->{state};
if ($to eq $user->email) {
- like $body, qr{/M/}, 'contains problem login url';
+ like $body, qr{/R/}, 'contains problem login url';
} elsif ($to eq $user3->email) {
like $body, qr{/report/$report_id}, 'contains problem url';
}
@@ -165,7 +167,7 @@ my $now = DateTime->now();
$report->confirmed( $now->ymd . ' ' . $now->hms );
$report->update();
-my $council_alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $council_alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
user => $user2,
parameter => 2504,
@@ -179,17 +181,20 @@ my $council_alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
subtest "correct text for title after URL" => sub {
$mech->clear_emails_ok;
- my $sent = FixMyStreet::App->model('DB::AlertSent')->search(
+ my $sent = FixMyStreet::DB->resultset('AlertSent')->search(
{
alert_id => $council_alert->id,
parameter => $report->id,
}
)->delete;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
+ };
- my $email = $mech->get_email;
(my $title = $report->title) =~ s/ /\\s+/;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
like $body, qr#report/$report_id\s+-\s+$title#, 'email contains expected title';
};
@@ -281,7 +286,7 @@ foreach my $test (
desc => 'address only',
addressLine => '18 North Bridge',
locality => undef,
- nearest => qr/: 18 North Bridge\n/,
+ nearest => qr/: 18 North Bridge\r?\n/,
},
{
desc => 'no fields',
@@ -298,7 +303,7 @@ foreach my $test (
subtest "correct Nearest Road text with $test->{desc}" => sub {
$mech->clear_emails_ok;
- my $sent = FixMyStreet::App->model('DB::AlertSent')->search(
+ my $sent = FixMyStreet::DB->resultset('AlertSent')->search(
{
alert_id => $council_alert->id,
parameter => $report->id,
@@ -318,10 +323,13 @@ foreach my $test (
$report->geocode( $g );
$report->update();
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
+ };
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
if ( $test->{nearest} ) {
like $body, $test->{nearest}, 'correct nearest line';
@@ -331,21 +339,21 @@ foreach my $test (
};
}
-my $ward_alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $ward_alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
user => $user,
parameter => 7117,
alert_type => 'area_problems',
whensubscribed => $dt->ymd . ' ' . $dt->hms,
confirmed => 1,
- cobrand => 'lichfielddc',
+ cobrand => 'hart',
}
);
-my $report_to_council = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report_to_council = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'WS13 6YY',
- council => '2434',
+ bodies_str => '2434',
areas => ',105255,11806,11828,2247,2504,7117,',
category => 'Other',
title => 'council report',
@@ -366,10 +374,10 @@ my $report_to_council = FixMyStreet::App->model('DB::Problem')->find_or_create(
}
);
-my $report_to_county_council = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report_to_county_council = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'WS13 6YY',
- council => '2240',
+ bodies_str => '2240',
areas => ',105255,11806,11828,2247,2504,7117,',
category => 'Other',
title => 'county report',
@@ -390,10 +398,10 @@ my $report_to_county_council = FixMyStreet::App->model('DB::Problem')->find_or_c
}
);
-my $report_outside_district = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report_outside_district = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'WS13 6YY',
- council => '2221',
+ bodies_str => '2221',
areas => ',105255,11806,11828,2247,2504,7117,',
category => 'Other',
title => 'outside district report',
@@ -417,20 +425,23 @@ my $report_outside_district = FixMyStreet::App->model('DB::Problem')->find_or_cr
subtest "check alerts from cobrand send main site url for alerts for different council" => sub {
$mech->clear_emails_ok;
- my $sent = FixMyStreet::App->model('DB::AlertSent')->search(
+ my $sent = FixMyStreet::DB->resultset('AlertSent')->search(
{
alert_id => $ward_alert->id,
}
)->delete;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
+ };
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
- my $expected1 = mySociety::Config::get('BASE_URL') . '/report/' . $report_to_county_council->id;
- my $expected3 = mySociety::Config::get('BASE_URL') . '/report/' . $report_outside_district->id;
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('lichfielddc')->new();
+ my $expected1 = FixMyStreet->config('BASE_URL') . '/report/' . $report_to_county_council->id;
+ my $expected3 = FixMyStreet->config('BASE_URL') . '/report/' . $report_outside_district->id;
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('hart')->new();
my $expected2 = $cobrand->base_url . '/report/' . $report_to_council->id;
like $body, qr#$expected1#, 'non cobrand area report point to fixmystreet.com';
@@ -439,14 +450,14 @@ subtest "check alerts from cobrand send main site url for alerts for different c
};
-my $local_alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $local_alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
user => $user,
parameter => -1.731322,
parameter2 => 52.727588,
alert_type => 'local_problems',
whensubscribed => $dt->ymd . ' ' . $dt->hms,
- cobrand => 'lichfielddc',
+ cobrand => 'hart',
confirmed => 1,
}
);
@@ -454,26 +465,50 @@ my $local_alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
subtest "check local alerts from cobrand send main site url for alerts for different council" => sub {
$mech->clear_emails_ok;
- my $sent = FixMyStreet::App->model('DB::AlertSent')->search(
+ my $sent = FixMyStreet::DB->resultset('AlertSent')->search(
{
alert_id => $local_alert->id,
}
)->delete;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
- my $expected1 = mySociety::Config::get('BASE_URL') . '/report/' . $report_to_county_council->id;
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('lichfielddc')->new();
+ my $expected1 = FixMyStreet->config('BASE_URL') . '/report/' . $report_to_county_council->id;
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('hart')->new();
my $expected2 = $cobrand->base_url . '/report/' . $report_to_council->id;
like $body, qr#$expected1#, 'non cobrand area report point to fixmystreet.com';
like $body, qr#$expected2#, 'cobrand area report point to cobrand url';
};
-$report->comments->delete();
-$report->delete();
-done_testing();
+# Test that email alerts are sent in the right language.
+subtest "correct i18n-ed summary for state of closed" => sub {
+ $mech->clear_emails_ok;
+
+ $report->update( { state => 'closed' } );
+ $alert->update( { lang => 'nb', cobrand => 'fiksgatami' } );
+
+ FixMyStreet::DB->resultset('AlertSent')->search( {
+ alert_id => $alert->id,
+ parameter => $comment->id,
+ } )->delete;
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fiksgatami' ],
+ }, sub {
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
+ };
+
+ my $body = $mech->get_text_body_from_email;
+ my $msg = 'Denne rapporten er for tiden markert som lukket';
+ like $body, qr/$msg/, 'email says problem is closed, in Norwegian';
+};
+
+END {
+ $mech->delete_user($user) if $user;
+ $mech->delete_user($user2) if $user2;
+ $mech->delete_user($user3) if $user3;
+ done_testing();
+}
diff --git a/t/app/model/comment.t b/t/app/model/comment.t
index 93104c2e5..e83d795fc 100644
--- a/t/app/model/comment.t
+++ b/t/app/model/comment.t
@@ -1,14 +1,12 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
use Test::More tests => 2;
use FixMyStreet;
-use FixMyStreet::App;
+use FixMyStreet::DB;
-my $comment_rs = FixMyStreet::App->model('DB::Comment');
+my $comment_rs = FixMyStreet::DB->resultset('Comment');
my $comment = $comment_rs->new(
{
@@ -23,5 +21,5 @@ my $comment = $comment_rs->new(
}
);
-is $comment->confirmed_local, undef, 'inflating null confirmed ok';
-is $comment->created_local, undef, 'inflating null confirmed ok';
+is $comment->confirmed, undef, 'inflating null confirmed ok';
+is $comment->created, undef, 'inflating null confirmed ok';
diff --git a/t/app/model/defecttype.t b/t/app/model/defecttype.t
new file mode 100644
index 000000000..0f66ac684
--- /dev/null
+++ b/t/app/model/defecttype.t
@@ -0,0 +1,67 @@
+use strict;
+use warnings;
+use Test::More;
+
+use FixMyStreet::App;
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+my $potholes_contact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' );
+my $traffic_lights_contact =$mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' );
+
+my $potholes_defect_type = FixMyStreet::App->model('DB::DefectType')->find_or_create(
+ {
+ body_id => 2237,
+ name => 'Potholes',
+ description => 'This defect type is to do with potholes'
+ }
+);
+$potholes_defect_type->contact_defect_types->find_or_create({
+ contact_id => $potholes_contact->id,
+});
+
+my $general_defect_type = FixMyStreet::App->model('DB::DefectType')->find_or_create(
+ {
+ body_id => 2237,
+ name => 'All categories',
+ description => 'This defect type is for all categories'
+ }
+);
+
+
+subtest 'for_bodies returns correct results' => sub {
+ my $defect_types = FixMyStreet::App->model('DB::DefectType')->for_bodies(
+ [ $oxfordshire->id ],
+ 'Potholes'
+ );
+
+ is $defect_types->count, 2, 'Both defect types are included for Potholes category';
+
+ $defect_types = FixMyStreet::App->model('DB::DefectType')->for_bodies(
+ [ $oxfordshire->id ],
+ 'Traffic lights'
+ );
+
+ is $defect_types->count, 1, 'Only 1 defect type is included for Traffic lights category';
+ is $defect_types->first->name, $general_defect_type->name, 'Correct defect type is returned for Traffic lights category';
+};
+
+subtest 'Problem->defect_types behaves correctly' => sub {
+ my ($problem) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Test', {
+ category => 'Potholes',
+ });
+
+ is $problem->defect_types->count, 2, 'Both defect types are available for the problem';
+
+ $problem->update({ category => 'Traffic lights' });
+ is $problem->defect_types->count, 1, 'Only 1 defect type is included for Traffic lights category';
+ is $problem->defect_types->first->name, $general_defect_type->name, 'Correct defect type is returned for Traffic lights category';
+};
+
+
+END {
+ $mech->delete_body( $oxfordshire );
+
+ done_testing();
+}
diff --git a/t/app/model/extra.t b/t/app/model/extra.t
new file mode 100644
index 000000000..3b46ce128
--- /dev/null
+++ b/t/app/model/extra.t
@@ -0,0 +1,109 @@
+use strict;
+use warnings;
+use Test::More;
+use utf8;
+
+use FixMyStreet::DB;
+use Data::Dumper;
+use DateTime;
+
+my $db = FixMyStreet::DB->connect;
+$db->txn_begin;
+
+my $body = $db->resultset('Body')->create({ name => 'ExtraTestingBody' });
+
+my $serial = 1;
+sub get_test_contact {
+ my $extra = shift;
+ my $contact = $db->resultset('Contact')->create({
+ category => "Testing ${serial}",
+ body => $body,
+ email => 'test@example.com',
+ confirmed => 1,
+ deleted => 0,
+ editor => 'test script',
+ note => 'test script',
+ whenedited => DateTime->now(),
+ $extra ? ( extra => $extra ) : (),
+ });
+ $serial++;
+ return $contact;
+}
+
+subtest 'Old list layout transparently upgraded' => sub {
+
+ subtest 'layout' => sub {
+ my $contact = get_test_contact([]);
+
+ is_deeply $contact->get_extra(), { _fields => [] }, 'transparently upgraded to a hash';
+ };
+
+ subtest 'extra fields' => sub {
+ my $contact = get_test_contact([]);
+
+ is_deeply $contact->get_extra_fields(), [], 'No extra fields';
+
+ my @fields = ( { a => 1 }, { b => 2 } );
+ $contact->set_extra_fields(@fields);
+ is_deeply $contact->extra, { _fields => \@fields }, 'extra fields set...';
+ $contact->update;
+ $contact->discard_changes;
+ is_deeply $contact->extra, { _fields => \@fields }, '...and retrieved';
+ is_deeply $contact->get_extra_fields(), \@fields, 'extra fields returned';
+ };
+
+ subtest 'metadata' => sub {
+ my $contact = get_test_contact([]);
+ is_deeply $contact->get_extra_metadata, {}, 'No extra metadata';
+
+ $contact->set_extra_metadata('foo' => 'bar');
+ is $contact->get_extra_metadata('foo'), 'bar', 'extra metadata set...';
+ $contact->update;
+ $contact->discard_changes;
+ is $contact->get_extra_metadata('foo'), 'bar', '... and retrieved';
+ is_deeply $contact->get_extra_metadata, { foo => 'bar' }, 'No extra metadata';
+ };
+};
+
+subtest 'Default hash layout' => sub {
+ subtest 'layout' => sub {
+ my $contact = get_test_contact();
+
+ is_deeply $contact->get_extra(), {}, 'default layout is hash';
+ };
+
+ subtest 'extra fields' => sub {
+ my $contact = get_test_contact();
+
+ is_deeply $contact->get_extra_fields(), [], 'No extra fields';
+
+ my @fields = ( { a => 1 }, { b => 2 } );
+ $contact->set_extra_fields(@fields);
+ is_deeply $contact->get_extra_fields, \@fields, 'extra fields set...';
+ $contact->update;
+ $contact->discard_changes;
+ is_deeply $contact->get_extra_fields(), \@fields, '... and returned';
+ is_deeply $contact->extra, { _fields => \@fields }, '(sanity check layout)';
+ };
+
+ subtest 'metadata' => sub {
+ my $contact = get_test_contact();
+ is_deeply $contact->get_extra_metadata, {}, 'No extra metadata';
+
+ $contact->set_extra_metadata('foo' => 'bar');
+ is $contact->get_extra_metadata('foo'), 'bar', 'extra metadata set...';
+ $contact->update;
+ $contact->discard_changes;
+ is $contact->get_extra_metadata( 'foo'), 'bar', '... and retrieved';
+ is_deeply $contact->get_extra_metadata, { foo => 'bar' }, 'No extra metadata';
+
+ $contact->unset_extra_metadata('foo');
+ is $contact->get_extra_metadata('foo'), undef, 'extra metadata now unset';
+ $contact->update;
+ $contact->discard_changes;
+ is $contact->get_extra_metadata('foo'), undef, '... after retrieval';
+ };
+};
+
+$db->txn_rollback;
+done_testing();
diff --git a/t/app/model/moderation.t b/t/app/model/moderation.t
new file mode 100644
index 000000000..8fa333db4
--- /dev/null
+++ b/t/app/model/moderation.t
@@ -0,0 +1,66 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+use utf8;
+
+use FixMyStreet::DB;
+use Data::Dumper;
+use DateTime;
+
+my $dt = DateTime->now;
+my $user = FixMyStreet::DB->resultset('User')->find_or_create({
+ name => 'Bob', email => 'bob@example.com',
+});
+
+sub get_report_and_original_data {
+ my $report = FixMyStreet::DB->resultset('Problem')->create(
+ {
+ postcode => 'BR1 3SB',
+ bodies_str => '',
+ areas => ",,",
+ category => 'Other',
+ title => 'test',
+ detail => 'test',
+ used_map => 't',
+ name => 'Anon',
+ anonymous => 't',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.4129',
+ longitude => '0.007831',
+ user => $user,
+ });
+ my $original = $report->create_related( moderation_original_data => {
+ anonymous => 't',
+ title => 'test',
+ detail => 'test',
+ photo => 'f',
+ } );
+
+ return ($report, $original);
+}
+
+subtest 'Explicit Deletion (sanity test)' => sub {
+ my ($report, $orig) = get_report_and_original_data;
+
+ lives_ok {
+ $orig->delete;
+ $report->delete;
+ };
+};
+
+subtest 'Implicit Chained Deletion' => sub {
+ my ($report, $orig) = get_report_and_original_data;
+
+ lives_ok {
+ $report->delete;
+ };
+};
+
+done_testing();
diff --git a/t/app/model/photoset.t b/t/app/model/photoset.t
new file mode 100644
index 000000000..54530adfb
--- /dev/null
+++ b/t/app/model/photoset.t
@@ -0,0 +1,81 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+use utf8;
+
+use FixMyStreet::DB;
+use DateTime;
+use Path::Tiny 'path';
+use File::Temp 'tempdir';
+
+my $dt = DateTime->now;
+
+my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
+
+my $db = FixMyStreet::DB->storage->schema;
+
+my $user = $db->resultset('User')->find_or_create({
+ name => 'Bob', email => 'bob@example.com',
+});
+
+FixMyStreet::override_config {
+ UPLOAD_DIR => $UPLOAD_DIR,
+}, sub {
+
+$db->txn_begin;
+
+my $image_path = path('t/app/controller/sample.jpg');
+
+sub make_report {
+ my $photo_data = shift;
+ return $db->resultset('Problem')->create({
+ postcode => 'BR1 3SB',
+ bodies_str => '',
+ areas => ",,",
+ category => 'Other',
+ title => 'test',
+ detail => 'test',
+ used_map => 't',
+ name => 'Anon',
+ anonymous => 't',
+ state => 'confirmed',
+ confirmed => $dt,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.4129',
+ longitude => '0.007831',
+ user => $user,
+ photo => $photo_data,
+ });
+}
+
+
+subtest 'Photoset with photo inline in DB' => sub {
+ my $report = make_report( $image_path->slurp );
+ my $photoset = $report->get_photoset();
+ is $photoset->num_images, 1, 'Found just 1 image';
+ is $photoset->data, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg';
+};
+
+$image_path->copy( path( $UPLOAD_DIR, '0123456789012345678901234567890123456789.jpeg' ) );
+subtest 'Photoset with 1 referenced photo' => sub {
+ my $report = make_report( '0123456789012345678901234567890123456789' );
+ my $photoset = $report->get_photoset();
+ is $photoset->num_images, 1, 'Found just 1 image';
+};
+
+subtest 'Photoset with 3 referenced photo' => sub {
+ my $report = make_report( '0123456789012345678901234567890123456789,0123456789012345678901234567890123456789,0123456789012345678901234567890123456789' );
+ my $photoset = $report->get_photoset();
+ is $photoset->num_images, 3, 'Found 3 images';
+};
+
+$db->txn_rollback;
+
+};
+
+done_testing();
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();
+}
diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t
index 60b52043a..945a64633 100644
--- a/t/app/model/questionnaire.t
+++ b/t/app/model/questionnaire.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
@@ -8,9 +6,9 @@ use Test::More;
use FixMyStreet;
use FixMyStreet::TestMech;
-my $user = FixMyStreet::App->model('DB::User')->find_or_create( { email => 'test@example.com' } );
+my $user = FixMyStreet::DB->resultset('User')->find_or_create( { email => 'test@example.com' } );
-my $problem = FixMyStreet::App->model('DB::Problem')->create(
+my $problem = FixMyStreet::DB->resultset('Problem')->create(
{
postcode => 'EH99 1SP',
latitude => 1,
@@ -25,15 +23,13 @@ my $problem = FixMyStreet::App->model('DB::Problem')->create(
service => '',
cobrand => 'default',
cobrand_data => '',
- confirmed => \"ms_current_timestamp() - '5 weeks'::interval",
- whensent => \"ms_current_timestamp() - '5 weeks'::interval",
+ confirmed => \"current_timestamp - '5 weeks'::interval",
+ whensent => \"current_timestamp - '5 weeks'::interval",
user => $user,
anonymous => 0,
}
);
-diag $problem->id;
-
my $mech = FixMyStreet::TestMech->new;
for my $test (
@@ -62,6 +58,10 @@ for my $test (
send_email => 1,
},
{
+ state => 'action scheduled',
+ send_email => 1,
+ },
+ {
state => 'in progress',
send_email => 1,
},
@@ -78,6 +78,18 @@ for my $test (
send_email => 1,
},
{
+ state => 'duplicate',
+ send_email => 1,
+ },
+ {
+ state => 'unable to fix',
+ send_email => 1,
+ },
+ {
+ state => 'not responsible',
+ send_email => 1,
+ },
+ {
state => 'closed',
send_email => 1,
},
@@ -92,7 +104,7 @@ for my $test (
$mech->email_count_is(0);
- FixMyStreet::App->model('DB::Questionnaire')
+ FixMyStreet::DB->resultset('Questionnaire')
->send_questionnaires( { site => 'fixmystreet' } );
$mech->email_count_is( $test->{send_email} );
diff --git a/t/app/model/rabx_column.t b/t/app/model/rabx_column.t
new file mode 100644
index 000000000..607d578ce
--- /dev/null
+++ b/t/app/model/rabx_column.t
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use_ok "FixMyStreet::DB::RABXColumn";
+
+# Test that the class names are correctly normalised
+my @tests = (
+ ["FixMyStreet::DB::Result::Token", "Token"],
+ ["FixMyStreet::App::Model::DB::Token", "Token"],
+);
+
+foreach my $test (@tests) {
+ my ($input, $expected) = @$test;
+ is(
+ FixMyStreet::DB::RABXColumn::_get_class_identifier($input),
+ $expected,
+ "$input -> $expected"
+ );
+}
+
+done_testing();
diff --git a/t/app/model/token.t b/t/app/model/token.t
index 12945975e..e31901187 100644
--- a/t/app/model/token.t
+++ b/t/app/model/token.t
@@ -1,23 +1,10 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
-use Test::More tests => 45;
+use Test::More;
use FixMyStreet;
-use FixMyStreet::App;
-use mySociety::AuthToken;
-use mySociety::DBHandle 'dbh';
-
-# set things up so that code using mySociety::DBHandle is happy
-FixMyStreet->configure_mysociety_dbhandle();
-
-# NOTE - remember that you need to explicitly dbh()->commit after making
-# database changes with the mySociety::* modules.
-
-# create a token using DBIC and check we can read it using AuthToken, and vice
-# versa
+use FixMyStreet::DB;
my %tests = (
nested_hash => { foo => 'bar', and => [ 'baz', 'bundy' ] },
@@ -25,72 +12,71 @@ my %tests = (
scalar => 123,
);
-my $token_rs = FixMyStreet::App->model('DB::Token');
+my $token_rs = FixMyStreet::DB->resultset('Token');
-# create using DBIC
foreach my $test_data_name ( sort keys %tests ) {
my $test_data = $tests{$test_data_name};
- pass "--- testing DBIC create using '$test_data_name'";
+ pass "--- testing token creation using '$test_data_name'";
my $dbic_token =
$token_rs->create( { scope => 'testing', data => $test_data } );
my $token = $dbic_token->token;
ok $token, "stored token '$token'";
- is_deeply $dbic_token->data, $test_data, "data stored correctly using DBIC";
+ is_deeply $dbic_token->data, $test_data, "data stored correctly";
- # read back using DBIC
+ # read back from database
is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data,
$test_data,
- "data read back correctly with DBIC";
-
- # read back using mySociety::AuthToken
- is_deeply mySociety::AuthToken::retrieve( 'testing', $token ),
- $test_data, "data read back correctly with m::AT";
+ "data read back correctly";
# delete token
ok $dbic_token->delete, "delete token";
is $token_rs->find( { token => $token, scope => 'testing' } ),
undef,
- "token gone for DBIC";
-
- # read back using mySociety::AuthToken
- is mySociety::AuthToken::retrieve( 'testing', $token ),
- undef, "token gone with m::AT";
-
+ "token gone";
}
-# create using m::AT
-foreach my $test_data_name ( sort keys %tests ) {
- my $test_data = $tests{$test_data_name};
-
- pass "--- testing m::AT create using '$test_data_name'";
-
- my $token = mySociety::AuthToken::store( 'testing', $test_data );
- dbh->commit();
- ok $token, "stored token '$token'";
-
- # read back using DBIC
- is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data,
- $test_data,
- "data read back correctly with DBIC";
-
- # read back using mySociety::AuthToken
- is_deeply mySociety::AuthToken::retrieve( 'testing', $token ),
- $test_data, "data read back correctly with m::AT";
-
- # delete token
- ok mySociety::AuthToken::destroy( 'testing', $token ), "destroy token";
- dbh->commit();
-
- is $token_rs->find( { token => $token, scope => 'testing' } ),
- undef,
- "token gone for DBIC";
-
- # read back using mySociety::AuthToken
- is mySociety::AuthToken::retrieve( 'testing', $token ),
- undef, "token gone with m::AT";
+# Test that the inflation and deflation works as expected
+{
+ my $token =
+ $token_rs->create( { scope => 'testing', data => {} } );
+ END { $token->delete() };
+
+ # Add in temporary check to test that the data is updated as expected.
+ is_deeply($token->data, {}, "data is empty");
+
+ # store something in it
+ $token->update({ data => { foo => 'bar' } });
+ $token->discard_changes();
+ is_deeply($token->data, { foo => 'bar' }, "data has content");
+
+ # change the hash stored
+ $token->update({ data => { baz => 'bundy' } });
+ $token->discard_changes();
+ is_deeply($token->data, { baz => 'bundy' }, "data has new content");
+
+ # change the hashref in place
+ {
+ my $data = $token->data;
+ $data->{baz} = 'new';
+ $token->data( $data );
+ $token->update();
+ $token->discard_changes();
+ is_deeply($token->data, { baz => 'new' }, "data has been updated");
+ }
+
+ # change the hashref in place
+ {
+ my $data = $token->data;
+ $data->{baz} = 'new';
+ $token->update({ data => $data });
+ $token->discard_changes();
+ is_deeply($token->data, { baz => 'new' }, "data has been updated");
+ }
}
+
+done_testing();
diff --git a/t/app/model/user.t b/t/app/model/user.t
new file mode 100644
index 000000000..d4115d586
--- /dev/null
+++ b/t/app/model/user.t
@@ -0,0 +1,61 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use FixMyStreet::TestMech;
+use FixMyStreet::DB;
+
+my $mech = FixMyStreet::TestMech->new();
+$mech->log_in_ok('test@example.com');
+
+my ($problem) = $mech->create_problems_for_body(1, '2504', 'Title', { anonymous => 'f' });
+is $problem->user->latest_anonymity, 0, "User's last report was not anonymous";
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/around?pc=sw1a1aa');
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->content_like(qr/may_show_name[^>]*checked/);
+};
+
+($problem) = $mech->create_problems_for_body(1, '2504', 'Title', { anonymous => 't' });
+is $problem->user->latest_anonymity, 1, "User's last report was anonymous";
+
+create_update($problem, anonymous => 'f');
+is $problem->user->latest_anonymity, 0, "User's last update was not anonyous";
+
+create_update($problem, anonymous => 't');
+is $problem->user->latest_anonymity, 1, "User's last update was anonymous";
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/around?pc=sw1a1aa');
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->content_like(qr/may_show_name[^>c]*>/);
+};
+
+END {
+ $mech->delete_user( $problem->user ) if $problem;
+ done_testing();
+}
+
+sub create_update {
+ my ($problem, %params) = @_;
+ my $dt = DateTime->now()->add(days => 1);
+ return FixMyStreet::App->model('DB::Comment')->find_or_create({
+ problem_id => $problem->id,
+ user_id => $problem->user_id,
+ name => 'Other User',
+ mark_fixed => 'false',
+ text => 'This is some update text',
+ state => 'confirmed',
+ anonymous => 'f',
+ created => $dt->ymd . ' ' . $dt->hms,
+ %params,
+ });
+}
diff --git a/t/app/model/user_planned_report.t b/t/app/model/user_planned_report.t
new file mode 100644
index 000000000..95a76615e
--- /dev/null
+++ b/t/app/model/user_planned_report.t
@@ -0,0 +1,52 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use FixMyStreet::TestMech;
+use FixMyStreet::DB;
+
+my $mech = FixMyStreet::TestMech->new();
+
+my @problems = $mech->create_problems_for_body(1, 2237, 'Title');
+my $problem = $problems[0];
+my $user = $problem->user;
+my $user2 = $mech->create_user_ok('other@example.net');
+
+is $user->active_planned_reports, 0;
+is $user->planned_reports, 0;
+
+$user->add_to_planned_reports($problem);
+is $user->active_planned_reports, 1;
+is $user->planned_reports, 1;
+
+$user->add_to_planned_reports($problem);
+is $user->active_planned_reports, 1;
+is $user->planned_reports, 1;
+
+$user->remove_from_planned_reports($problem);
+is $user->active_planned_reports, 0;
+is $user->planned_reports, 1;
+
+$user->add_to_planned_reports($problem);
+is $user->active_planned_reports, 1;
+is $user->planned_reports, 2;
+
+$user2->add_to_planned_reports($problem);
+is $user->active_planned_reports, 0;
+is $user->planned_reports, 2;
+is $user2->active_planned_reports, 1;
+is $user2->planned_reports, 1;
+
+$user->add_to_planned_reports($problem);
+is $user->active_planned_reports, 1;
+is $user->planned_reports, 3;
+is $user2->active_planned_reports, 0;
+is $user2->planned_reports, 1;
+
+done_testing();
+
+END {
+ $mech->delete_user($user);
+ $mech->delete_user($user2);
+}