[], 'fallback' => 'https://fallback.com', ]; $ctx = ['country' => 'US', 'device' => 'desktop']; expect($engine->resolve($rules, $ctx))->toBe('https://fallback.com'); }); it('matches device rule', function () { $engine = new SmartRoutingEngine; $rules = [ 'rules' => [ [ 'id' => 'r1', 'priority' => 1, 'conditions' => [['field' => 'device', 'op' => 'in', 'value' => ['mobile']]], 'match' => 'all', 'target' => 'https://mobile.com', ], ], 'fallback' => 'https://fallback.com', ]; expect($engine->resolve($rules, ['device' => 'mobile']))->toBe('https://mobile.com'); expect($engine->resolve($rules, ['device' => 'desktop']))->toBe('https://fallback.com'); }); it('matches country IN condition', function () { $engine = new SmartRoutingEngine; $rules = [ 'rules' => [ [ 'id' => 'r1', 'priority' => 1, 'conditions' => [['field' => 'country', 'op' => 'in', 'value' => ['DE', 'AT', 'CH']]], 'match' => 'all', 'target' => 'https://dach.com', ], ], 'fallback' => 'https://fallback.com', ]; expect($engine->resolve($rules, ['country' => 'DE']))->toBe('https://dach.com'); expect($engine->resolve($rules, ['country' => 'US']))->toBe('https://fallback.com'); }); it('matches ANY condition with mixed fields', function () { $engine = new SmartRoutingEngine; $rules = [ 'rules' => [ [ 'id' => 'r1', 'priority' => 1, 'conditions' => [ ['field' => 'country', 'op' => 'in', 'value' => ['DE']], ['field' => 'device', 'op' => 'in', 'value' => ['mobile']], ], 'match' => 'any', 'target' => 'https://any.com', ], ], 'fallback' => 'https://fallback.com', ]; // Either DE or mobile matches expect($engine->resolve($rules, ['country' => 'DE', 'device' => 'desktop']))->toBe('https://any.com'); expect($engine->resolve($rules, ['country' => 'US', 'device' => 'mobile']))->toBe('https://any.com'); // Neither matches expect($engine->resolve($rules, ['country' => 'US', 'device' => 'desktop']))->toBe('https://fallback.com'); });