X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=t%2Fcontrollers%2Fhelpers%2Fparse_filter.t;h=bfccf4eda61e6447e9e9929f66ae305f3b069d5f;hb=991369b17d679e2855f4d5086d0b9769dc2ae1aa;hp=198877358062b38c289e03034ef3cb96d9630853;hpb=c8bdac22de4fbd63c974d76a23fe3393cdc551ed;p=kivitendo-erp.git diff --git a/t/controllers/helpers/parse_filter.t b/t/controllers/helpers/parse_filter.t index 198877358..bfccf4eda 100644 --- a/t/controllers/helpers/parse_filter.t +++ b/t/controllers/helpers/parse_filter.t @@ -1,12 +1,14 @@ use lib 't'; -use Test::More tests => 17; +use Test::More tests => 41; use Test::Deep; use Data::Dumper; use_ok 'Support::TestSetup'; use_ok 'SL::Controller::Helper::ParseFilter'; +use SL::DB::OrderItem; + undef *::any; # Test::Deep exports any (for junctions) and MoreCommon exports any (like in List::Moreutils) Support::TestSetup::login(); @@ -35,10 +37,10 @@ test { name => 'Test', whut => 'moof', }, { - query => [ %{{ + query => bag( name => 'Test', whut => 'moof' - }} ], + ), }, 'basic test'; test { @@ -58,7 +60,7 @@ test { } }, { query => [ 'customer.chart.accno' => 'test' ], - with_objects => bag( 'customer', 'chart' ), + with_objects => bag( 'customer', 'customer.chart' ), }, 'nested joins'; test { @@ -82,7 +84,7 @@ test { }, { query => [ 'customer.chart.accno' => { like => '%1200' } ], - with_objects => bag('customer', 'chart' ), + with_objects => bag('customer', 'customer.chart' ), }, 'all together'; @@ -96,11 +98,11 @@ test { }, }, }, { - 'query' => [ %{{ + 'query' => bag( 'invoice.customer.name' => 'test', 'customer.name' => 'test', - }} ], - 'with_objects' => bag( 'invoice', 'customer' ) + ), + 'with_objects' => bag( 'invoice.customer', 'customer', 'invoice' ) }, 'object in more than one relationship'; test { @@ -140,7 +142,7 @@ test { ] }, { 'sellprice:number' => [ '123,4', '2,34', '0,4' ], - 'sellprice_number' => [ '123,4', '2,34', '0,4' ], + 'sellprice_number_' => { '123,4' => 1, '2,34' => 1, '0,4' => 1 }, }, 'laundering with array', target => 'filter'; my %args = ( @@ -177,3 +179,265 @@ test { } }, 'deep laundering, check for laundered hash', target => 'launder', launder_to => { }; +test { + part => { + 'sellprice:number' => '2', + 'sellprice:number::' => 'le', + } +}, { + part => { + 'sellprice:number' => '2', + 'sellprice:number::' => 'le', + } +}, 'laundering of indirect filters does not alter', target => 'filter', launder_to => { }; + +test { + part => { + 'sellprice:number' => '2', + 'sellprice:number::' => 'le', + } +}, { + part => { + 'sellprice_number' => '2', + 'sellprice_number__' => 'le', + } +}, 'laundering of indirect filters', target => 'launder', launder_to => { }; + +test { + part => { + 'sellprice:number' => '2', + 'sellprice:number::' => 'le', + } +}, { + part => { + 'sellprice:number' => '2', + 'sellprice:number::' => 'le', + 'sellprice_number' => '2', + 'sellprice_number__' => 'le', + } +}, 'laundering of indirect filters - inplace', target => 'filter'; + +### bug: sub objects + +test { + order => { + customer => { + 'name:substr::ilike' => 'test', + } + } +}, { + query => [ 'order.customer.name' => { ilike => '%test%' } ], + with_objects => bag('order.customer', 'order'), +}, 'sub objects have to retain their prefix'; + +### class filter dispatch +# +test { + name => 'Test', + whut => 'moof', +}, { + query => bag( + name => 'Test', + whut => 'moof' + ), +}, 'object test simple', class => 'SL::DB::Manager::Part'; + +test { + 'part_type' => 'assembly', +}, { + query => [ + 'part_type', + 'assembly' + ] , +}, 'object test without prefix', class => 'SL::DB::Manager::Part'; + +test { + 'part.part_type' => 'assembly', +}, { + query => [ + 'part.part_type', + 'assembly' + ] +}, 'object test with prefix', class => 'SL::DB::Manager::OrderItem'; + +test { + 'part_type' => [ 'part', 'assembly' ], +}, { + query => [ + 'or', + [ + 'part_type', + 'part', + 'part_type', + 'assembly' + ] + ] +}, 'object test without prefix but complex value', class => 'SL::DB::Manager::Part'; +test { + 'part.part_type' => [ 'part', 'assembly' ], +}, { + query => [ + 'or', + [ + 'part.part_type', + 'part', + 'part.part_type', + 'assembly' + ] + ] +}, 'object test with prefix but complex value', class => 'SL::DB::Manager::OrderItem'; + +test { + description => 'test' +}, { + query => [ description => 'test' ], + with_objects => [ 'order' ] +}, 'with_objects don\'t get clobbered', with_objects => [ 'order' ]; + +test { + customer => { + description => 'test' + } +}, { + query => [ 'customer.description' => 'test' ], + with_objects => [ 'order', 'customer' ] +}, 'with_objects get extended with auto infered objects', with_objects => [ 'order' ]; + +test { + customer => { + description => 'test' + } +}, { + query => [ 'customer.description' => 'test' ], + with_objects => [ 'order', 'customer' ] +}, 'with_objects get extended with auto infered objects with classes', class => 'SL::DB::Manager::Order', with_objects => [ 'order' ]; + +test { + customer => { + description => 'test' + } +}, { + query => [ 'customer.description' => 'test' ], + with_objects => [ 'customer' ] +}, 'with_objects: no duplicates', with_objects => [ 'customer' ]; + +test { + part => { + 'partnumber:substr::ilike' => '1', + }, +}, { + query => [ + 'part.partnumber', { + ilike => '%1%' + } + ], + with_objects => [ 'part' ], +}, 'Regression check: prefixing of fallback filtering in relation with custom filters', class => 'SL::DB::Manager::OrderItem'; +test { + 'description:substr:multi::ilike' => 'term1 term2', +}, { + query => [ + and => [ + description => { ilike => '%term1%' }, + description => { ilike => '%term2%' }, + ] + ] +}, 'simple :multi'; + +test { + part => { + 'all:substr:multi::ilike' => 'term1 term2', + }, +}, { + query => [ + and => [ + or => [ + 'part.partnumber' => { ilike => '%term1%' }, + 'part.description' => { ilike => '%term1%' }, + 'part.ean' => { ilike => '%term1%' }, + ], + or => [ + 'part.partnumber' => { ilike => '%term2%' }, + 'part.description' => { ilike => '%term2%' }, + 'part.ean' => { ilike => '%term2%' }, + ], + ] + ], +}, 'complex :multi with custom dispatch and prefix', class => 'SL::DB::Manager::OrderItem'; + +test { + 'description:substr:multi::ilike' => q|term1 "term2 and half" 'term3 and stuff'|, +}, { + query => [ + and => [ + description => { ilike => '%term1%' }, + description => { ilike => '%term2 and half%' }, + description => { ilike => '%term3 and stuff%' }, + ] + ] +}, ':multi with complex tokenizing'; + +# test tokenizing for custom filters by monkeypatching a custom filter into Part +SL::DB::Manager::Part->add_filter_specs( + test => sub { + my ($key, $value, $prefix, @additional) = @_; + return "$prefix$key" => { @additional, $value }; + } +); + +test { + 'part.test.what' => 2, +}, { + query => [ + 'part.test' => { 'what', 2 }, + ] +}, 'additional tokens', class => 'SL::DB::Manager::OrderItem'; + +test { + 'part.test.what:substr::ilike' => 2, +}, { + query => [ + 'part.test' => { 'what', { ilike => '%2%' } }, + ] +}, 'additional tokens + filters + methods', class => 'SL::DB::Manager::OrderItem'; + +test { + 'orderitems.part.test.what:substr::ilike' => 2, +}, { + query => [ + 'orderitems.part.test' => { 'what', { ilike => '%2%' } }, + ] +}, 'relationship + additional tokens + filters + methods', class => 'SL::DB::Manager::Order'; + +test { + part => { + 'obsolete::lazy_bool_eq' => '0', + }, +}, { + query => [ + or => [ + 'part.obsolete' => undef, + 'part.obsolete' => 0 + ], + ], + with_objects => [ 'part' ], +}, 'complex methods modifying the key'; + + +test { + 'customer:substr::ilike' => ' Meyer' +}, { + query => [ customer => { ilike => '%Meyer%' } ] +}, 'auto trim 1'; + +test { + 'customer:head::ilike' => ' Meyer ' +}, { + query => [ customer => { ilike => 'Meyer%' } ] +}, 'auto trim 2'; + +test { + 'customer:tail::ilike' => "\nMeyer\x{a0}" +}, { + query => [ customer => { ilike => '%Meyer' } ] +}, 'auto trim 2';