Compare commits
1 commit
master
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
|
465d183050 |
35 changed files with 9618 additions and 1 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/web
|
||||
/vendor
|
||||
/app
|
47
.gitlab-ci.yml
Normal file
47
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
stages:
|
||||
- setup
|
||||
- test
|
||||
|
||||
setup:composer:
|
||||
image: composer:latest
|
||||
stage: setup
|
||||
script:
|
||||
- mkdir -p .composer/cache
|
||||
- COMPOSER_CACHE_DIR=.composer/cache composer install --no-progress --no-ansi --no-interaction -o
|
||||
cache:
|
||||
key: composer-cache
|
||||
paths:
|
||||
- .composer/cache
|
||||
artifacts:
|
||||
expire_in: 30 mins
|
||||
paths:
|
||||
- app
|
||||
- web
|
||||
- vendor
|
||||
|
||||
test:acceptance:
|
||||
image: php:7.2-alpine
|
||||
stage: test
|
||||
services:
|
||||
- mysql:5.7
|
||||
- mailhog/mailhog:v1.0.0
|
||||
- selenium/standalone-chrome
|
||||
variables:
|
||||
MYSQL_ROOT_PASSWORD: "dev"
|
||||
MYSQL_DATABASE: "dev"
|
||||
MYSQL_USER: "dev"
|
||||
MYSQL_PASSWORD: "dev"
|
||||
before_script:
|
||||
- docker-php-ext-install pdo pdo_mysql mysqli
|
||||
- export LOCAL_IP=$(ip a | grep inet | sed -n 2p | xargs | cut -d" " -f2 | cut -d"/" -f1)
|
||||
- export TESTING_DOMAIN="$LOCAL_IP:8080"
|
||||
- export TYPO3_CONTEXT=Testing/Acceptance
|
||||
- php -S "$TESTING_DOMAIN" -t web &> php.log.txt &
|
||||
script:
|
||||
- ./vendor/bin/codecept run --env=gitlab-ci
|
||||
artifacts:
|
||||
when: on_failure
|
||||
expire_in: 10 mins
|
||||
paths:
|
||||
- tests/_output/
|
||||
- php.log.txt
|
37
README.rst
37
README.rst
|
@ -3,4 +3,39 @@ Workshop GitLab Acceptance Testing
|
|||
|
||||
This repository provides material for GitLab Acceptance testing.
|
||||
|
||||
Superseded by https://gitea.daniel-siepmann.de/danielsiepmann/acceptance-testing-with-php-codeception
|
||||
Install
|
||||
-------
|
||||
|
||||
#. Run ``composer install``
|
||||
|
||||
#. Setup database ``own_workshopgitlabacceptance_testing``
|
||||
|
||||
#. Setup Mailhog.
|
||||
|
||||
Execute
|
||||
-------
|
||||
|
||||
|
||||
#. Start selenium
|
||||
E.g.::
|
||||
|
||||
ChromeDriver=~/Applications/chromedriver-76 java -Djava.awt.headless=true -jar ~/Applications/selenium-server-standalone-3.141.59.jar
|
||||
|
||||
#. Start mailhog
|
||||
|
||||
#. Start php server::
|
||||
|
||||
TYPO3_CONTEXT=Testing/Acceptance php -S 127.0.0.1:8080 -t web
|
||||
|
||||
#. Execute tests::
|
||||
|
||||
./vendor/bin/codecept run --env local
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
* Add css / js for testing
|
||||
|
||||
* Use docker registry for finished container with php support for mysql
|
||||
|
||||
* Add db tests as examples to cest
|
||||
|
|
52
app/typo3conf/AdditionalConfiguration.php
Normal file
52
app/typo3conf/AdditionalConfiguration.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
if (getenv('TYPO3_ADDITIONAL_CONFIGURATION')) {
|
||||
require_once getenv('TYPO3_ADDITIONAL_CONFIGURATION');
|
||||
}
|
||||
|
||||
$appContext = \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext();
|
||||
if ((string) $appContext === 'Testing/Acceptance') {
|
||||
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule(
|
||||
$GLOBALS['TYPO3_CONF_VARS'],
|
||||
[
|
||||
'SYS' => [
|
||||
'trustedHostsPattern' => 'localhost:8080',
|
||||
],
|
||||
'MAIL' => [
|
||||
'transport' => 'smtp',
|
||||
'transport_smtp_server' => '127.0.0.1:1025',
|
||||
],
|
||||
'DB' => [
|
||||
'Connections' => [
|
||||
'Default' => [
|
||||
'dbname' => 'own_workshopgitlabacceptance_testing',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
if ((string) $appContext === 'Testing/Acceptance' && getenv('CI') === 'true') {
|
||||
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule(
|
||||
$GLOBALS['TYPO3_CONF_VARS'],
|
||||
[
|
||||
'SYS' => [
|
||||
'trustedHostsPattern' => getenv('TESTING_DOMAIN'),
|
||||
],
|
||||
'MAIL' => [
|
||||
'transport' => 'smtp',
|
||||
'transport_smtp_server' => 'mailhog__mailhog:1025',
|
||||
],
|
||||
'DB' => [
|
||||
'Connections' => [
|
||||
'Default' => [
|
||||
'dbname' => 'dev',
|
||||
'password' => 'dev',
|
||||
'user' => 'dev',
|
||||
'host' => 'mysql',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
95
app/typo3conf/LocalConfiguration.php
Normal file
95
app/typo3conf/LocalConfiguration.php
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
return [
|
||||
'BE' => [
|
||||
'debug' => true,
|
||||
'explicitADmode' => 'explicitAllow',
|
||||
'installToolPassword' => '$argon2i$v=19$m=65536,t=16,p=2$UzAyaTZoVEpFMmV2M1piSQ$TywI+4PRhqx2ggtTrV+R7BNrb0oheW6tr/SThHr6HgM',
|
||||
'loginSecurityLevel' => 'normal',
|
||||
'passwordHashing' => [
|
||||
'className' => 'TYPO3\\CMS\\Core\\Crypto\\PasswordHashing\\Argon2iPasswordHash',
|
||||
'options' => [],
|
||||
],
|
||||
],
|
||||
'DB' => [
|
||||
'Connections' => [
|
||||
'Default' => [
|
||||
'charset' => 'utf8mb4',
|
||||
'dbname' => 'own_workshopgitlabacceptance',
|
||||
'driver' => 'mysqli',
|
||||
'host' => '127.0.0.1',
|
||||
'password' => 'dev',
|
||||
'port' => 3306,
|
||||
'tableoptions' => [
|
||||
'charset' => 'utf8mb4',
|
||||
'collate' => 'utf8mb4_unicode_ci',
|
||||
],
|
||||
'unix_socket' => '/var/run/mysqld/mysqld.sock',
|
||||
'user' => 'dev',
|
||||
],
|
||||
],
|
||||
],
|
||||
'EXT' => [
|
||||
'extConf' => [
|
||||
'backend' => 'a:6:{s:9:"loginLogo";s:0:"";s:19:"loginHighlightColor";s:0:"";s:20:"loginBackgroundImage";s:0:"";s:13:"loginFootnote";s:0:"";s:11:"backendLogo";s:0:"";s:14:"backendFavicon";s:0:"";}',
|
||||
'extensionmanager' => 'a:2:{s:21:"automaticInstallation";s:1:"1";s:11:"offlineMode";s:1:"0";}',
|
||||
'scheduler' => 'a:2:{s:11:"maxLifetime";s:4:"1440";s:15:"showSampleTasks";s:1:"1";}',
|
||||
],
|
||||
],
|
||||
'EXTENSIONS' => [
|
||||
'backend' => [
|
||||
'backendFavicon' => '',
|
||||
'backendLogo' => '',
|
||||
'loginBackgroundImage' => '',
|
||||
'loginFootnote' => '',
|
||||
'loginHighlightColor' => '',
|
||||
'loginLogo' => '',
|
||||
],
|
||||
'extensionmanager' => [
|
||||
'automaticInstallation' => '1',
|
||||
'offlineMode' => '0',
|
||||
],
|
||||
'scheduler' => [
|
||||
'maxLifetime' => '1440',
|
||||
'showSampleTasks' => '1',
|
||||
],
|
||||
],
|
||||
'FE' => [
|
||||
'debug' => true,
|
||||
'loginSecurityLevel' => 'normal',
|
||||
'passwordHashing' => [
|
||||
'className' => 'TYPO3\\CMS\\Core\\Crypto\\PasswordHashing\\Argon2iPasswordHash',
|
||||
'options' => [],
|
||||
],
|
||||
],
|
||||
'GFX' => [
|
||||
'processor' => 'ImageMagick',
|
||||
'processor_allowTemporaryMasksAsPng' => false,
|
||||
'processor_colorspace' => 'sRGB',
|
||||
'processor_effects' => true,
|
||||
'processor_enabled' => true,
|
||||
'processor_path' => '/usr/bin/',
|
||||
'processor_path_lzw' => '/usr/bin/',
|
||||
],
|
||||
'MAIL' => [
|
||||
'transport' => 'sendmail',
|
||||
'transport_sendmail_command' => '/usr/sbin/sendmail -t -i ',
|
||||
'transport_smtp_encrypt' => '',
|
||||
'transport_smtp_password' => '',
|
||||
'transport_smtp_server' => '',
|
||||
'transport_smtp_username' => '',
|
||||
],
|
||||
'SYS' => [
|
||||
'devIPmask' => '*',
|
||||
'displayErrors' => 1,
|
||||
'encryptionKey' => 'fc4441867ae5c425bd55676e01d6d14fd2ae17ed8fd5682b495e74518eda4d437c0c48917772dc848fff31f5cea3c3eb',
|
||||
'exceptionalErrors' => 12290,
|
||||
'features' => [
|
||||
'unifiedPageTranslationHandling' => true,
|
||||
],
|
||||
'sitename' => 'New TYPO3 Console site',
|
||||
'systemLogLevel' => 0,
|
||||
'systemMaintainers' => [
|
||||
1,
|
||||
],
|
||||
],
|
||||
];
|
40
app/typo3conf/sites/main/config.yaml
Normal file
40
app/typo3conf/sites/main/config.yaml
Normal file
|
@ -0,0 +1,40 @@
|
|||
rootPageId: 1
|
||||
base: /
|
||||
languages:
|
||||
-
|
||||
title: English
|
||||
enabled: true
|
||||
languageId: '0'
|
||||
base: /
|
||||
typo3Language: default
|
||||
locale: en_US.UTF-8
|
||||
iso-639-1: en
|
||||
navigationTitle: English
|
||||
hreflang: en-us
|
||||
direction: ltr
|
||||
flag: us
|
||||
errorHandling: {}
|
||||
routes: {}
|
||||
baseVariants: {}
|
||||
|
||||
# routeEnhancers:
|
||||
# ExamplePlugin:
|
||||
# type: Extbase
|
||||
# extension: ExampleExtension
|
||||
# plugin: Address
|
||||
# defaultController: 'Address::index'
|
||||
# routes:
|
||||
# -
|
||||
# routePath: '/edit/{address}'
|
||||
# _controller: 'Address::edit'
|
||||
# _arguments:
|
||||
# 'address': 'address'
|
||||
# -
|
||||
# routePath: '/update'
|
||||
# _controller: 'Address::update'
|
||||
# aspects:
|
||||
# address:
|
||||
# type: PersistedAliasMapper
|
||||
# tableName: 'tx_exampleextension_domain_model_address'
|
||||
# routeFieldName: 'slug'
|
||||
# routeValuePrefix: '/'
|
35
codeception.yml
Normal file
35
codeception.yml
Normal file
|
@ -0,0 +1,35 @@
|
|||
suites:
|
||||
acceptance:
|
||||
actor: AcceptanceTester
|
||||
path: .
|
||||
modules:
|
||||
enabled:
|
||||
- WebDriver:
|
||||
url: https://workshop-gitlab-acceptance.own.localhost/
|
||||
browser: chrome
|
||||
- Db:
|
||||
dump: tests/_data/typo3.sql
|
||||
populate: true
|
||||
cleanup: true
|
||||
- MailHog:
|
||||
url: http://127.0.0.1
|
||||
port: 8025
|
||||
deleteEmailsAfterScenario: true
|
||||
- \Helper\Acceptance
|
||||
step_decorators:
|
||||
- Codeception\Step\ConditionalAssertion
|
||||
- Codeception\Step\TryTo
|
||||
- Codeception\Step\Retry
|
||||
|
||||
extensions:
|
||||
enabled: [Codeception\Extension\RunFailed]
|
||||
|
||||
params:
|
||||
- env
|
||||
|
||||
paths:
|
||||
tests: tests
|
||||
output: tests/_output
|
||||
data: tests/_data
|
||||
support: tests/_support
|
||||
envs: tests/_envs
|
51
composer.json
Normal file
51
composer.json
Normal file
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"repositories": [
|
||||
{
|
||||
"type": "path",
|
||||
"url": "localPackages/*"
|
||||
},
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://composer.typo3.org/"
|
||||
}
|
||||
],
|
||||
"name": "website/typo3-extension-workshop",
|
||||
"description": "Example TYPO3 installation for Acceptance Testing",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"helhum/typo3-console": "^5.5.5",
|
||||
"helhum/typo3-secure-web": "^0.2.7",
|
||||
"typo3-console/composer-auto-commands": "^0.2.0",
|
||||
"typo3/cms-core": "^9.5.0",
|
||||
"typo3/cms-about": "*",
|
||||
"typo3/cms-belog": "*",
|
||||
"typo3/cms-beuser": "*",
|
||||
"typo3/cms-fluid-styled-content": "*",
|
||||
"typo3/cms-info": "*",
|
||||
"typo3/cms-info-pagetsconfig": "*",
|
||||
"typo3/cms-rte-ckeditor": "*",
|
||||
"typo3/cms-setup": "*",
|
||||
"typo3/cms-t3editor": "*",
|
||||
"typo3/cms-tstemplate": "*",
|
||||
"workshop/example-extension": "@dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"typo3/cms-lowlevel": "*",
|
||||
"codeception/codeception": "^3.1.0",
|
||||
"ericmartel/codeception-email-mailhog": "^1.0"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.2"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"typo3/cms": {
|
||||
"app-dir": "app",
|
||||
"root-dir": "app",
|
||||
"web-dir": "web"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
6617
composer.lock
generated
Normal file
6617
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Workshop\ExampleExtension\Controller;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
use Workshop\ExampleExtension\Domain\Model\Address;
|
||||
use Workshop\ExampleExtension\Domain\Repository\AddressRepository;
|
||||
|
||||
class AddressController extends ActionController
|
||||
{
|
||||
/**
|
||||
* @var AddressRepository
|
||||
*/
|
||||
protected $addressRepository;
|
||||
|
||||
public function __construct(AddressRepository $addressRepository)
|
||||
{
|
||||
$this->addressRepository = $addressRepository;
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->assign('addresses', $this->addressRepository->findAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignorevalidation $address
|
||||
*/
|
||||
public function editAction(Address $address)
|
||||
{
|
||||
$this->view->assign('address', $address);
|
||||
}
|
||||
|
||||
public function updateAction(Address $address)
|
||||
{
|
||||
$this->addressRepository->update($address);
|
||||
|
||||
$this->signalSlotDispatcher->dispatch(__CLASS__, 'addressUpdated', [
|
||||
$address,
|
||||
$this,
|
||||
]);
|
||||
|
||||
$this->redirect('index');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Workshop\ExampleExtension\Domain\Event;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Mail\MailMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
use Workshop\ExampleExtension\Controller\AddressController;
|
||||
use Workshop\ExampleExtension\Domain\Model\Address as AddressModel;
|
||||
|
||||
class Address
|
||||
{
|
||||
public function updated(AddressModel $address, AddressController $controller)
|
||||
{
|
||||
$this->sendUpdateEMail($address);
|
||||
$this->addUpdateFlashMessage($address, $controller);
|
||||
}
|
||||
|
||||
private function sendUpdateEmail(AddressModel $address)
|
||||
{
|
||||
$mail = GeneralUtility::makeInstance(MailMessage::class);
|
||||
|
||||
$mail->setSubject('Address ' . $address->getCompanyName() . ' was updated');
|
||||
$mail->setTo(array('coding@daniel-siepmann.de'));
|
||||
$mail->setBody('The address ' . $address->getCompanyName() . ' was successfully updated.');
|
||||
$mail->send();
|
||||
}
|
||||
|
||||
private function addUpdateFlashMessage(AddressModel $address, AddressController $controller)
|
||||
{
|
||||
$controller->addFlashMessage(
|
||||
LocalizationUtility::translate('flashSuccess', 'ExampleExtension', [
|
||||
'companyName' => $address->getCompanyName(),
|
||||
'street' => $address->getStreet(),
|
||||
]),
|
||||
'Update successfully'
|
||||
);
|
||||
}
|
||||
}
|
119
localPackages/example_extension/Classes/Domain/Model/Address.php
Normal file
119
localPackages/example_extension/Classes/Domain/Model/Address.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Workshop\ExampleExtension\Domain\Model;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
|
||||
class Address extends AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @validate NotEmpty
|
||||
*/
|
||||
protected $companyName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $street;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $houseNumber;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @validate RegularExpression(regularExpression = '/^[0-9]{5}$/')
|
||||
*/
|
||||
protected $zip;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $city;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $country;
|
||||
|
||||
public function setCompanyName(string $companyName)
|
||||
{
|
||||
$this->companyName = $companyName;
|
||||
}
|
||||
|
||||
public function getCompanyName(): string
|
||||
{
|
||||
return $this->companyName;
|
||||
}
|
||||
|
||||
public function setStreet(string $street)
|
||||
{
|
||||
$this->street = $street;
|
||||
}
|
||||
|
||||
public function getStreet(): string
|
||||
{
|
||||
return $this->street;
|
||||
}
|
||||
|
||||
public function setHouseNumber(string $houseNumber)
|
||||
{
|
||||
$this->houseNumber = $houseNumber;
|
||||
}
|
||||
|
||||
public function getHouseNumber(): string
|
||||
{
|
||||
return $this->houseNumber;
|
||||
}
|
||||
|
||||
public function setZip(string $zip)
|
||||
{
|
||||
$this->zip = $zip;
|
||||
}
|
||||
|
||||
public function getZip(): string
|
||||
{
|
||||
return $this->zip;
|
||||
}
|
||||
|
||||
public function setCity(string $city)
|
||||
{
|
||||
$this->city = $city;
|
||||
}
|
||||
|
||||
public function getCity(): string
|
||||
{
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
public function setCountry(string $country)
|
||||
{
|
||||
$this->country = $country;
|
||||
}
|
||||
|
||||
public function getCountry(): string
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Workshop\ExampleExtension\Domain\Repository;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
class AddressRepository extends Repository
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
(function ($extensionKey, $tableName) {
|
||||
$langPath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang.xlf:' . $tableName . '.';
|
||||
|
||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||
'Workshop.ExampleExtension',
|
||||
'Address',
|
||||
'Address Plugin',
|
||||
'content-store'
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule(
|
||||
$GLOBALS['TCA'][$tableName],
|
||||
[
|
||||
'ctrl' => [
|
||||
'typeicon_classes' => [
|
||||
'exampleextension_address' => 'content-store',
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'exampleextension_address' => [
|
||||
'showitem' => implode(',', [
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
// Keep original code from ext:frontend
|
||||
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general',
|
||||
'--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.general;general',
|
||||
'--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.headers;headers',
|
||||
'pages;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:pages.ALT.list_formlabel',
|
||||
'recursive,',
|
||||
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access',
|
||||
'--palette--;;hidden',
|
||||
'--palette--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.access;access',
|
||||
// phpcs:enable
|
||||
]),
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
})('example_extension', 'tt_content');
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
return (function (
|
||||
$extensionKey = 'example_extension',
|
||||
$tableName = 'tx_workshopexampleextension_domain_model_address'
|
||||
) {
|
||||
$extensionLanguagePrefix = 'LLL:EXT:example_extension/Resources/Private/Language/locallang_tca.xlf:';
|
||||
$coreLanguagePrefix = 'LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:';
|
||||
|
||||
return [
|
||||
'ctrl' => [
|
||||
'label' => 'company_name',
|
||||
'iconfile' => 'EXT:core/Resources/Public/Icons/T3Icons/content/content-store.svg',
|
||||
'default_sortby' => 'company_name',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'cruser_id' => 'cruser_id',
|
||||
'title' => $extensionLanguagePrefix . 'address',
|
||||
'delete' => 'deleted',
|
||||
'enablecolumns' => [
|
||||
'disabled' => 'hidden',
|
||||
'starttime' => 'starttime',
|
||||
'endtime' => 'endtime'
|
||||
],
|
||||
'searchFields' => 'company_name, street, city'
|
||||
],
|
||||
'interface' => [
|
||||
'showRecordFieldList' => 'company_name, street, house_number, zip, city, country, slug'
|
||||
],
|
||||
'palettes' => [
|
||||
'address' => [
|
||||
'showitem' => implode(',', [
|
||||
'street, house_number',
|
||||
'--linebreak--',
|
||||
'zip, city',
|
||||
'--linebreak--',
|
||||
'country',
|
||||
]),
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => [
|
||||
'showitem' => implode(',', [
|
||||
'--div--;' . $coreLanguagePrefix . 'general',
|
||||
'company_name;;address',
|
||||
'slug',
|
||||
]),
|
||||
],
|
||||
],
|
||||
'columns' => [
|
||||
'company_name' => [
|
||||
'label' => $extensionLanguagePrefix . 'company_name',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'street' => [
|
||||
'label' => $extensionLanguagePrefix . 'street',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'house_number' => [
|
||||
'label' => $extensionLanguagePrefix . 'house_number',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'zip' => [
|
||||
'label' => $extensionLanguagePrefix . 'zip',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'city' => [
|
||||
'label' => $extensionLanguagePrefix . 'city',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'country' => [
|
||||
'label' => $extensionLanguagePrefix . 'country',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'max' => 255,
|
||||
'eval' => 'trim,required',
|
||||
],
|
||||
],
|
||||
'slug' => [
|
||||
'label' => $extensionLanguagePrefix . 'slug',
|
||||
'config' => [
|
||||
'type' => 'slug',
|
||||
'generatorOptions' => [
|
||||
'fields' => ['company_name'],
|
||||
'prefixParentPageSlug' => true,
|
||||
],
|
||||
'fallbackCharacter' => '-',
|
||||
'eval' => 'uniqueInSite',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
})();
|
|
@ -0,0 +1,3 @@
|
|||
config {
|
||||
contentObjectExceptionHandler = 0
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
@import 'EXT:fluid_styled_content/Configuration/TypoScript/setup.typoscript'
|
|
@ -0,0 +1,4 @@
|
|||
page = PAGE
|
||||
page {
|
||||
10 < styles.content.get
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2018-10-01T11:16:33Z" product-name="CodeExamples">
|
||||
<header/>
|
||||
<body>
|
||||
<!-- Form Labels -->
|
||||
<trans-unit id="labels.companyName" xml:space="preserve">
|
||||
<source>Company name</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.street" xml:space="preserve">
|
||||
<source>Street</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.houseNumber" xml:space="preserve">
|
||||
<source>House number</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.zip" xml:space="preserve">
|
||||
<source>Zip</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.city" xml:space="preserve">
|
||||
<source>City</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.country" xml:space="preserve">
|
||||
<source>Country</source>
|
||||
</trans-unit>
|
||||
|
||||
<!-- Form Validation -->
|
||||
<trans-unit id="error.address.companyName.1221560718" xml:space="preserve">
|
||||
<source>Please provide a company name.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="error.address.zip.1221565130" xml:space="preserve">
|
||||
<source>Please provide a valid ZIP consisting of 5 digits.</source>
|
||||
</trans-unit>
|
||||
|
||||
<trans-unit id="flashSuccess" xml:space="preserve">
|
||||
<source>Update des Datensatzes %1$s war Erfolgreich.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2018-09-05T08:51:01Z" product-name="CodeExamples">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="address" xml:space="preserve">
|
||||
<source>Address</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="company_name" xml:space="preserve">
|
||||
<source>Company name</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="street" xml:space="preserve">
|
||||
<source>Street</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="house_number" xml:space="preserve">
|
||||
<source>House number</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="zip" xml:space="preserve">
|
||||
<source>Zip</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="city" xml:space="preserve">
|
||||
<source>City</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="country" xml:space="preserve">
|
||||
<source>Country</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,41 @@
|
|||
<h3>Editing: {address.companyName}</h3>
|
||||
|
||||
<f:form action="update" object="{address}" name="address">
|
||||
<f:for each="{
|
||||
0: 'companyName',
|
||||
1: 'street',
|
||||
2: 'houseNumber',
|
||||
3: 'zip',
|
||||
4: 'city',
|
||||
5: 'country'
|
||||
}" as="propertyName">
|
||||
{f:render(section: 'Field', arguments: {
|
||||
propertyName: propertyName
|
||||
})}
|
||||
</f:for>
|
||||
|
||||
<br>
|
||||
<f:form.submit value="Update" />
|
||||
</f:form>
|
||||
|
||||
<f:section name="Field">
|
||||
<p>
|
||||
<label for="{propertyName}">{f:translate(id: 'labels.{propertyName}')}</label>
|
||||
<br>
|
||||
<f:form.textfield property="{propertyName}" id="{propertyName}" />
|
||||
{f:render(section: 'FieldErrors', arguments: {
|
||||
propertyPath: 'address.{propertyName}'
|
||||
})}
|
||||
<br>
|
||||
</p>
|
||||
</f:section>
|
||||
|
||||
<f:section name="FieldErrors">
|
||||
<f:form.validationResults for="{propertyPath}">
|
||||
<f:for each="{validationResults.flattenedErrors}" as="errors">
|
||||
<f:for each="{errors}" as="error">
|
||||
{f:translate(id: 'error.{propertyPath}.{error.code}', default: error.code)}
|
||||
</f:for>
|
||||
</f:for>
|
||||
</f:form.validationResults>
|
||||
</f:section>
|
|
@ -0,0 +1,11 @@
|
|||
<f:flashMessages />
|
||||
<f:for each="{addresses}" as="address">
|
||||
<h3>{address.companyName}</h3>
|
||||
<address>
|
||||
{address.street} {address.houseNumber}
|
||||
{address.zip} {address.city}
|
||||
{address.country}
|
||||
</address>
|
||||
|
||||
<f:link.action action="edit" arguments="{address: address}">Edit</f:link.action>
|
||||
</f:for>
|
21
localPackages/example_extension/composer.json
Normal file
21
localPackages/example_extension/composer.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "workshop/example-extension",
|
||||
"description": "Example for TYPO3 Extension Workshop.",
|
||||
"type": "typo3-cms-extension",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Daniel Siepmann",
|
||||
"email": "coding@daniel-siepmann.de"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Workshop\\ExampleExtension\\": "Classes"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"typo3/cms-core": "*"
|
||||
}
|
||||
}
|
23
localPackages/example_extension/ext_emconf.php
Normal file
23
localPackages/example_extension/ext_emconf.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
$EM_CONF['example_extension'] = [
|
||||
'title' => 'Example extension',
|
||||
'description' => 'Example for TYPO3 Extension Workshop.',
|
||||
'category' => 'example',
|
||||
'version' => '1.0.0',
|
||||
'state' => 'stable',
|
||||
'author' => 'Daniel Siepmann',
|
||||
'author_email' => 'coding@daniel-siepmann.de',
|
||||
'author_company' => 'Codappix',
|
||||
'constraints' => [
|
||||
'depends' => [
|
||||
'php' => '7.2.0-7.2.999',
|
||||
'typo3' => '8.7.0-9.5.999',
|
||||
],
|
||||
],
|
||||
'autoload' => [
|
||||
'psr-4' => [
|
||||
'Workshop\\ExampleExtension\\' => 'Classes',
|
||||
]
|
||||
],
|
||||
];
|
51
localPackages/example_extension/ext_localconf.php
Normal file
51
localPackages/example_extension/ext_localconf.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
(function () {
|
||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||
'Workshop.ExampleExtension',
|
||||
'Address',
|
||||
[
|
||||
'Address' => 'index, edit, update'
|
||||
],
|
||||
[
|
||||
'Address' => 'update'
|
||||
],
|
||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup(trim('
|
||||
@import "EXT:example_extension/Configuration/TypoScript/*.typoscript"
|
||||
'));
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
|
||||
mod {
|
||||
wizards {
|
||||
newContentElement {
|
||||
wizardItems {
|
||||
common {
|
||||
show = *
|
||||
elements {
|
||||
exampleElement {
|
||||
iconIdentifier = content-store
|
||||
title = Example title
|
||||
description = Example Description
|
||||
tt_content_defValues {
|
||||
CType = list
|
||||
list_type = exampleextension_pluginkey
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
|
||||
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class)->connect(
|
||||
\Workshop\ExampleExtension\Controller\AddressController::class,
|
||||
'addressUpdated',
|
||||
\Workshop\ExampleExtension\Domain\Event\Address::class,
|
||||
'updated'
|
||||
);
|
||||
})();
|
9
localPackages/example_extension/ext_tables.sql
Normal file
9
localPackages/example_extension/ext_tables.sql
Normal file
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE tx_exampleextension_domain_model_address (
|
||||
company_name varchar(255) DEFAULT '' NOT NULL,
|
||||
street varchar(255) DEFAULT '' NOT NULL,
|
||||
house_number varchar(255) DEFAULT '' NOT NULL,
|
||||
zip varchar(255) DEFAULT '' NOT NULL,
|
||||
city varchar(255) DEFAULT '' NOT NULL,
|
||||
country varchar(255) DEFAULT '' NOT NULL,
|
||||
slug varchar(2048),
|
||||
);
|
66
tests/AddressCest.php
Normal file
66
tests/AddressCest.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
class AddressCest
|
||||
{
|
||||
public function listsExistingRecords(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/plugin');
|
||||
$I->see('Codappix GmbH');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends listsExistingRecords
|
||||
*/
|
||||
public function canEditRecord(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/plugin');
|
||||
$I->see('Edit');
|
||||
$I->click('Edit');
|
||||
|
||||
$I->see('Editing: Codappix GmbH');
|
||||
$I->fillField(['id' => 'companyName'], 'TYPO3 Camp Rhein Ruhr');
|
||||
$I->click('Update');
|
||||
|
||||
$I->amOnPage('/plugin');
|
||||
$I->see('TYPO3 Camp Rhein Ruhr');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends canEditRecord
|
||||
*/
|
||||
public function sendsMailOnUpdate(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/plugin');
|
||||
$I->see('Edit');
|
||||
$I->click('Edit');
|
||||
|
||||
$I->see('Editing: Codappix GmbH');
|
||||
$I->fillField(['id' => 'companyName'], 'TYPO3 Camp Rhein Ruhr');
|
||||
$I->click('Update');
|
||||
|
||||
$I->fetchEmails();
|
||||
$I->haveUnreadEmails();
|
||||
$I->openNextUnreadEmail();
|
||||
$I->dontHaveUnreadEmails();
|
||||
|
||||
$I->seeInOpenedEmailSubject('Address TYPO3 Camp Rhein Ruhr was updated');
|
||||
$I->seeInOpenedEmailBody('The address TYPO3 Camp Rhein Ruhr was successfully updated.');
|
||||
$I->seeInOpenedEmailRecipients('coding@daniel-siepmann.de');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends listsExistingRecords
|
||||
*/
|
||||
public function zipValidatesAgainst5Digits(AcceptanceTester $I)
|
||||
{
|
||||
$I->amOnPage('/plugin');
|
||||
$I->see('Edit');
|
||||
$I->click('Edit');
|
||||
|
||||
$I->see('Editing: Codappix GmbH');
|
||||
$I->fillField(['id' => 'zip'], '123');
|
||||
$I->click('Update');
|
||||
|
||||
$I->see('Please provide a valid ZIP consisting of 5 digits.');
|
||||
}
|
||||
}
|
0
tests/_data/.gitkeep
Normal file
0
tests/_data/.gitkeep
Normal file
1855
tests/_data/typo3.sql
Normal file
1855
tests/_data/typo3.sql
Normal file
File diff suppressed because one or more lines are too long
12
tests/_envs/gitlab-ci.yml
Normal file
12
tests/_envs/gitlab-ci.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
modules:
|
||||
config:
|
||||
WebDriver:
|
||||
url: http://%TESTING_DOMAIN%/
|
||||
host: selenium__standalone-chrome
|
||||
Db:
|
||||
dsn: 'mysql:host=mysql;dbname=dev'
|
||||
user: 'dev'
|
||||
password: 'dev'
|
||||
MailHog:
|
||||
url: http://mailhog__mailhog
|
||||
port: 8025
|
11
tests/_envs/local.yml
Normal file
11
tests/_envs/local.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
modules:
|
||||
config:
|
||||
WebDriver:
|
||||
url: http://localhost:8080/
|
||||
Db:
|
||||
dsn: 'mysql:host=localhost;dbname=own_workshopgitlabacceptance_testing'
|
||||
user: 'dev'
|
||||
password: 'dev'
|
||||
MailHog:
|
||||
url: http://127.0.0.1
|
||||
port: 8025
|
2
tests/_output/.gitignore
vendored
Normal file
2
tests/_output/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
26
tests/_support/AcceptanceTester.php
Normal file
26
tests/_support/AcceptanceTester.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method void pause()
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class AcceptanceTester extends \Codeception\Actor
|
||||
{
|
||||
use _generated\AcceptanceTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
10
tests/_support/Helper/Acceptance.php
Normal file
10
tests/_support/Helper/Acceptance.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
namespace Helper;
|
||||
|
||||
// here you can define custom actions
|
||||
// all public methods declared in helper class will be available in $I
|
||||
|
||||
class Acceptance extends \Codeception\Module
|
||||
{
|
||||
|
||||
}
|
2
tests/_support/_generated/.gitignore
vendored
Normal file
2
tests/_support/_generated/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
Loading…
Reference in a new issue