Skip to content

Commit

Permalink
Add ISO tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ericwang401 committed Mar 4, 2024
1 parent 83314c9 commit 570dabc
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 40 deletions.
3 changes: 2 additions & 1 deletion app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace Convoy\Http\Requests\Admin\Nodes\Isos;

use Convoy\Models\ISO;
use Convoy\Http\Requests\BaseApiRequest;
use Convoy\Models\ISO;

class UpdateIsoRequest extends BaseApiRequest
{
Expand All @@ -16,4 +16,5 @@ public function rules(): array
'hidden' => $rules['hidden'],
];
}

}
77 changes: 41 additions & 36 deletions app/Repositories/Proxmox/Node/ProxmoxStorageRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@

namespace Convoy\Repositories\Proxmox\Node;

use Convoy\Models\Node;
use Carbon\CarbonImmutable;
use Illuminate\Support\Arr;
use Webmozart\Assert\Assert;
use Convoy\Data\Helpers\ChecksumData;
use Convoy\Data\Node\Storage\IsoData;
use Convoy\Data\Node\Storage\FileMetaData;
use Convoy\Data\Node\Storage\IsoData;
use Convoy\Enums\Node\Storage\ContentType;
use Convoy\Repositories\Proxmox\ProxmoxRepository;
use Convoy\Exceptions\Service\Node\IsoLibrary\InvalidIsoLinkException;
use Convoy\Models\Node;
use Convoy\Repositories\Proxmox\ProxmoxRepository;
use Illuminate\Support\Arr;
use Spatie\LaravelData\DataCollection;
use Webmozart\Assert\Assert;

class ProxmoxStorageRepository extends ProxmoxRepository
{
public function download(ContentType $contentType, string $fileName, string $link, ?bool $verifyCertificates = true, ?ChecksumData $checksumData = null)
public function download(
ContentType $contentType, string $fileName, string $link,
?bool $verifyCertificates = true,
?ChecksumData $checksumData = null,
)
{
Assert::isInstanceOf($this->node, Node::class);
Assert::regex($link, '/^(http|https):\/\//');
Expand All @@ -33,12 +38,12 @@ public function download(ContentType $contentType, string $fileName, string $lin
}

$response = $this->getHttpClient()
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
])
->post('/api2/json/nodes/{node}/storage/{storage}/download-url', $payload)
->json();
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
])
->post('/api2/json/nodes/{node}/storage/{storage}/download-url', $payload)
->json();

return $this->getData($response);
}
Expand All @@ -48,28 +53,28 @@ public function deleteFile(ContentType $contentType, string $fileName)
Assert::isInstanceOf($this->node, Node::class);

$response = $this->getHttpClient()
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
'file' => "{$this->node->iso_storage}:$contentType->value/$fileName",
])
->delete('/api2/json/nodes/{node}/storage/{storage}/content/{file}')
->json();
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
'file' => "{$this->node->iso_storage}:$contentType->value/$fileName",
])
->delete('/api2/json/nodes/{node}/storage/{storage}/content/{file}')
->json();

return $this->getData($response);
}

public function getIsos()
public function getIsos(): DataCollection
{
Assert::isInstanceOf($this->node, Node::class);

$response = $this->getHttpClient()
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
])
->get('/api2/json/nodes/{node}/storage/{storage}/content?content=iso')
->json();
->withUrlParameters([
'node' => $this->node->cluster,
'storage' => $this->node->iso_storage,
])
->get('/api2/json/nodes/{node}/storage/{storage}/content?content=iso')
->json();

$response = $this->getData($response);

Expand All @@ -86,23 +91,23 @@ public function getIsos()
return IsoData::collection($isos);
}

