Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions tests/EncryptedFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ protected function getCassetteName(): string
return 'encrypted_files.yml';
}

protected function setUp(): void
{
parent::setUp();
// Guard against php-vcr silently making a real sandbox call (and
// re-recording the cassette) if a request doesn't exactly match what
// is on tape: force a hard failure instead.
\VCR\VCR::configure()->setMode(\VCR\VCR::MODE_NONE);
}

protected function tearDown(): void
{
\VCR\VCR::configure()->setMode(\VCR\VCR::MODE_NEW_EPISODES);
parent::tearDown();
}

public function testAllWithPagination()
{
$encryptedFilesDocument = \Didww\Item\EncryptedFile::all(
Expand Down Expand Up @@ -57,4 +72,93 @@ public function testUploadMethodSignature()
$this->assertEquals('description', $params[2]->getName());
$this->assertTrue($params[2]->isOptional());
}

private function buildDataFiles(string $delimiter, array $files, array $fields): string
{
$reflection = new \ReflectionMethod(\Didww\Item\EncryptedFile::class, 'buildDataFiles');

return $reflection->invoke(null, $delimiter, $files, $fields);
Comment on lines +78 to +80
}

public function testBuildDataFilesMultipartStructureWithDescription()
{
$body = $this->buildDataFiles(
'-------------TESTBOUNDARY0001',
[['name' => 'encrypted_files[file]', 'data' => 'plain file bytes']],
[
['name' => 'encrypted_files[encryption_fingerprint]', 'data' => 'fp-abc123'],
['name' => 'encrypted_files[description]', 'data' => 'test upload description'],
]
);

$this->assertEquals(
"---------------TESTBOUNDARY0001\r\n"
."Content-Disposition: form-data; name=\"encrypted_files[encryption_fingerprint]\"\r\n\r\n"
."fp-abc123\r\n"
."---------------TESTBOUNDARY0001\r\n"
."Content-Disposition: form-data; name=\"encrypted_files[description]\"\r\n\r\n"
."test upload description\r\n"
."---------------TESTBOUNDARY0001\r\n"
."Content-Disposition: form-data; name=\"encrypted_files[file]\"; filename=\"file.enc\"\r\n"
."Content-Type: application/octet-stream\r\n"
."Content-Transfer-Encoding: binary\r\n\r\n"
."plain file bytes\r\n"
.'---------------TESTBOUNDARY0001--'."\r\n",
$body
);
}

public function testBuildDataFilesMultipartStructureWithoutDescription()
{
$body = $this->buildDataFiles(
'-------------TESTBOUNDARY0002',
[['name' => 'encrypted_files[file]', 'data' => 'bad content']],
[['name' => 'encrypted_files[encryption_fingerprint]', 'data' => 'fp-error-999']]
);

// No description field part; only fingerprint + the single file part.
$this->assertEquals(
"---------------TESTBOUNDARY0002\r\n"
."Content-Disposition: form-data; name=\"encrypted_files[encryption_fingerprint]\"\r\n\r\n"
."fp-error-999\r\n"
."---------------TESTBOUNDARY0002\r\n"
."Content-Disposition: form-data; name=\"encrypted_files[file]\"; filename=\"file.enc\"\r\n"
."Content-Type: application/octet-stream\r\n"
."Content-Transfer-Encoding: binary\r\n\r\n"
."bad content\r\n"
.'---------------TESTBOUNDARY0002--'."\r\n",
$body
);
}

public function testUploadSendsExpectedMultipartRequestAndParsesSuccessResponse()
{
$result = \Didww\Item\EncryptedFile::upload(
'fp-abc123',
'plain file bytes',
'test upload description',
'TESTBOUNDARY0001'
);

$this->assertEquals(201, $result->getResponseCode());
$this->assertTrue($result->success());
$this->assertFalse($result->hasErrors());
$this->assertEquals('aaaa1111-2222-3333-4444-555566667777', $result->getId());
}

public function testUploadSendsExpectedMultipartRequestAndParsesErrorResponse()
{
$result = \Didww\Item\EncryptedFile::upload(
'fp-error-999',
'bad content',
null,
'TESTBOUNDARY0002'
);

$this->assertEquals(422, $result->getResponseCode());
$this->assertFalse($result->success());
$this->assertTrue($result->hasErrors());
$this->assertNull($result->getId());
$this->assertEquals([['title' => 'Invalid fingerprint']], $result->getErrors());
}
}
47 changes: 47 additions & 0 deletions tests/SupportingDocumentTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ protected function getCassetteName(): string
return 'supporting_document_templates.yml';
}

