Skip to content

Commit

Permalink
Add destroyable singletons (#45549)
Browse files Browse the repository at this point in the history
  • Loading branch information
axlon authored Jan 6, 2023
1 parent a13b10f commit b5ad135
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Illuminate/Routing/PendingSingletonResourceRegistration.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ public function creatable($creatable = true)
return $this;
}

/**
* Indicate that the resource should have a deletion route.
*
* @param bool $destroyable
* @return $this
*/
public function destroyable($destroyable = true)
{
$this->options['destroyable'] = $destroyable;

return $this;
}

/**
* Set the route names for controller actions.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Routing/ResourceRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ protected function getResourceMethods($defaults, $options)
);
}

if (isset($options['destroyable'])) {
$methods = array_merge(['destroy'], $methods);

return $this->getResourceMethods(
$methods, array_values(Arr::except($options, ['destroyable']))
);
}

return $methods;
}

Expand Down
70 changes: 70 additions & 0 deletions tests/Integration/Routing/RouteSingletonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,31 @@ public function testCreatableSingleton()
$this->assertSame('singleton destroy', $response->getContent());
}

public function testDestroyableSingleton()
{
Route::singleton('avatar', CreatableSingletonTestController::class)->destroyable();

$this->assertSame('http://localhost/avatar', route('avatar.show'));
$response = $this->get('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton show', $response->getContent());

$this->assertSame('http://localhost/avatar/edit', route('avatar.edit'));
$response = $this->get('/avatar/edit');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton edit', $response->getContent());

$this->assertSame('http://localhost/avatar', route('avatar.update'));
$response = $this->put('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton update', $response->getContent());

$this->assertSame('http://localhost/avatar', route('avatar.destroy'));
$response = $this->delete('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton destroy', $response->getContent());
}

public function testApiSingleton()
{
Route::apiSingleton('avatar', SingletonTestController::class);
Expand Down Expand Up @@ -96,6 +121,26 @@ public function testCreatableApiSingleton()
$this->assertSame('singleton update', $response->getContent());
}

public function testDestroyableApiSingleton()
{
Route::apiSingleton('avatar', CreatableSingletonTestController::class)->destroyable();

$this->assertSame('http://localhost/avatar', route('avatar.show'));
$response = $this->get('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton show', $response->getContent());

$this->assertSame('http://localhost/avatar', route('avatar.update'));
$response = $this->put('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton update', $response->getContent());

$this->assertSame('http://localhost/avatar', route('avatar.destroy'));
$response = $this->delete('/avatar');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton destroy', $response->getContent());
}

public function testSingletonOnly()
{
Route::singleton('avatar', SingletonTestController::class)->only('show');
Expand Down Expand Up @@ -203,6 +248,31 @@ public function testCreatableNestedSingleton()
$this->assertSame('singleton destroy for 123', $response->getContent());
}

public function testDestroyableNestedSingleton()
{
Route::singleton('videos.thumbnail', NestedSingletonTestController::class)->destroyable();

$response = $this->get('/videos/123/thumbnail');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton show for 123', $response->getContent());

$response = $this->get('/videos/123/thumbnail/edit');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton edit for 123', $response->getContent());

$response = $this->put('/videos/123/thumbnail');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton update for 123', $response->getContent());

$response = $this->patch('/videos/123/thumbnail');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton update for 123', $response->getContent());

$response = $this->delete('/videos/123/thumbnail');
$this->assertEquals(200, $response->getStatusCode());
$this->assertSame('singleton destroy for 123', $response->getContent());
}

public function testNestedSingletonParameter()
{
Route::singleton('v.thumbnail', NestedSingletonTestController::class)->parameter('v', 'video');
Expand Down

0 comments on commit b5ad135

Please sign in to comment.