diff options
author | Struan Donald <struan@exo.org.uk> | 2011-11-18 14:32:25 +0000 |
---|---|---|
committer | Struan Donald <struan@exo.org.uk> | 2011-11-18 14:32:25 +0000 |
commit | 9a83d679abbdb467ec1c363d086b35f09a4c7044 (patch) | |
tree | 30c8fece41b518080fd420d33c2aaf742ddd6ea0 /t | |
parent | d941a8c26e943c941f8e37ecbd9a9982dd41cb70 (diff) | |
parent | 375610803cfcad104049ff895c77c53e6767e1e7 (diff) |
Merge remote branch 'origin/master' into js-validation
Diffstat (limited to 't')
-rw-r--r-- | t/app/controller/admin.t | 53 | ||||
-rw-r--r-- | t/app/controller/report_new.t | 15 | ||||
-rw-r--r-- | t/app/controller/report_new_open311.t | 167 | ||||
-rw-r--r-- | t/app/model/problem.t | 109 | ||||
-rw-r--r-- | t/open311.t | 24 | ||||
-rw-r--r-- | t/open311/getupdates.t | 198 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 255 |
7 files changed, 814 insertions, 7 deletions
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 25e921a4f..beeb6c9c1 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -205,6 +205,59 @@ subtest 'check contact updating' => sub { $mech->content_like(qr{test2\@example.com[^<]*</td>[^<]*<td><strong>Yes}s); }; +my $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); +$open311->delete if $open311; + +subtest 'check open311 configuring' => sub { + $mech->get_ok('/admin/council_contacts/2650/'); + $mech->content_lacks('Council contacts configured via Open311'); + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'api key', + endpoint => 'http://example.com/open311', + jurisdiction => 'mySociety', + } + } + ); + $mech->content_contains('Council contacts configured via Open311'); + $mech->content_contains('Configuration updated - contacts will be generated automatically later'); + + $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); + + is $open311->count, 1, 'only one configuration'; + my $conf = $open311->first; + is $conf->endpoint, 'http://example.com/open311', 'endpoint configured'; + is $conf->api_key, 'api key', 'api key configured'; + is $conf->jurisdiction, 'mySociety', 'jurisdiction configures'; + + $mech->form_number(3); + $mech->submit_form_ok( + { + with_fields => { + api_key => 'new api key', + endpoint => 'http://example.org/open311', + jurisdiction => 'open311', + } + } + ); + + $mech->content_contains('Configuration updated'); + + $open311 = + FixMyStreet::App->model('DB::Open311Conf')->search( { area_id => 2650 } ); + + is $open311->count, 1, 'only one configuration'; + $conf = $open311->first; + is $conf->endpoint, 'http://example.org/open311', 'endpoint updated'; + is $conf->api_key, 'new api key', 'api key updated'; + is $conf->jurisdiction, 'open311', 'jurisdiction configures'; +}; + subtest 'check text output' => sub { $mech->get_ok('/admin/council_contacts/2650?text=1'); is $mech->content_type, 'text/plain'; diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index ff4f4294f..15237e041 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -2,6 +2,7 @@ use strict; use utf8; # sign in error message has – in it use warnings; use Test::More; +use utf8; use FixMyStreet::TestMech; use Web::Scraper; @@ -375,9 +376,11 @@ foreach my $test ( FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); ok $user, "user found"; if ($test->{user}) { + is $user->name, 'Old Name', 'name unchanged'; ok $user->check_password('old_password'), 'password unchanged'; } else { - ok $user->check_password('secret'), 'password set correctly'; + is $user->name, undef, 'name not yet set'; + is $user->password, '', 'password not yet set for new user'; } # find the report @@ -406,10 +409,8 @@ foreach my $test ( $mech->get_ok( '/report/' . $report->id ); - if ($test->{user}) { - is $report->name, 'Joe Bloggs', 'name updated correctly'; - ok $report->user->check_password('secret'), 'password updated correctly'; - } + is $report->name, 'Joe Bloggs', 'name updated correctly'; + ok $report->user->check_password('secret'), 'password updated correctly'; # check that the reporter has an alert my $alert = FixMyStreet::App->model('DB::Alert')->find( { @@ -615,7 +616,7 @@ foreach my $test ( $mech->submit_form_ok( { with_fields => { - title => "Test Report at caf\xc3\xa9", + title => "Test Report at cafĂ©", detail => 'Test report details.', photo => '', name => 'Joe Bloggs', @@ -670,7 +671,7 @@ foreach my $test ( } -$contact2->category( "Pothol\xe9s" ); +$contact2->category( "Pothol\xc3\xa9s" ); $contact2->update; $mech->get_ok( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon ); $mech->content_contains( "Pothol\xc3\xa9s" ); diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t new file mode 100644 index 000000000..dc3583e6b --- /dev/null +++ b/t/app/controller/report_new_open311.t @@ -0,0 +1,167 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; + +my $mech = FixMyStreet::TestMech->new; + +my $open311Conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( { + area_id => 2651, + endpoint => 'http://example.com/open311', + jurisdiction => 'mySociety', + api_key => 'apikey', +} ); + +my %contact_params = ( + confirmed => 1, + deleted => 0, + editor => 'Test', + whenedited => \'current_timestamp', + note => 'Created for test', +); +# Let's make some contacts to send things to! +my $contact1 = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2651, # Edinburgh + category => 'Street lighting', + email => '100', + extra => [ { description => 'Lamppost number', code => 'number', required => 'True' }, + { description => 'Lamppost type', code => 'type', required => 'False', values => + { value => { Yellow => { key => 'modern' }, 'Gas' => { key => 'old' } } } + } + ], +} ); +my $contact2 = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2651, # Edinburgh + category => 'Graffiti Removal', + email => '101', +} ); +ok $contact1, "created test contact 1"; +ok $contact2, "created test contact 2"; + +# test that the various bit of form get filled in and errors correctly +# generated. +foreach my $test ( + { + msg => 'all fields empty', + pc => 'EH99 1SP', + fields => { + title => '', + detail => '', + photo => '', + name => '', + may_show_name => '1', + email => '', + phone => '', + category => 'Street lighting', + password_sign_in => '', + password_register => '', + remember_me => undef, + }, + changes => { + number => '', + type => 'old', + }, + errors => [ + 'Please enter a subject', + 'Please enter some details', + 'This information is required', + 'Please enter your email', + 'Please enter your name', + ], + submit_with => { + title => 'test', + detail => 'test detail', + name => 'Test User', + email => 'testopen311@example.com', + category => 'Street lighting', + number => 27, + }, + extra => [ + { + name => 'number', + value => 27, + description => 'Lamppost number', + }, + { + name => 'type', + value => 'old', + description => 'Lamppost type', + } + ] + }, + ) +{ + subtest "check form errors where $test->{msg}" => sub { + $mech->log_out_ok; + $mech->clear_emails_ok; + + # check that the user does not exist + my $test_email = $test->{submit_with}->{email}; + my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + if ( $user ) { + $user->problems->delete; + $user->comments->delete; + $user->delete; + } + + $mech->get_ok('/around'); + + # submit initial pc form + $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, + "submit location" ); + is_deeply $mech->form_errors, [], "no errors for pc '$test->{pc}'"; + + # click through to the report page + $mech->follow_link_ok( { text => 'skip this step', }, + "follow 'skip this step' link" ); + + # submit the main form + $mech->submit_form_ok( { with_fields => $test->{fields} }, + "submit form" ); + + # check that we got the errors expected + is_deeply $mech->form_errors, $test->{errors}, "check errors"; + + # check that fields have changed as expected + my $new_values = { + %{ $test->{fields} }, # values added to form + %{ $test->{changes} }, # changes we expect + }; + is_deeply $mech->visible_form_values, $new_values, + "values correctly changed"; + + if ( $test->{fields}->{category} eq 'Street lighting' ) { + my $result = scraper { + process 'div#category_meta div select#form_type option', 'option[]' => '@value'; + } + ->scrape( $mech->response ); + + is_deeply $result->{option}, [ qw/old modern/], 'displayed streetlight type select'; + } + + $new_values = { + %{ $test->{fields} }, + %{ $test->{submit_with} }, + }; + $mech->submit_form_ok( { with_fields => $new_values } ); + + $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, 'created user'; + my $prob = $user->problems->first; + ok $prob, 'problem created'; + + is_deeply $prob->extra, $test->{extra}, 'extra open311 data added to problem'; + + $user->problems->delete; + $user->delete; + }; +} + +$contact1->delete; +$contact2->delete; + +done_testing(); diff --git a/t/app/model/problem.t b/t/app/model/problem.t index 4c6be6a8d..ad42c5fdf 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -152,6 +152,111 @@ for my $test ( }; } +my $user = FixMyStreet::App->model('DB::User')->find_or_create( + { + email => 'system_user@example.com' + } +); + +$problem->user( $user ); +$problem->created( DateTime->now()->subtract( days => 1 ) ); +$problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); +$problem->anonymous(1); +$problem->insert; + +my $tz_local = DateTime::TimeZone->new( name => 'local' ); + +for my $test ( + { + desc => 'request older than problem ignored', + lastupdate => '', + 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, + }, + { + desc => 'request newer than problem created', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'open', + status_notes => 'this is an update from the council', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + state => 'confirmed', + mark_fixed => 0, + mark_open => 0, + }, + { + desc => 'update with state of closed fixes problem', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'closed', + status_notes => 'the council have fixed this', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + state => 'fixed', + mark_fixed => 1, + mark_open => 0, + }, + { + desc => 'update with state of open leaves problem as fixed', + lastupdate => '', + request => { + updated_datetime => DateTime::Format::W3CDTF->new()->format_datetime( DateTime->now()->set_time_zone( $tz_local ) ), + status => 'open', + status_notes => 'the council do not think this is fixed', + }, + council => { + name => 'Edinburgh City Council', + }, + created => 1, + start_state => 'fixed', + state => 'fixed', + mark_fixed => 0, + mark_open => 0, + }, +) { + subtest $test->{desc} => sub { + # makes testing easier; + $problem->comments->delete; + $problem->created( DateTime->now()->subtract( days => 1 ) ); + $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); + $problem->state( $test->{start_state} || 'confirmed' ); + $problem->update; + my $w3c = DateTime::Format::W3CDTF->new(); + + my $ret = $problem->update_from_open311_service_request( $test->{request}, $test->{council}, $user ); + is $ret, $test->{created}, 'return value'; + + return unless $test->{created}; + + $problem->discard_changes; + is $problem->lastupdate, $w3c->parse_datetime($test->{request}->{updated_datetime}), 'lastupdate time'; + + my $update = $problem->comments->first; + + ok $update, 'updated created'; + + is $problem->state, $test->{state}, 'problem state'; + + is $update->text, $test->{request}->{status_notes}, 'update text'; + is $update->mark_open, $test->{mark_open}, 'update mark_open flag'; + is $update->mark_fixed, $test->{mark_fixed}, 'update mark_fixed flag'; + }; +} + for my $test ( { state => 'partial', @@ -240,4 +345,8 @@ for my $test ( }; } +$problem->comments->delete; +$problem->delete; +$user->delete; + done_testing(); diff --git a/t/open311.t b/t/open311.t new file mode 100644 index 000000000..f7a8cd815 --- /dev/null +++ b/t/open311.t @@ -0,0 +1,24 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More tests => 4; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311' ); + +my $o = Open311->new(); +ok $o, 'created object'; + +my $err_text = <<EOT +<?xml version="1.0" encoding="utf-8"?><errors><error><code>400</code><description>Service Code cannot be null -- can't proceed with the request.</description></error></errors> +EOT +; + +is $o->_process_error( $err_text ), "400: Service Code cannot be null -- can't proceed with the request.\n", 'error text parsing'; +is $o->_process_error( '503 - service unavailable' ), 'unknown error', 'error text parsing of bad error'; + + diff --git a/t/open311/getupdates.t b/t/open311/getupdates.t new file mode 100644 index 000000000..500ac97d2 --- /dev/null +++ b/t/open311/getupdates.t @@ -0,0 +1,198 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311::GetUpdates' ); +use_ok( 'Open311' ); + +my $user = FixMyStreet::App->model('DB::User')->find_or_create( + { + email => 'system_user@example.com' + } +); + + +my $updates = Open311::GetUpdates->new( system_user => $user ); +ok $updates, 'created object'; + +my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>638344</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +UPDATED_DATETIME +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +</service_requests> +}; + +my $problem_rs = FixMyStreet::App->model('DB::Problem'); +my $problem = $problem_rs->new( + { + postcode => 'EH99 1SP', + latitude => 1, + longitude => 1, + areas => 1, + title => '', + detail => '', + used_map => 1, + user_id => 1, + name => '', + state => 'confirmed', + service => '', + cobrand => 'default', + cobrand_data => '', + user => $user, + created => DateTime->now()->subtract( days => 1 ), + lastupdate => DateTime->now()->subtract( days => 1 ), + anonymous => 1, + external_id => 638344, + } +); + +$problem->insert; + +for my $test ( + { + desc => 'element missing', + updated_datetime => '', + comment_count => 0, + }, + { + desc => 'empty element', + updated_datetime => '<updated_datetime />', + comment_count => 0, + }, + { + desc => 'element with no content', + updated_datetime => '<updated_datetime></updated_datetime>', + comment_count => 0, + }, + { + desc => 'element with old content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', DateTime->now->subtract( days => 3 ) ), + comment_count => 0, + }, + { + desc => 'element with new content', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', DateTime->now ), + comment_count => 1, + }, +) { + subtest $test->{desc} => sub { + $problem->comments->delete; + $problem->lastupdate(DateTime->now()->subtract( days => 1 ) ), + $problem->update; + + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $local_requests_xml } ); + + ok $updates->update_reports( [ 638344 ], $o, { name => 'Test Council' } ); + is $o->test_uri_used, 'http://example.com/requests.xml?jurisdiction_id=mysociety&service_request_id=638344', 'get url'; + + is $problem->comments->count, $test->{comment_count}, 'added a comment'; + }; +} + +$requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> +<service_requests> +<request> +<service_request_id>638344</service_request_id> +<status>open</status> +<status_notes>This is a note.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>UPDATED_DATETIME</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +<request> +<service_request_id>638345</service_request_id> +<status>open</status> +<status_notes>This is a for a different issue.</status_notes> +<service_name>Sidewalk and Curb Issues</service_name> +<service_code>006</service_code> +<description></description> +<agency_responsible></agency_responsible> +<service_notice></service_notice> +<requested_datetime>2010-04-14T06:37:38-08:00</requested_datetime> +<updated_datetime>UPDATED_DATETIME2</updated_datetime> +<expected_datetime>2010-04-15T06:37:38-08:00</expected_datetime> +<lat>37.762221815</lat> +<long>-122.4651145</long> +</request> +</service_requests> +}; + +my $problem2 = $problem_rs->create( + { + postcode => 'EH99 1SP', + latitude => 1, + longitude => 1, + areas => 1, + title => '', + detail => '', + used_map => 1, + user_id => 1, + name => '', + state => 'confirmed', + service => '', + cobrand => 'default', + cobrand_data => '', + user => $user, + created => DateTime->now()->subtract( days => 1 ), + lastupdate => DateTime->now()->subtract( days => 1 ), + anonymous => 1, + external_id => 638345, + } +); + +$problem->comments->delete; +subtest 'update with two requests' => sub { + $problem->comments->delete; + $problem->lastupdate(DateTime->now()->subtract( days => 1 ) ), + + my $date1 = DateTime::Format::W3CDTF->new->format_datetime( DateTime->now() ); + my $date2 = DateTime::Format::W3CDTF->new->format_datetime( DateTime->now->subtract( hours => 1) ); + my $local_requests_xml = $requests_xml; + $local_requests_xml =~ s/UPDATED_DATETIME2/$date2/; + $local_requests_xml =~ s/UPDATED_DATETIME/$date1/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'requests.xml' => $local_requests_xml } ); + + ok $updates->update_reports( [ 638344,638345 ], $o, { name => 'Test Council' } ); + is $o->test_uri_used, 'http://example.com/requests.xml?jurisdiction_id=mysociety&service_request_id=638344%2C638345', 'get url'; + + is $problem->comments->count, 1, 'added a comment to first problem'; + is $problem2->comments->count, 1, 'added a comment to second problem'; +}; + +$problem->comments->delete; +$problem->delete; +$user->comments->delete; +$user->problems->delete; +$user->delete; + +done_testing(); diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t new file mode 100644 index 000000000..bdb7404f9 --- /dev/null +++ b/t/open311/populate-service-list.t @@ -0,0 +1,255 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Test::More; + +use FixMyStreet::App; + +use FindBin; +use lib "$FindBin::Bin/../perllib"; +use lib "$FindBin::Bin/../commonlib/perllib"; + +use_ok( 'Open311::PopulateServiceList' ); +use_ok( 'Open311' ); + + +my $processor = Open311::PopulateServiceList->new( council_list => [] ); +ok $processor, 'created object'; + + + +subtest 'check basic functionality' => sub { + FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->delete(); + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $council = FixMyStreet::App->model('DB::Open311Conf')->new( { + area_id => 1 + } ); + + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + $processor->_current_council( $council ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->count(); + is $contact_count, 3, 'correct number of contacts'; +}; + +subtest 'check non open311 contacts marked as deleted' => sub { + FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->delete(); + + my $contact = FixMyStreet::App->model('DB::Contact')->create( + { + area_id => 1, + email => 'contact@example.com', + category => 'An old category', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $council = FixMyStreet::App->model('DB::Open311Conf')->new( { + area_id => 1 + } ); + + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + $processor->_current_council( $council ); + $processor->process_services( $service_list ); + + my $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->count(); + is $contact_count, 4, 'correct number of contacts'; + + $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1, deleted => 1 } )->count(); + is $contact_count, 1, 'correct number of deleted contacts'; +}; + +subtest 'check email changed if matching category' => sub { + FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->delete(); + + my $contact = FixMyStreet::App->model('DB::Contact')->create( + { + area_id => 1, + email => '009', + category => 'Cans left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + ok $contact, 'contact created'; + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $council = FixMyStreet::App->model('DB::Open311Conf')->new( { + area_id => 1 + } ); + + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + $processor->_current_council( $council ); + $processor->process_services( $service_list ); + + $contact->discard_changes; + is $contact->email, '001', 'email unchanged'; + is $contact->confirmed, 1, 'contact still confirmed'; + is $contact->deleted, 0, 'contact still not deleted'; + + my $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->count(); + is $contact_count, 3, 'correct number of contacts'; +}; + +subtest 'check category name changed if updated' => sub { + FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->delete(); + + my $contact = FixMyStreet::App->model('DB::Contact')->create( + { + area_id => 1, + email => '001', + category => 'Bins left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + ok $contact, 'contact created'; + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $council = FixMyStreet::App->model('DB::Open311Conf')->new( { + area_id => 1 + } ); + + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + $processor->_current_council( $council ); + $processor->process_services( $service_list ); + + $contact->discard_changes; + is $contact->email, '001', 'email unchanged'; + is $contact->category, 'Cans left out 24x7', 'category changed'; + is $contact->confirmed, 1, 'contact still confirmed'; + is $contact->deleted, 0, 'contact still not deleted'; + + my $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->count(); + is $contact_count, 3, 'correct number of contacts'; +}; + +subtest 'check conflicting contacts not changed' => sub { + FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->delete(); + + my $contact = FixMyStreet::App->model('DB::Contact')->create( + { + area_id => 1, + email => 'existing@example.com', + category => 'Cans left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + ok $contact, 'contact created'; + + my $contact2 = FixMyStreet::App->model('DB::Contact')->create( + { + area_id => 1, + email => '001', + category => 'Bins left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + ok $contact2, 'contact created'; + + my $service_list = get_xml_simple_object( get_standard_xml() ); + + my $council = FixMyStreet::App->model('DB::Open311Conf')->new( { + area_id => 1 + } ); + + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + $processor->_current_council( $council ); + $processor->process_services( $service_list ); + + $contact->discard_changes; + is $contact->email, 'existing@example.com', 'first contact email unchanged'; + is $contact->category, 'Cans left out 24x7', 'first contact category unchanged'; + is $contact->confirmed, 1, 'first contact contact still confirmed'; + is $contact->deleted, 0, 'first contact contact still not deleted'; + + $contact2->discard_changes; + is $contact2->email, '001', 'second contact email unchanged'; + is $contact2->category, 'Bins left out 24x7', 'second contact category unchanged'; + is $contact2->confirmed, 1, 'second contact contact still confirmed'; + is $contact2->deleted, 0, 'second contact contact still not deleted'; + + my $contact_count = FixMyStreet::App->model('DB::Contact')->search( { area_id => 1 } )->count(); + is $contact_count, 4, 'correct number of contacts'; +}; + +sub get_standard_xml { + return qq{<?xml version="1.0" encoding="utf-8"?> +<services> + <service> + <service_code>001</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <group>sanitation</group> + </service> + <service> + <service_code>002</service_code> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <group>street</group> + <service_name>Construction plate shifted</service_name> + <description>Metal construction plate covering the street or sidewalk has been moved.</description> + </service> + <service> + <service_code>003</service_code> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <group>street</group> + <service_name>Curb or curb ramp defect</service_name> + <description>Sidewalk curb or ramp has problems such as cracking, missing pieces, holes, and/or chipped curb.</description> + </service> +</services> +}; +} + +sub get_xml_simple_object { + my $xml = shift; + + my $simple = XML::Simple->new(); + my $obj; + + eval { + $obj = $simple->XMLin( $xml ); + }; + + die $@ if $@; + + return $obj; +} + +done_testing(); |