Skip to content

Commit

Permalink
Merge pull request #18 from crypto-scythe/master
Browse files Browse the repository at this point in the history
Implement delete action
  • Loading branch information
dlundgren authored Jul 3, 2021
2 parents be05440 + e762244 commit 5846489
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ vendor/
data/
.env
composer.lock
phpunit.xml
phpunit.xml
.phpunit.result.cache
72 changes: 72 additions & 0 deletions src/Action/Api/Scope/Box/Delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/**
* @file
* Contains Phagrancy\Action\Api\Scope\Box\Delete
*/

namespace Phagrancy\Action\Api\Scope\Box;

use Phagrancy\Http\Response;
use Phagrancy\Model\Input;
use Phagrancy\Model\Repository;
use Psr\Http\Message\ServerRequestInterface;

/**
* Action for deleting a box from the server
*
* @package Phagrancy\Action\Api\Scope\Box
*/
class Delete
{
/**
* @var Repository\Box
*/
private $boxes;

/**
* @var string
*/
private $storagePath;

/**
* @var Input\BoxDelete
*/
private $input;

public function __construct(Repository\Box $boxes, Input\BoxDelete $input, $storagePath)
{
$this->boxes = $boxes;
$this->input = $input;
$this->storagePath = $storagePath;
}

public function __invoke(ServerRequestInterface $request)
{
/**
* The route controls these params, and they are validated so safe
*
* @var string $name
* @var string $scope
* @var string $version
* @var string $provider
*/
$params = $this->input->validate($request->getAttribute('route')->getArguments());
if (!$params) {
return new Response\NotFound();
}

extract($params);
$box = $this->boxes->ofNameInScope($name, $scope);

if ($box) {
$path = "{$this->storagePath}/{$box->path()}/{$version}/{$provider}.box";

if (file_exists($path) && unlink($path)) {
return new Response\Json([]);
}
}

return new Response\NotFound();
}
}
4 changes: 2 additions & 2 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct($container = [])
$this->put('/release', Action\AllClear::class);
$this->group('/provider/{provider}', function () {
$this->get('', Action\Api\Scope\Box\SendFile::class);
$this->delete('', Action\AllClear::class);
$this->delete('', Action\Api\Scope\Box\Delete::class);
$this->get('/upload', Action\Api\Scope\Box\UploadPreFlight::class);
$this->put('/upload', Action\Api\Scope\Box\Upload::class);
});
Expand All @@ -63,4 +63,4 @@ public function __construct($container = [])

// @formatter:on
}
}
}
45 changes: 45 additions & 0 deletions src/Model/Input/BoxDelete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/**
* @file
* Contains Phagrancy\Model\Input\BoxDelete
*/

namespace Phagrancy\Model\Input;

use Validator\LIVR;

/**
* Input for the BoxDelete
*
* Validates the scope, name, version, provider
*
* @package Phagrancy\Model\Input
*/
class BoxDelete
{
use IsValidator, ValidatesScope, ValidatesBoxName, ValidatesVersion;

public function __construct()
{
LIVR::registerDefaultRules(
[
'scope' => [$this, 'validateScope'],
'name' => [$this, 'validateBoxName'],
'version' => [$this, 'validateVersion'],
'provider' => [$this, 'validateProvider']
]);
}

public function validate($params)
{
return $this->perform(
$params,
[
'scope' => self::$SCOPE_RULE,
'name' => self::$BOX_NAME_RULE,
'version' => self::$VERSION_RULE,
'provider' => ['required', 'trim', 'to_lc']
]);
}
}
6 changes: 5 additions & 1 deletion src/ServiceProvider/Pimple.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public function register(Container $di)
return new Action\Api\Scope\Box\Upload($c[Repository\Box::class], new Input\BoxUpload(), $c['path.storage']);
};

$di[Action\Api\Scope\Box\Delete::class] = function ($c) {
return new Action\Api\Scope\Box\Delete($c[Repository\Box::class], new Input\BoxDelete(), $c['path.storage']);
};

$di[Action\Api\Scope\Box\SendFile::class] = function ($c) {
return new Action\Api\Scope\Box\SendFile($c[Repository\Box::class], new Input\BoxUpload(), $c['path.storage']);
};
Expand All @@ -124,4 +128,4 @@ private function resolveStoragePath()

