provider([$this->hotelsResponse()]); $hotels = $provider->getAll(); $this->assertEquals([163959, 11223], array_keys($hotels)); $this->assertEquals('Sportclub Jenatsch', $hotels[163959]->getName()); // MyE&P reports the BusProNet idbuspro as its id, and busProId is the only property // that holds it now - the model used to carry the same number twice $this->assertEquals(163959, $hotels[163959]->getBusProId()); $this->assertEquals('4711', $hotels[163959]->getCostUnit()); $this->assertEquals('CH', $hotels[163959]->getCountry()); $this->assertEquals('ch', $hotels[163959]->getCountryCode()); } public function testAnUnmappableCountryCodeBecomesNull(): void { $provider = $this->provider([$this->hotelsResponse()]); // "AUT" is what MyE&P could not map; it must not reach the two character column $this->assertNull($provider->getAll()[11223]->getCountryCode()); $this->assertEquals('AUT', $provider->getAll()[11223]->getCountry()); } public function testAFailingRequestServesTheLastKnownHotels(): void { $pool = new ArrayAdapter(); $provider = $this->provider([$this->hotelsResponse()], $pool); $this->assertCount(2, $provider->getAll()); // the fresh key is gone but the last known good one is not, which is the whole // point: an outage must not empty the destination form's hotel list $pool->deleteItem('myep_hotels'); $failing = $this->provider([new MockResponse('', ['http_code' => 503])], $pool); $this->assertCount(2, $failing->getAll()); } public function testAFailingRequestWithoutAnyCachedDataYieldsNothing(): void { $provider = $this->provider([new MockResponse('', ['http_code' => 503])]); $this->assertEquals([], $provider->getAll()); } public function testFindByCodeMatchesOnEitherEnd(): void { $provider = $this->provider([$this->hotelsResponse()]); $this->assertCount(1, $provider->findByCode('LPJ')); $this->assertCount(1, $provider->findByCode('GR')); $this->assertCount(0, $provider->findByCode('XXX')); } public function testAHotelWithoutACodeIsSkippedByFindByCode(): void { $provider = $this->provider([new MockResponse(json_encode([ ['id' => 1, 'name' => 'Ohne Code'], ]))]); $this->assertEquals([], $provider->findByCode('SSL')); } private function hotelsResponse(): MockResponse { return new MockResponse(json_encode([ [ 'id' => 163959, 'code' => 'LPJGR', 'name' => 'Sportclub Jenatsch', 'city' => 'Lenzerheide', 'street' => 'Voa Principala 1', 'phone' => '+41 81 000 00 00', 'costUnit' => '4711', 'country' => 'CH', 'countryCode' => 'ch', ], [ 'id' => 11223, 'code' => 'SSLAT', 'name' => 'Haus Sonnenschein', 'country' => 'AUT', 'countryCode' => 'AUT', ], ])); } /** * @param list $responses */ private function provider(array $responses, ?ArrayAdapter $pool = null): HotelDataProvider { $pool ??= new ArrayAdapter(); $logger = new NullLogger(); $httpClient = new MockHttpClient(array_merge( [new MockResponse(json_encode(['access_token' => 'token', 'expires_in' => 600]))], $responses, )); $tokens = new AccessTokenProvider($httpClient, new ArrayAdapter(), $logger, [ 'client_id' => 'id', 'client_secret' => 'secret', ]); return new HotelDataProvider( new ApiClient($httpClient, $tokens, $logger), new ResponseMapper($logger), new StaleWhileErrorCache($pool, $logger), ); } }