baseUri = $baseUri; } public function client(): DavClient { return (new DavClient)->setBaseUri($this->baseUri); } public function fake() { $this->http = Http::fake(function ($request) { return $this->responses[$this->current++]['response']; }); return $this; } public function assert() { Http::assertSentInOrder(array_map(function ($data) { return function (Request $request, Response $response) use ($data) { $srequest = $request->method().' '.$request->url(); $this->assertEquals($data['method'], $request->method(), "method for request $srequest differs"); $this->assertEquals($data['uri'], $request->url(), "uri for request $srequest differs"); if (isset($data['body'])) { $this->assertEquals($data['body'], $request->body(), "body for request $srequest differs"); } if (isset($data['headers'])) { foreach ($data['headers'] as $key => $value) { $this->assertArrayHasKey($key, $request->headers(), "header $key for request $srequest is missing"); $this->assertEquals($value, $request->header($key), "header $key for request $srequest differs"); } } return true; }; }, $this->responses)); } public function addressBookBaseUri() { return $this->userPrincipal('https://test') ->addressbookHome() ->resourceTypeAddressBook() ->optionsOk('https://test/dav/addressbooks/user@test.com/contacts/'); } public function capabilities() { return $this->supportedReportSet() ->supportedAddressData(); } public function addResponse(string $uri, PromiseInterface $response, ?string $body = null, string $method = 'PROPFIND', ?array $headers = null) { $this->responses[] = [ 'uri' => $uri, 'response' => $response, 'method' => $method, 'body' => $body, 'headers' => $headers, ]; return $this; } public function serviceUrl() { return $this->addResponse('https://test/.well-known/carddav', Http::response(null, 301, ['Location' => $this->baseUri.'/dav/']), null, 'GET'); } public function nonStandardServiceUrl() { return $this->addResponse('https://test/.well-known/carddav', Http::response(null, 301, ['Location' => '/dav/']), null, 'PROPFIND'); } public function optionsOk(string $url = 'https://test/dav/') { return $this->addResponse($url, Http::response(null, 200, ['Dav' => '1, 3, addressbook']), null, 'OPTIONS'); } public function optionsFail() { return $this->addResponse('https://test/dav/', Http::response(null, 200, ['Dav' => 'bad']), null, 'OPTIONS'); } public function userPrincipal(string $url = 'https://test/dav/') { return $this->addResponse($url, Http::response($this->multistatusHeader(). ''. '/dav/'. ''. ''. ''. '/dav/principals/user@test.com/'. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function userPrincipalEmpty() { return $this->addResponse('https://test/dav/', Http::response($this->multistatusHeader(). ''. '/dav/'. ''. ''. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function addressbookHome() { return $this->addResponse('https://test/dav/principals/user@test.com/', Http::response($this->multistatusHeader(). ''. '/dav/principals/user@test.com/'. ''. ''. ''. '/dav/addressbooks/user@test.com/'. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function addressbookEmpty() { return $this->addResponse('https://test/dav/principals/user@test.com/', Http::response($this->multistatusHeader(). ''. '/dav/principals/user@test.com/'. ''. ''. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function resourceTypeAddressBook(string $uri = 'https://test/dav/addressbooks/user@test.com/') { return $this->addResponse($uri, Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. ''. ''. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function resourceTypeHomeOnly() { return $this->addResponse('https://test/dav/addressbooks/user@test.com/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/'. ''. ''. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function resourceTypeEmpty() { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function supportedReportSet(array $reportSet = ['card:addressbook-multiget', 'card:addressbook-query', 'd:sync-collection']) { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. ''. implode('', array_map(function ($report) { return "<$report/>"; }, $reportSet)). ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function supportedAddressData(array $list = ['card:address-data-type content-type="text/vcard" version="4.0"']) { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. ''. implode('', array_map(function ($item) { return "<$item/>"; }, $list)). ''. ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function displayName(string $name = 'Test') { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. "$name". ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function getSynctoken(string $synctoken = '"test"') { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. '/dav/addressbooks/user@test.com/contacts/'. ''. ''. "$synctoken". ''. 'HTTP/1.1 200 OK'. ''. ''. '')); } public function getSyncCollection(string $synctoken = '"token"', string $etag = '"etag"', string $uuid = 'uuid') { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. "https://test/dav/addressbooks/user@test.com/contacts/$uuid". ''. ''. "$etag". 'text/vcard'. ''. 'HTTP/1.1 200 OK'. ''. ''. "$synctoken". ''), null, 'REPORT'); } public function addressMultiGet($etag, $card, $url) { return $this->addResponse('https://test/dav/addressbooks/user@test.com/contacts/', Http::response($this->multistatusHeader(). ''. 'https://test/dav/addressbooks/user@test.com/contacts/uuid'. ''. ''. "$etag". "$card". ''. 'HTTP/1.1 200 OK'. ''. ''. ''), ''."\n". ''. ''. ''. ''. ''. "$url". "\n", 'REPORT'); } public static function multistatusHeader() { return ''; } }