mirror of
https://github.com/FriendsOfTYPO3/tea.git
synced 2024-12-24 04:26:10 +01:00
[FEATURE] Add a delete functionality for the Tea FE editor (#876)
The delete action is triggered using a form with a submit button, causing a POST request to be sent instead of a GET request. This is because GET requests should not modify (or delete) data, but only read it and be idempotent. Also, the request then is guaranteed to not get cached. From a usability perspective, a button instead of a link also is semantically more correct: A link is expected to bring you to some place, whereas a button is expected to trigger some action. Closes #871
This commit is contained in:
parent
82e7e95487
commit
cda38af84b
7 changed files with 93 additions and 4 deletions
|
@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
## x.y.z
|
||||
|
||||
### Added
|
||||
- Add an FE editor (#864, #872, #874)
|
||||
- Add an FE editor (#864, #872, #874, #876)
|
||||
- Add automerging of green Dependabot PRs (#756)
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -9,6 +9,7 @@ use TTN\Tea\Domain\Model\Product\Tea;
|
|||
use TTN\Tea\Domain\Repository\Product\TeaRepository;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Annotation as Extbase;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
|
||||
/**
|
||||
|
@ -89,4 +90,16 @@ class FrontEndEditorController extends ActionController
|
|||
|
||||
return $this->redirect('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Extbase\IgnoreValidation("tea")
|
||||
*/
|
||||
public function deleteAction(Tea $tea): ResponseInterface
|
||||
{
|
||||
$this->checkIfUserIsOwner($tea);
|
||||
|
||||
$this->teaRepository->remove($tea);
|
||||
|
||||
return $this->redirect('index');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,10 @@
|
|||
<source>Create new tea</source>
|
||||
<target>Neuen Tee anlegen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="plugin.frontEndEditor.action.delete">
|
||||
<source>Delete</source>
|
||||
<target>Löschen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="plugin.frontEndEditor.new.heading">
|
||||
<source>Create new tea</source>
|
||||
<target>Neuen Tee anlegen</target>
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
<trans-unit id="plugin.frontEndEditor.action.new">
|
||||
<source>Create new tea</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="plugin.frontEndEditor.action.delete">
|
||||
<source>Delete</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="plugin.frontEndEditor.new.heading">
|
||||
<source>Create new tea</source>
|
||||
</trans-unit>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<th scope="col">
|
||||
<f:translate key="plugin.frontEndEditor.property.title"/>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<th scope="col" colspan="2">
|
||||
<f:translate key="plugin.frontEndEditor.action.actions"/>
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -40,6 +40,12 @@
|
|||
<f:translate key="plugin.frontEndEditor.action.edit"/>
|
||||
</f:link.action>
|
||||
</td>
|
||||
<td>
|
||||
<f:form action="delete" name="tea" object="{tea}">
|
||||
<f:form.submit value="{f:translate(key: 'plugin.frontEndEditor.action.delete')}"
|
||||
class="btn btn-danger"/>
|
||||
</f:form>
|
||||
</td>
|
||||
</tr>
|
||||
</f:for>
|
||||
</table>
|
||||
|
|
|
@ -373,4 +373,67 @@ final class FrontEndEditorControllerTest extends UnitTestCase
|
|||
|
||||
$this->subject->updateAction($tea);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function deleteActionWithOwnTeaRemovesProvidedTea(): void
|
||||
{
|
||||
$userUid = 5;
|
||||
$this->setUidOfLoggedInUser($userUid);
|
||||
$tea = new Tea();
|
||||
$tea->setOwnerUid($userUid);
|
||||
$this->stubRedirect('index');
|
||||
|
||||
$this->teaRepositoryMock->expects(self::once())->method('remove')->with($tea);
|
||||
|
||||
$this->subject->deleteAction($tea);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function deleteActionWithOwnTeaRedirectsToIndexAction(): void
|
||||
{
|
||||
$userUid = 5;
|
||||
$this->setUidOfLoggedInUser($userUid);
|
||||
$tea = new Tea();
|
||||
$tea->setOwnerUid($userUid);
|
||||
|
||||
$this->mockRedirect('index');
|
||||
|
||||
$this->subject->deleteAction($tea);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function deleteActionWithTeaFromOtherUserThrowsException(): void
|
||||
{
|
||||
$this->setUidOfLoggedInUser(1);
|
||||
$tea = new Tea();
|
||||
$tea->setOwnerUid(2);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('You do not have the permissions to edit this tea.');
|
||||
$this->expectExceptionCode(1687363749);
|
||||
|
||||
$this->subject->deleteAction($tea);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function deleteActionWithTeaWithoutOwnerThrowsException(): void
|
||||
{
|
||||
$this->setUidOfLoggedInUser(1);
|
||||
$tea = new Tea();
|
||||
$tea->setOwnerUid(0);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('You do not have the permissions to edit this tea.');
|
||||
$this->expectExceptionCode(1687363749);
|
||||
|
||||
$this->subject->deleteAction($tea);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ ExtensionUtility::configurePlugin(
|
|||
'TeaFrontEndEditor',
|
||||
// all actions
|
||||
[
|
||||
FrontEndEditorController::class => 'index, edit, update, create, new',
|
||||
FrontEndEditorController::class => 'index, edit, update, create, new, delete',
|
||||
],
|
||||
// non-cacheable actions
|
||||
[
|
||||
// All actions need to be non-cacheable because they either contain dynamic data,
|
||||
// or because they are specific to the logged-in FE user (while FE content is cached by FE groups).
|
||||
FrontEndEditorController::class => 'index, edit, update, create, new',
|
||||
FrontEndEditorController::class => 'index, edit, update, create, new, delete',
|
||||
]
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue