diff options
-rw-r--r-- | perllib/FixMyStreet/Roles/Extra.pm | 50 | ||||
-rw-r--r-- | t/app/model/extra.t | 25 |
2 files changed, 75 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/Roles/Extra.pm b/perllib/FixMyStreet/Roles/Extra.pm index 445f6d91c..883ac2fd7 100644 --- a/perllib/FixMyStreet/Roles/Extra.pm +++ b/perllib/FixMyStreet/Roles/Extra.pm @@ -135,6 +135,56 @@ sub push_extra_fields { $self->extra({ %$extra, $META_FIELD => [ @$existing, @fields ] }); } +=head2 update_extra_field + + $problem->update_extra_field( { ... } ); + +Given an extra field, will replace one with the same code in the +existing list of fields, or add to the end if not present. + +=cut + +sub update_extra_field { + my ($self, $field) = @_; + + # Can operate on list that uses code (Contact) or name (Problem), + # but make sure we have one of them + my $attr; + $attr = 'code' if $field->{code}; + $attr = 'name' if $field->{name}; + die unless $attr; + + my $existing = $self->get_extra_fields; + my $found; + foreach (@$existing) { + if ($_->{$attr} eq $field->{$attr}) { + $_ = $field; + $found = 1; + } + } + if (!$found) { + push @$existing, $field; + } + + $self->set_extra_fields(@$existing); +} + +=head2 remove_extra_field + + $problem->remove_extra_field( $code ); + +Given an extra field code, will remove it from the list of fields. + +=cut + +sub remove_extra_field { + my ($self, $code) = @_; + + my @fields = @{ $self->get_extra_fields() }; + @fields = grep { ($_->{code} || $_->{name}) ne $code } @fields; + $self->set_extra_fields(@fields); +} + =head1 HELPER METHODS For internal use mostly. diff --git a/t/app/model/extra.t b/t/app/model/extra.t index 55accb086..970efc465 100644 --- a/t/app/model/extra.t +++ b/t/app/model/extra.t @@ -79,6 +79,31 @@ subtest 'Default hash layout' => sub { is_deeply $contact->extra, { _fields => \@fields }, '(sanity check layout)'; }; + subtest 'updating extra field' => sub { + my $contact = get_test_contact(); + my @fields = ( { code => 'ABC', description => 'ABC', variable => 'false', }, { code => 'DEF', description => 'DEF', variable => 'true' } ); + $contact->set_extra_fields(@fields); + is_deeply $contact->get_extra_fields, \@fields, 'extra fields set...'; + my $new_field = { code => 'ABC', description => 'XYZ', variable => 'false' }; + $contact->update_extra_field($new_field); + $fields[0] = $new_field; + is_deeply $contact->get_extra_fields, \@fields, 'extra fields changed'; + $new_field = { code => 'GHI', description => 'GHI', variable => 'false' }; + $contact->update_extra_field($new_field); + push @fields, $new_field; + is_deeply $contact->get_extra_fields, \@fields, 'extra fields changed'; + }; + + subtest 'removing extra field' => sub { + my $contact = get_test_contact(); + my @fields = ( { code => 'ABC', description => 'ABC', variable => 'false', }, { code => 'DEF', description => 'DEF', variable => 'true' } ); + $contact->set_extra_fields(@fields); + is_deeply $contact->get_extra_fields, \@fields, 'extra fields set...'; + $contact->remove_extra_field('DEF'); + pop @fields; + is_deeply $contact->get_extra_fields(), \@fields, 'extra field removed'; + }; + subtest 'metadata' => sub { my $contact = get_test_contact(); is_deeply $contact->get_extra_metadata, {}, 'No extra metadata'; |