public function getFileMetadata(string $link, ?bool $verifyCertificates = true): FileMetaData
public function getFileMetadata(string $link, bool $verifyCertificates = true): FileMetaData
{
Assert::isInstanceOf($this->node, Node::class);
Assert::regex($link, '/^(http|https):\/\//');

$response = $this->getHttpClient()
->withUrlParameters([
'node' => $this->node->cluster,
])
->get('/api2/json/nodes/{node}/query-url-metadata', [
'url' => $link,
'verify-certificates' => $verifyCertificates,
])
->json();
->withUrlParameters([
'node' => $this->node->cluster,
])
->get('/api2/json/nodes/{node}/query-url-metadata', [
'url' => $link,
'verify-certificates' => $verifyCertificates,
])
->json();

if (Arr::get($response, 'success', 1) !== 1) {
throw new InvalidIsoLinkException;
throw new InvalidIsoLinkException();
}

$data = $this->getData($response);
Expand Down
6 changes: 3 additions & 3 deletions app/Services/Isos/IsoService.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(
}

public function download(
Node $node, string $name, ?string $fileName, string $link,
Node $node, string $name, ?string $fileName, string $link,
?ChecksumData $checksumData = null, ?bool $hidden = false,
)
{
Expand Down Expand Up @@ -57,11 +57,11 @@ public function getIso(Node $node, string $fileName): ?IsoData
return $isos->where('file_name', '=', $fileName)->first();
}

public function delete(Node $node, ISO $iso)
public function delete(Node $node, ISO $iso): void
{
if (is_null($iso->completed_at)) {
throw new BadRequestHttpException(
'This ISO cannot be restored at this time: not completed.',
'This ISO cannot be deleted at this time: not completed.',
);
}

Expand Down
122 changes: 122 additions & 0 deletions tests/Feature/Controllers/Admin/Nodes/IsoControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

use Convoy\Jobs\Node\MonitorIsoDownloadJob;
use Convoy\Models\ISO;
use Convoy\Models\Location;
use Convoy\Models\Node;
use Convoy\Models\User;

beforeEach(function () {
$this->user = User::factory()->create([
'root_admin' => true,
]);
$this->location = Location::factory()->create();
$this->node = Node::factory()->for($this->location)->create();
});

it('can fetch ISOs', function () {
$response = $this->actingAs($this->user)->getJson(
"/api/admin/nodes/{$this->node->id}/isos",
);

$response->assertOk();
});

it('can create an ISO', function () {
Http::fake([
'*/download-url' => Http::response(
file_get_contents(
base_path('tests/Fixtures/Repositories/Node/Storage/DownloadIsoData.json'),
),
200,
),
'*/query-url-metadata*' => Http::response(
file_get_contents(
base_path('tests/Fixtures/Repositories/Node/Storage/QueryIsoData.json'),
),
200,
),
]);

$response = $this->actingAs($this->user)->postJson(
"/api/admin/nodes/{$this->node->id}/isos",
[
'name' => 'Test ISO',
'file_name' => 'test.iso',
'link' => 'https://example.com/test.iso',
'should_download' => true,
'hidden' => false,
],
);

Queue::assertPushed(MonitorIsoDownloadJob::class);
$response->assertOk();
});

it("can't create an ISO with file_name taken", function () {
ISO::factory()->for($this->node)->create([
'file_name' => 'duplicate.iso',
]);

$response = $this->actingAs($this->user)->postJson(
"/api/admin/nodes/{$this->node->id}/isos",
[
'name' => 'Test ISO',
'file_name' => 'duplicate.iso',
'link' => 'https://example.com/duplicate.iso',
'should_download' => true,
'hidden' => false,
],
);

$response->assertStatus(422);
});

it('can update an ISO', function () {
$iso = ISO::factory()->for($this->node)->create();

$response = $this->actingAs($this->user)->putJson(
"/api/admin/nodes/{$this->node->id}/isos/{$iso->uuid}",
[
'name' => 'Updated ISO',
],
);

$response->assertOk();
});

it('can delete an ISO', function () {
Http::fake([
'*/storage/*/content/*' => Http::response(
file_get_contents(
base_path('tests/Fixtures/Repositories/Node/Storage/DeleteIsoData.json'),
), 200,
),
]);
$iso = ISO::factory()->for($this->node)->create();

$response = $this->actingAs($this->user)->deleteJson(
"/api/admin/nodes/{$this->node->id}/isos/{$iso->uuid}",
);

$response->assertNoContent();
});

it('can query link', function () {
Http::fake([
'*/query-url-metadata*' => Http::response(
file_get_contents(
base_path('tests/Fixtures/Repositories/Node/Storage/QueryIsoData.json'),
),
200,
),
]);

$response = $this->actingAs($this->user)->getJson(
'/tools/query-remote-file?link=' . urlencode(
'https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso',
),
);

$response->assertOk();
});
4 changes: 4 additions & 0 deletions tests/Fixtures/Repositories/Node/Storage/DeleteIsoData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"success": 1,
"data": null
}
4 changes: 4 additions & 0 deletions tests/Fixtures/Repositories/Node/Storage/DownloadIsoData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"data": "UPID:us-southeast:001BE662:04671913:65CF8596:download:virtio-win.iso:root@pam:",
"success": 1
}
8 changes: 8 additions & 0 deletions tests/Fixtures/Repositories/Node/Storage/QueryIsoData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"data": {
"filename": "virtio-win.iso",
"size": 627519488,
"mimetype": "application/octet-stream"
},
"success": 1
}

0 comments on commit 570dabc

Please sign in to comment.