TT#46187 Use value in "remove" PATCH op as filter

Change-Id: Ic04917b1e90750e4517d45082cdab7f7f2bcf534
changes/79/24679/8
Irina Peshinskaya 7 years ago
parent aeb5cd9c28
commit 7e3a1d1cd2

@ -576,7 +576,7 @@ sub require_valid_patch {
my $valid_ops = {
'replace' => { 'path' => 1, 'value' => 1 },
'copy' => { 'from' => 1, 'path' => 1 },
'remove' => { 'path' => 1 },
'remove' => { 'path' => 1, 'value' => 0, 'index' => 0 },# 0 means optional
'add' => { 'path' => 1, 'value' => 1, mode => {
required => 0,
allowed_values => [qw/append/],
@ -811,6 +811,53 @@ sub process_patch_description {
} else {
push @$patch_diff, map {{"op" => "add", "path" => $op->{path}.'/-', "value" => $_}} ref $op->{value} eq 'ARRAY' ? @{$op->{value}} : ($op->{value});
}
} elsif ($op->{op} eq 'remove' && $op->{value}) {
splice @$patch, $op_iterator, 1;
my $remove_index = $op->{index};#no default value, undefined means "remove all"
my $found_count = 0;
my $removal_done = 0;
my $values_to_remove;
if (ref $op->{value} eq 'ARRAY') {
undef $remove_index;#??? - this is according to AC, but during meeting it sounded different
$values_to_remove = $op->{value};
} else {
$values_to_remove = [$op->{value}];
}
my $value_current = JSON::Pointer->get($entity, $op->{path});
foreach my $value_to_remove (@$values_to_remove) {
#we are not able to request full array removal with exact value
if (ref $value_current eq 'ARRAY') {
for (my $i=0; $i < @$value_current; $i++) {
# 0 if different, 1 if equal
if (compare($value_current->[$i], $value_to_remove)) {
if ( defined $remove_index ) {
if ($found_count == $remove_index) {
#if we want to use patch info to try to make clear changes, we shouldn't use replace
#from the other pov, if we requested 10000 removals, we will have 10000 new op entries
push @$patch_diff, {"op" => "remove", "path" => $op->{path}.'/'.$i };
$removal_done = 1;
last;
} else {
$found_count++;
}
} else {
push @$patch_diff, {"op" => "remove", "path" => $op->{path}.'/'.$i };
}
}
}
if ($removal_done) {
last;
}
} else { #current value is not an array
if (compare($value_current, $value_to_remove)) {
push @$patch_diff, {"op" => "remove", "path" => $op->{path} };
}
}
}
#we went through all the filter values and still didn't find enough elements to satisfy requested index
if ($remove_index && $found_count < $remove_index ) {
die("delete index $remove_index out of bounds");
}
}
}
push @$patch, @$patch_diff;

@ -45,6 +45,8 @@ my @apis = qw/subscriber domain peeringserver customer profile pbxdevice pbxfiel
foreach my $api (@apis){
my $preferences_old;
my $preferences_put;
my $preferences_patch;
my $res;
my $index = $api.'_id';
my ($preferences) = {'uri' => '/api/'.$api.'preferences/'.$test_machine->DATA_ITEM->{$index}};
(undef, $preferences_old) = $test_machine->check_item_get($preferences->{uri});
@ -86,7 +88,11 @@ foreach my $api (@apis){
}
if($value && 'no_process' ne $value){
if($preference->{max_occur} > 0 ){
$preferences->{content}->{$preference_name} = 1 < $preference->{max_occur} ? [$value] : $value ;
if ($preference->{max_occur} eq '1') {
$preferences->{content}->{$preference_name} = $value;
} else {
$preferences->{content}->{$preference_name} = [$value];
}
}
}else{
#print "Undefined value for preference: $api:$preference_name;\n";
@ -96,7 +102,41 @@ foreach my $api (@apis){
#(undef, $preferences_put->{content}) = $test_machine->request_put($preferences->{content},$preferences->{uri});
#we don't check read_only flag when update preferences?
(undef, $preferences_put->{content}) = $test_machine->check_put2get({data_in=>$preferences->{content},uri=>$preferences->{uri}},undef, { skip_compare => 1 });
(undef, $preferences_put->{content}) = $test_machine->request_put($preferences_old,$preferences->{uri});
(undef, $preferences_patch->{content}) = $test_machine->check_patch2get({location => $preferences->{uri}} );
if ($api eq 'subscriber') {
diag("test extended patch");
my $preferences_new;
my $addmulti_value = ['111','222','222','333'];
my $preferences_patch_op = [
{'op' => 'add', 'path' => '/allowed_clis', value => $addmulti_value, mode => 'append' },
];
($res, $preferences_put->{content}) = $test_machine->request_patch($preferences_patch_op,$preferences->{uri});
$test_machine->http_code_msg(200, "check extended patch result: add multi to absent", $res, $preferences_put->{content});
(undef, $preferences_new->{content}) = $test_machine->check_item_get($preferences->{uri});
is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-4..-1]], $addmulti_value, "check patched allowed_clis: add multi to absent");
$addmulti_value = ['222','222','222','555','666'];
$preferences_patch_op = [
{'op' => 'add', 'path' => '/allowed_clis', value => $addmulti_value, mode => 'append' },
];
($res, $preferences_put->{content}) = $test_machine->request_patch($preferences_patch_op,$preferences->{uri});
$test_machine->http_code_msg(200, "check extended patch result: add multi to existing", $res, $preferences_put->{content});
(undef, $preferences_new->{content}) = $test_machine->check_item_get($preferences->{uri});
is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-5..-1]], $addmulti_value, "check patched allowed_clis: add multi to existing");
$preferences_patch_op = [
{'op' => 'remove', 'path' => '/allowed_clis', value => '222', 'index' => 2 },
];
($res, $preferences_put->{content}) = $test_machine->request_patch($preferences_patch_op,$preferences->{uri});
$test_machine->http_code_msg(200, "check extended patch result: remove by value", $res, $preferences_put->{content});
(undef, $preferences_new->{content}) = $test_machine->check_item_get($preferences->{uri});
is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-8..-1]], ['111','222','222','333','222','222','555','666'], "check patched allowed_clis: remove by value.");
}
($res, $preferences_put->{content}) = $test_machine->request_put($preferences_old,$preferences->{uri});
$test_machine->http_code_msg(200, "check return old values", $res, $preferences_put->{content});
}
$test_machine->clear_test_data_all();

Loading…
Cancel
Save