protected function setUp(): void
{
parent::setUp();
// Guard against php-vcr silently making a real sandbox call (and
// re-recording the cassette) if a request doesn't exactly match what
// is on tape: force a hard failure instead.
\VCR\VCR::configure()->setMode(\VCR\VCR::MODE_NONE);
}

protected function tearDown(): void
{
\VCR\VCR::configure()->setMode(\VCR\VCR::MODE_NEW_EPISODES);
parent::tearDown();
}

public function testAllWithIncludesAndPagination()
{
$supportingDocumentTemplatesDocument = \Didww\Item\SupportingDocumentTemplate::all(
Expand All @@ -31,4 +46,36 @@ public function testAllWithIncludesAndPagination()
$this->assertEquals('Belgium Registration Form', $second->getName());
$this->assertTrue($second->getPermanent());
}

public function testDownload()
{
$template = \Didww\Item\SupportingDocumentTemplate::build(
'206ccec2-1166-461f-9f58-3a56823db548',
['url' => 'https://sandbox-api.didww.com/storage/public/w7f2irbo819la7vd7up7u67pkmkn']
);

$destFile = tempnam(sys_get_temp_dir(), 'didww_test_');
$result = $template->download($destFile);

$this->assertTrue($result);
$this->assertEquals('Generic LOI template contents', file_get_contents($destFile));
unlink($destFile);
}

public function testDownloadToResourceHandle()
{
$template = \Didww\Item\SupportingDocumentTemplate::build(
'206ccec2-1166-461f-9f58-3a56823db548',
['url' => 'https://sandbox-api.didww.com/storage/public/w7f2irbo819la7vd7up7u67pkmkn']
);

$destFile = tempnam(sys_get_temp_dir(), 'didww_test_');
$handle = fopen($destFile, 'w');
$result = $template->download($handle);
fclose($handle);

$this->assertTrue($result);
$this->assertEquals('Generic LOI template contents', file_get_contents($destFile));
unlink($destFile);
}
}
38 changes: 38 additions & 0 deletions tests/fixtures/encrypted_files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,41 @@
Access-Control-Allow-Methods: 'GET, POST, DELETE, PUT, PATCH, OPTIONS'
Access-Control-Allow-Credentials: 'true'
body: '{"data":{"id":"371eafbd-ac6a-485c-aadf-9e3c5da37eb4","type":"encrypted_files","attributes":{"description":null,"expires_at":"2021-04-06T16:38:34.437Z"}},"meta":{"api_version":"2026-04-16"}}'
-
request:
method: POST
url: 'https://sandbox-api.didww.com/v3/encrypted_files'
headers:
Api-Key: PLACEYOURAPIKEYHERE
X-DIDWW-API-Version: '2026-04-16'
Content-Type: 'multipart/form-data; boundary=-------------TESTBOUNDARY0001'
Content-Length: '501'
Accept: application/json
Comment on lines +187 to +195
body: "---------------TESTBOUNDARY0001\r\nContent-Disposition: form-data; name=\"encrypted_files[encryption_fingerprint]\"\r\n\r\nfp-abc123\r\n---------------TESTBOUNDARY0001\r\nContent-Disposition: form-data; name=\"encrypted_files[description]\"\r\n\r\ntest upload description\r\n---------------TESTBOUNDARY0001\r\nContent-Disposition: form-data; name=\"encrypted_files[file]\"; filename=\"file.enc\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\nplain file bytes\r\n---------------TESTBOUNDARY0001--\r\n"
response:
status:
http_version: '1.1'
code: '201'
message: Created
headers:
Content-Type: application/vnd.api+json
body: '{"data":{"id":"aaaa1111-2222-3333-4444-555566667777","type":"encrypted_files","attributes":{"description":"test upload description","expires_at":"2026-04-22T10:00:00.000Z"}},"meta":{"api_version":"2026-04-16"}}'
-
request:
method: POST
url: 'https://sandbox-api.didww.com/v3/encrypted_files'
headers:
Api-Key: PLACEYOURAPIKEYHERE
X-DIDWW-API-Version: '2026-04-16'
Content-Type: 'multipart/form-data; boundary=-------------TESTBOUNDARY0002'
Content-Length: '370'
Accept: application/json
body: "---------------TESTBOUNDARY0002\r\nContent-Disposition: form-data; name=\"encrypted_files[encryption_fingerprint]\"\r\n\r\nfp-error-999\r\n---------------TESTBOUNDARY0002\r\nContent-Disposition: form-data; name=\"encrypted_files[file]\"; filename=\"file.enc\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\nbad content\r\n---------------TESTBOUNDARY0002--\r\n"
response:
status:
http_version: '1.1'
code: '422'
message: 'Unprocessable Entity'
headers:
Content-Type: application/vnd.api+json
body: '{"errors":[{"title":"Invalid fingerprint"}]}'
12 changes: 12 additions & 0 deletions tests/fixtures/supporting_document_templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,15 @@
Access-Control-Allow-Methods: 'GET, POST, DELETE, PUT, PATCH, OPTIONS'
Access-Control-Allow-Credentials: 'true'
body: '{"data":[{"id":"206ccec2-1166-461f-9f58-3a56823db548","type":"supporting_document_templates","attributes":{"name":"Generic LOI","permanent":false,"url":"https://sandbox-api.didww.com/storage/public/w7f2irbo819la7vd7up7u67pkmkn"}},{"id":"fd38c86d-b69b-4ca8-b73c-286a3b93d107","type":"supporting_document_templates","attributes":{"name":"Belgium Registration Form","permanent":true,"url":"https://sandbox-api.didww.com/storage/public/e8lziulj68xetfa5ed6na3g7q7ra"}},{"id":"4199435f-646e-4e9d-a143-8f3b972b10c5","type":"supporting_document_templates","attributes":{"name":"Germany Special Registration Form","permanent":true,"url":"https://sandbox-api.didww.com/storage/public/4rghqnqtba0fa7mbdgig086xej1e"}},{"id":"94be4d74-c968-4d81-91c5-2d11b4e45328","type":"supporting_document_templates","attributes":{"name":"LOI Example","permanent":false,"url":"https://sandbox-api.didww.com/storage/public/xptvgb8derrz0ru95wr9oi68g9tg"}},{"id":"eb810289-8620-44e1-982d-13e6cee70404","type":"supporting_document_templates","attributes":{"name":"TestPermanDoc","permanent":true,"url":"https://sandbox-api.didww.com/storage/public/owwqi77007ks4qx198b7su3eukg6"}}],"meta":{"total_records":30,"api_version":"2026-04-16"},"links":{"first":"https://sandbox-api.didww.com/v3/supporting_document_templates?page%5Bnumber%5D=1&page%5Bsize%5D=5","next":"https://sandbox-api.didww.com/v3/supporting_document_templates?page%5Bnumber%5D=2&page%5Bsize%5D=5","last":"https://sandbox-api.didww.com/v3/supporting_document_templates?page%5Bnumber%5D=6&page%5Bsize%5D=5"}}'
-
request:
method: GET
url: 'https://sandbox-api.didww.com/storage/public/w7f2irbo819la7vd7up7u67pkmkn'
response:
Comment on lines +41 to +44
status:
http_version: '1.1'
code: '200'
message: OK
headers:
Content-Type: application/octet-stream
body: 'Generic LOI template contents'
Loading