aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/Roles/Extra.pm50
-rw-r--r--t/app/model/extra.t25
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';