$count, 'fetch' => function ($offset, $limit) use (&$calls, $prefix, $count) { $calls[] = [$prefix, $offset, $limit]; return array_map(fn ($i) => ['title' => $prefix.$i, 'url' => '/'.$prefix.$i], array_slice(range(1, $count), $offset, $limit)); }]; }; }; $sources = ['Páginas' => $factory('p', 3), 'Oportunidades' => $factory('o', 7), 'Documentos' => $factory('d', 2)]; $service = new FederatedSearch; $first = $service->page($sources, 1); $this->assertSame(['p1', 'p2', 'p3', 'o1', 'o2'], array_column($first['data'], 'title')); $this->assertSame(['Páginas', 'Páginas', 'Páginas', 'Oportunidades', 'Oportunidades'], array_column($first['data'], 'category')); $this->assertSame(12, $first['total']); $this->assertSame(3, $first['last_page']); $calls = []; $second = $service->page($sources, 2); $this->assertSame(['o3', 'o4', 'o5', 'o6', 'o7'], array_column($second['data'], 'title')); $this->assertSame([['p', 0, 5], ['o', 0, 5], ['d', 0, 5], ['o', 5, 5]], $calls); $third = $service->page($sources, 99); $this->assertSame(3, $third['current_page']); $this->assertSame(['d1', 'd2'], array_column($third['data'], 'title')); } public function test_more_relevant_titles_appear_first_across_sources(): void { $factories = [ 'Serviços' => fn () => ['count' => 1, 'fetch' => fn ($offset, $limit) => array_slice([['title' => 'Informação', 'url' => '/info', 'score' => 10]], $offset, $limit)], 'Sectores' => fn () => ['count' => 1, 'fetch' => fn ($offset, $limit) => array_slice([['title' => 'Sectores', 'url' => '/sectores', 'score' => 100]], $offset, $limit)], ]; $result = (new FederatedSearch)->page($factories, 1, 5, fn ($item) => $item['score']); $this->assertSame(['Sectores', 'Informação'], array_column($result['data'], 'title')); } }