return $path;
}
}
}
16 changes: 13 additions & 3 deletions tests/integration/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ public function provideGoodRoutes()
// provider delete
[
'DELETE',
'test/something/version/2.0.0/provider/test',
'delete/test/version/1.0.0/provider/test',
Response\Json::class,
null
[]
],
// version release
[
Expand Down Expand Up @@ -195,6 +195,16 @@ public function testUploadReturnsNotFound()
self::assertInstanceOf(Response\NotFound::class, $response);
}

public function testDeleteReturnsNotFoundOnNotExistingBox()
{
$response = $this->runApp(
'DELETE',
'/api/v1/box/test/something/version/1.0.0/provider/virtualtest'
);

self::assertInstanceOf(Response\NotFound::class, $response);
}

public function testAccessTokenIsRequired()
{
$env = $this->fs->url() . '/.env';
Expand Down Expand Up @@ -258,4 +268,4 @@ public function testAccessTokenAsHeaderIsInvalid()
file_put_contents($env, $old);
unset($this->app);
}
}
}
6 changes: 3 additions & 3 deletions tests/integration/FrontendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function provideGoodRoutes()
return [
['GET', '', Response\Json::class, null],
['GET', '/', Response\Json::class, null],
['GET', '/scopes', Response\ScopeList::class, ['alt','test']],
['GET', '/scopes', Response\ScopeList::class, ['alt', 'delete', 'test']],
['GET', '/test', Response\BoxList::class, ['username' => 'test', 'boxes' => ['test']]],
['GET', '/test/nope', Response\BoxDefinition::class, ['name' => 'test/nope', 'versions' => []]],
[
Expand Down Expand Up @@ -65,7 +65,7 @@ public function provideGoodRoutes()
]
]
]
]
],
],
];
}
Expand Down Expand Up @@ -142,4 +142,4 @@ public function testPasswordValidatesWhenSet()
file_put_contents($env, $old);
unset($this->app);
}
}
}
13 changes: 10 additions & 3 deletions tests/src/TestCase/Integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class Integration
],
'2.0.0' => [
'test.box' => 'test'
]
],
]
],
"alt" => [
Expand All @@ -49,7 +49,14 @@ abstract class Integration
'vmware.box' => 'vmware'
]
]
]
],
'delete' => [
'test' => [
'1.0.0' => [
'test.box' => 'testcontent'
]
]
]
]
]
];
Expand Down Expand Up @@ -141,4 +148,4 @@ public static function printVFS()
{
print_r(vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());
}
}
}
9 changes: 7 additions & 2 deletions tests/src/TestCase/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ abstract class Scope
'1.1' => [
'test.box' => 'test'
]
]
],
'delete' => [
'1.0.0' => [
'test.box' => 'testcontent'
]
]
]
];

Expand All @@ -56,4 +61,4 @@ protected function setUp(): void
$this->fs = vfsStream::setup('scope', null, $this->scope);
}

}
}
49 changes: 49 additions & 0 deletions tests/unit/Action/Api/Scope/Box/DeleteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/**
* @file
* Contains Phagrancy\Action\Api\Scope\Box\UploadTest
*/

namespace Phagrancy\Action\Api\Scope\Box;

use Phagrancy\Http\Response\Json;
use Phagrancy\Model\Input\BoxDelete;
use Phagrancy\Model\Repository\Box;
use Phagrancy\TestCase\Scope as ScopeTestCase;

class DeleteTest
extends ScopeTestCase
{
public function testReturnsOkAndRemovesExistingBox()
{
$request = $this->buildRequest();
$request->getAttribute('route')
->setArguments(
[
'scope' => 'test',
'name' => 'delete',
'version' => '1.0.0',
'provider' => 'test'
]);

// build the action itself
$action = new Delete(
new Box($this->fs->url()),
new BoxDelete(),
$this->fs->url()
);

// box file exists before action
self::assertTrue(file_exists($this->fs->url() . '/test/delete/1.0.0/test.box'));

$response = $action($request);

// file was removed
self::assertFalse(file_exists($this->fs->url() . '/test/delete/1.0.0/test.box'));
self::assertInstanceOf(Json::class, $response);
self::assertResponseHasStatus($response, 200);

$response->getBody()->close();
}
}

0 comments on commit 5846489

Please sign in to comment.