Setup functional tests with first sample test

This commit is contained in:
Kajetan Dvoracek 2022-01-18 13:39:01 +01:00
parent 6c39c9574d
commit bc018a688d
11 changed files with 708 additions and 11 deletions

View File

@ -17,5 +17,8 @@ jobs:
- name: Install dependencies
run: Build/Test/runTests.sh -s composerInstall -t ${{ matrix.typo3 }}
- name: Run the tests
run: Build/Test/runTests.sh
- name: Run unit tests
run: Build/Test/runTests.sh -s unit
- name: Run functional tests
run: Build/Test/runTests.sh -s functional

View File

@ -0,0 +1,31 @@
<!-- adopted from https://github.com/TYPO3/styleguide/blob/2a51dc3db6c2916c07595dd96e8b817a73216002/Build/FunctionalTests.xml -->
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
backupGlobals="true"
bootstrap="../../vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php"
cacheResult="false"
colors="true"
convertErrorsToExceptions="true"
convertWarningsToExceptions="true"
convertNoticesToExceptions="true"
convertDeprecationsToExceptions="true"
forceCoversAnnotation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false"
beStrictAboutTestsThatDoNotTestAnything="false"
failOnWarning="true"
>
<testsuites>
<testsuite name="Functional tests">
<directory>../../Tests/Functional/</directory>
</testsuite>
</testsuites>
<php>
<ini name="display_errors" value="1" />
<env name="TYPO3_CONTEXT" value="Testing" />
</php>
</phpunit>

View File

@ -2,6 +2,20 @@
version: "2.3"
services:
mysql:
image: mysql:${MYSQL_VERSION}
environment:
MYSQL_ROOT_PASSWORD: funcp
tmpfs:
- /var/lib/mysql/:rw,noexec,nosuid
mariadb:
image: mariadb:${MARIADB_VERSION}
environment:
MYSQL_ROOT_PASSWORD: funcp
tmpfs:
- /var/lib/mysql/:rw,noexec,nosuid
composer_install:
image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest
user: "${HOST_UID}:${HOST_GID}"
@ -22,6 +36,48 @@ services:
fi
"
functional:
image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest
links:
- ${DBMS}
user: "${HOST_UID}:${HOST_GID}"
volumes:
- ${DLF_ROOT}:${DLF_ROOT}
environment:
typo3DatabaseDriver: "${DATABASE_DRIVER}"
typo3DatabaseName: func_test
typo3DatabaseUsername: root
typo3DatabasePassword: funcp
typo3DatabaseHost: ${DBMS}
working_dir: ${DLF_ROOT}
extra_hosts:
- "host.docker.internal:host-gateway"
command: >
/bin/sh -c "
if [ ${SCRIPT_VERBOSE} -eq 1 ]; then
set -x
fi
echo Waiting for database start...;
while ! nc -z ${DBMS} 3306; do
sleep 1;
done;
echo Database is up;
if [ ${SCRIPT_VERBOSE} -eq 1 ]; then
set -x
fi
php -v | grep '^PHP'
COMMAND=\"vendor/phpunit/phpunit/phpunit -c Build/Test/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}\"
if [ ${PHP_XDEBUG_ON} -eq 0 ]; then
XDEBUG_MODE=\"off\" $${COMMAND};
else
XDEBUG_MODE=\"debug,develop\" \
XDEBUG_TRIGGER=\"foo\" \
XDEBUG_CONFIG=\"client_port=${PHP_XDEBUG_PORT} client_host=host.docker.internal\" \
$${COMMAND};
fi
"
unit:
image: typo3/core-testing-${DOCKER_PHP_IMAGE}:latest
user: "${HOST_UID}:${HOST_GID}"

View File

@ -27,15 +27,35 @@ setUpDockerComposeDotEnv() {
echo "DOCKER_PHP_IMAGE=${DOCKER_PHP_IMAGE}"
echo "EXTRA_TEST_OPTIONS=${EXTRA_TEST_OPTIONS}"
echo "SCRIPT_VERBOSE=${SCRIPT_VERBOSE}"
echo "DBMS=${DBMS}"
echo "DATABASE_DRIVER=${DATABASE_DRIVER}"
echo "MARIADB_VERSION=${MARIADB_VERSION}"
echo "MYSQL_VERSION=${MYSQL_VERSION}"
echo "PHP_VERSION=${PHP_VERSION}"
} > .env
}
# Options -a and -d depend on each other. The function
# validates input combinations and sets defaults.
handleDbmsAndDriverOptions() {
case ${DBMS} in
mysql|mariadb)
[ -z "${DATABASE_DRIVER}" ] && DATABASE_DRIVER="mysqli"
if [ "${DATABASE_DRIVER}" != "mysqli" ] && [ "${DATABASE_DRIVER}" != "pdo_mysql" ]; then
echo "Invalid option -a ${DATABASE_DRIVER} with -d ${DBMS}" >&2
echo >&2
echo "call \".Build/Test/runTests.sh -h\" to display help and valid options" >&2
exit 1
fi
;;
esac
}
# Load help text into $HELP
read -r -d '' HELP <<EOF
Based upon TYPO3 core test runner.
Execute unit and other test suites in a docker based test environment. Handles
Execute unit, functional and other test suites in a docker based test environment. Handles
execution of single test files, sending xdebug information to a local IDE and more.
Recommended docker version is >=20.10 for xdebug break pointing to work reliably, and
@ -49,6 +69,7 @@ Options:
-s <...>
Specifies which test suite to run
- composerInstall: "composer install"
- functional: PHP functional tests
- unit (default): PHP unit tests
-t <9.5|10.4>
@ -58,6 +79,39 @@ Options:
- 9.5
- 10.4
-a <mysqli|pdo_mysql>
Only with -s functional
Specifies to use another driver, following combinations are available:
- mysql
- mysqli (default)
- pdo_mysql
- mariadb
- mysqli (default)
- pdo_mysql
-d <mariadb|mysql>
Only with -s functional
Specifies on which DBMS tests are performed
- mariadb (default): use mariadb
- mysql: use MySQL server
-i <10.1|10.2|10.3|10.4|10.5>
Only with -d mariadb
Specifies on which version of mariadb tests are performed
- 10.1
- 10.2
- 10.3 (default)
- 10.4
- 10.5
-j <5.5|5.6|5.7|8.0>
Only with -d mysql
Specifies on which version of mysql tests are performed
- 5.5 (default)
- 5.6
- 5.7
- 8.0
-p <7.4|8.0|8.1>
Specifies the PHP minor version to be used
- 7.4 (default): use PHP 7.4
@ -65,14 +119,14 @@ Options:
- 8.1: use PHP 8.1
-e "<phpunit options>"
Only with -s unit
Only with -s functional|unit
Additional options to send to phpunit (unit & functional tests) or codeception (acceptance
tests). For phpunit, options starting with "--" must be added after options starting with "-".
Example -e "-v --filter canDoEverything" to enable verbose output AND filter tests
named "canDoEverything"
-x
Only with -s unit
Only with -s functional|unit
Send information to host instance for test or system under test break points. This is especially
useful if a local PhpStorm instance is listening on default xdebug port 9003. A different port
can be selected with -y
@ -129,11 +183,15 @@ fi
# Option defaults
TEST_SUITE="unit"
TYPO3_VERSION=""
DBMS="mariadb"
PHP_VERSION="7.4"
PHP_XDEBUG_ON=0
PHP_XDEBUG_PORT=9003
EXTRA_TEST_OPTIONS=""
SCRIPT_VERBOSE=0
DATABASE_DRIVER=""
MARIADB_VERSION="10.3"
MYSQL_VERSION="5.5"
# Option parsing
# Reset in case getopts has been used previously in the shell
@ -141,7 +199,7 @@ OPTIND=1
# Array for invalid options
INVALID_OPTIONS=();
# Simple option parsing based on getopts (! not getopt)
while getopts ":s:t:p:e:xy:huv" OPT; do
while getopts ":a:s:t:d:i:j:p:e:xy:huv" OPT; do
case ${OPT} in
s)
TEST_SUITE=${OPTARG}
@ -149,6 +207,24 @@ while getopts ":s:t:p:e:xy:huv" OPT; do
t)
TYPO3_VERSION=${OPTARG}
;;
a)
DATABASE_DRIVER=${OPTARG}
;;
d)
DBMS=${OPTARG}
;;
i)
MARIADB_VERSION=${OPTARG}
if ! [[ ${MARIADB_VERSION} =~ ^(10.1|10.2|10.3|10.4|10.5)$ ]]; then
INVALID_OPTIONS+=("${OPTARG}")
fi
;;
j)
MYSQL_VERSION=${OPTARG}
if ! [[ ${MYSQL_VERSION} =~ ^(5.5|5.6|5.7|8.0)$ ]]; then
INVALID_OPTIONS+=("${OPTARG}")
fi
;;
p)
PHP_VERSION=${OPTARG}
if ! [[ ${PHP_VERSION} =~ ^(7.4|8.0|8.1)$ ]]; then
@ -213,6 +289,23 @@ case ${TEST_SUITE} in
SUITE_EXIT_CODE=$?
docker-compose down
;;
functional)
handleDbmsAndDriverOptions
setUpDockerComposeDotEnv
case ${DBMS} in
mariadb|mysql)
echo "Using driver: ${DATABASE_DRIVER}"
docker-compose run functional
SUITE_EXIT_CODE=$?
;;
*)
echo "Functional tests don't run with DBMS ${DBMS}" >&2
echo >&2
echo "call \".Build/Test/runTests.sh -h\" to display help and valid options" >&2
exit 1
esac
docker-compose down
;;
unit)
setUpDockerComposeDotEnv
docker-compose run unit
@ -232,6 +325,18 @@ case ${TEST_SUITE} in
exit 1
esac
case ${DBMS} in
mariadb)
DBMS_OUTPUT="DBMS: ${DBMS} version ${MARIADB_VERSION} driver ${DATABASE_DRIVER}"
;;
mysql)
DBMS_OUTPUT="DBMS: ${DBMS} version ${MYSQL_VERSION} driver ${DATABASE_DRIVER}"
;;
*)
DBMS_OUTPUT="DBMS not recognized: $DBMS"
exit 1
esac
# Print summary
if [ ${SCRIPT_VERBOSE} -eq 1 ]; then
# Turn off verbose mode for the script summary
@ -239,8 +344,14 @@ if [ ${SCRIPT_VERBOSE} -eq 1 ]; then
fi
echo "" >&2
echo "###########################################################################" >&2
echo "Result of ${TEST_SUITE}" >&2
echo "PHP: ${PHP_VERSION}" >&2
if [[ ${TEST_SUITE} =~ ^(functional)$ ]]; then
echo "Result of ${TEST_SUITE}" >&2
echo "PHP: ${PHP_VERSION}" >&2
echo "${DBMS_OUTPUT}" >&2
else
echo "Result of ${TEST_SUITE}" >&2
echo "PHP: ${PHP_VERSION}" >&2
fi
if [[ ${SUITE_EXIT_CODE} -eq 0 ]]; then
echo "SUCCESS" >&2

View File

@ -32,7 +32,7 @@ https://docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/ApiOverview/Paginati
## Testing
Before running the tests, please install the project dependencies. Choose which version of TYPO3 you would like to test against.
Before running any of the tests, please install the project dependencies. Choose which version of TYPO3 you would like to test against.
```bash
# (a)
@ -47,11 +47,15 @@ composer update --with=typo3/cms-core:^10.4
```bash
# Run all tests
composer test
# Run specific kind of tests
composer test:unit
composer test:func
```
### Run Tests Manually
Tests may be run either via a locally installed Composer / PHP setup, or within a Docker container.
Unit tests may be run either via a locally installed Composer / PHP setup, or within a Docker container.
```bash
# Run locally
@ -61,6 +65,12 @@ vendor/bin/phpunit -c Build/Test/UnitTests.xml
Build/Test/runTests.sh
```
Functional tests may only be run in Docker as they require more infrastructure to be set up.
```bash
Build/Test/runTests.sh -s functional
```
To learn about available options (e.g., to select the PHP version), check the usage info:
```bash
@ -73,13 +83,19 @@ You may also interact with the Docker containers directly:
cd Build/Test/
vim .env # Edit configuration
docker-compose run unit
docker-compose run functional
docker-compose down
```
### Fixtures
- When writing datasets, please use `uid`s that are easy to search (`grep`) for.
### File Structure
- `Build/Test/`: Test-related setup files (e.g. configuration for PHPUnit and testing container)
- `Tests/`: Test cases. In unit tests, namespacing follows the structure of `Classes/`.
- `Tests/Fixtures`: Datasets to use in functional tests.
### External Links

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<tx_dlf_documents>
<uid>1001</uid>
<pid>20000</pid>
<tstamp>1631775000</tstamp>
<crdate>1631775000</crdate>
<cruser_id>2</cruser_id>
<deleted>0</deleted>
<hidden>0</hidden>
<starttime>0</starttime>
<endtime>0</endtime>
<fe_group />
<prod_id />
<location>https://digital.slub-dresden.de/data/kitodo/10Kepi_476251419/10Kepi_476251419_mets.xml</location>
<record_id>oai:de:slub-dresden:db:id-476251419</record_id>
<opac_id>476251419</opac_id>
<union_id>476251419</union_id>
<urn>urn:nbn:de:bsz:14-db-id4762514197</urn>
<purl>http://digital.slub-dresden.de/id476251419</purl>
<title>10 Keyboard pieces - Go. S. 658</title>
<title_sorting>10 Keyboard pieces - Go. S. 658</title_sorting>
<author />
<year>[1759-1800]</year>
<place>[S.l.]</place>
<thumbnail>https://digital.slub-dresden.de/data/kitodo/10Kepi_476251419/10Kepi_476251419_tif/jpegs/00000003.tif.thumbnail.jpg</thumbnail>
<structure>59</structure>
<partof>0</partof>
<volume />
<volume_sorting />
<license />
<terms />
<restrictions />
<out_of_print />
<rights_info />
<collections />
<mets_label>10 Keyboard pieces - Go. S. 658</mets_label>
<mets_orderlabel>10 Keyboard pieces - Go. S. 658</mets_orderlabel>
<owner>10001</owner>
<solrcore>1</solrcore>
<status>0</status>
<document_format>METS</document_format>
</tx_dlf_documents>
<tx_dlf_documents>
<uid>1002</uid>
<pid>20000</pid>
<tstamp>1631774000</tstamp>
<crdate>1631774000</crdate>
<cruser_id>2</cruser_id>
<deleted>0</deleted>
<hidden>0</hidden>
<starttime>0</starttime>
<endtime>0</endtime>
<fe_group />
<prod_id />
<location>https://digital.slub-dresden.de/data/kitodo/6Saso_476248086/6Saso_476248086_mets.xml</location>
<record_id>oai:de:slub-dresden:db:id-476248086</record_id>
<opac_id>476248086</opac_id>
<union_id>476248086</union_id>
<urn>urn:nbn:de:bsz:14-db-id4762480864</urn>
<purl>http://digital.slub-dresden.de/id476248086</purl>
<title>6 Sacred songs - Go. S. 591</title>
<title_sorting>6 Sacred songs - Go. S. 591</title_sorting>
<author />
<year>[1840-1860]</year>
<place>[S.l.]</place>
<thumbnail>https://digital.slub-dresden.de/data/kitodo/6Saso_476248086/6Saso_476248086_tif/jpegs/00000001.tif.thumbnail.jpg</thumbnail>
<structure>59</structure>
<partof>0</partof>
<volume />
<volume_sorting />
<license />
<terms />
<restrictions />
<out_of_print />
<rights_info />
<collections />
<mets_label>6 Sacred songs - Go. S. 591</mets_label>
<mets_orderlabel>6 Sacred songs - Go. S. 591</mets_orderlabel>
<owner>10001</owner>
<solrcore>1</solrcore>
<status>0</status>
<document_format>METS</document_format>
</tx_dlf_documents>
<tx_dlf_documents>
<uid>1003</uid>
<pid>20000</pid>
<tstamp>1631776000</tstamp>
<crdate>1631776000</crdate>
<cruser_id>2</cruser_id>
<deleted>0</deleted>
<hidden>0</hidden>
<starttime>0</starttime>
<endtime>0</endtime>
<fe_group />
<prod_id />
<location>https://digital.slub-dresden.de/data/kitodo/6FuG_476251729/6FuG_476251729_mets.xml</location>
<record_id>oai:de:slub-dresden:db:id-476251729</record_id>
<opac_id>476251729</opac_id>
<union_id>476251729</union_id>
<urn>urn:nbn:de:bsz:14-db-id4762517292</urn>
<purl>http://digital.slub-dresden.de/id476251729</purl>
<title>6 Fugues - Go. S. 317</title>
<title_sorting>6 Fugues - Go. S. 317</title_sorting>
<author />
<year>[um 1820]</year>
<place>[S.l.]</place>
<thumbnail>https://digital.slub-dresden.de/data/kitodo/6FuG_476251729/6FuG_476251729_tif/jpegs/00000001.tif.thumbnail.jpg</thumbnail>
<structure>59</structure>
<partof>0</partof>
<volume />
<volume_sorting />
<license />
<terms />
<restrictions />
<out_of_print />
<rights_info />
<collections>3</collections>
<mets_label>6 Fugues - Go. S. 317</mets_label>
<mets_orderlabel>6 Fugues - Go. S. 317</mets_orderlabel>
<owner>10001</owner>
<solrcore>1</solrcore>
<status>0</status>
<document_format>METS</document_format>
</tx_dlf_documents>
<tx_dlf_collections>
<uid>1101</uid>
<pid>20000</pid>
<tstamp>1631279509</tstamp>
<crdate>1631279509</crdate>
<cruser_id>2</cruser_id>
<deleted>0</deleted>
<sys_language_uid>0</sys_language_uid>
<l18n_parent>0</l18n_parent>
<l18n_diffsource>a:8:{s:5:"label";N;s:10:"index_name";N;s:8:"oai_name";N;s:11:"description";N;s:9:"documents";N;s:5:"owner";N;s:6:"status";N;s:16:"sys_language_uid";N;}</l18n_diffsource>
<hidden>0</hidden>
<fe_group />
<l10n_state />
<fe_cruser_id>0</fe_cruser_id>
<fe_admin_lock>0</fe_admin_lock>
<label>Musik</label>
<index_name>Musik</index_name>
<index_search />
<oai_name>music</oai_name>
<description />
<thumbnail />
<priority>3</priority>
<documents>0</documents>
<owner>0</owner>
<status>0</status>
</tx_dlf_collections>
<tx_dlf_relations>
<uid>1201</uid>
<uid_local>1001</uid_local>
<uid_foreign>1101</uid_foreign>
<tablenames />
<sorting />
<sorting_foreign />
<ident>docs_colls</ident>
</tx_dlf_relations>
</dataset>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<tx_dlf_libraries>
<uid>10001</uid>
<pid>20000</pid>
<tstamp>1631193108</tstamp>
<crdate>1631193108</crdate>
<cruser_id>2</cruser_id>
<deleted>0</deleted>
<sys_language_uid>0</sys_language_uid>
<l18n_parent>0</l18n_parent>
<l18n_diffsource>a:12:{s:5:&quot;label&quot;;N;s:10:&quot;index_name&quot;;N;s:7:&quot;website&quot;;N;s:7:&quot;contact&quot;;N;s:5:&quot;image&quot;;N;s:9:&quot;oai_label&quot;;N;s:8:&quot;oai_base&quot;;N;s:10:&quot;opac_label&quot;;N;s:9:&quot;opac_base&quot;;N;s:11:&quot;union_label&quot;;N;s:10:&quot;union_base&quot;;N;s:16:&quot;sys_language_uid&quot;;N;}</l18n_diffsource>
<l10n_state></l10n_state>
<label>Default Library</label>
<index_name>default</index_name>
<website></website>
<contact></contact>
<image></image>
<oai_label></oai_label>
<oai_base></oai_base>
<opac_label></opac_label>
<opac_base></opac_base>
<union_label></union_label>
<union_base></union_base>
</tx_dlf_libraries>
</dataset>

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<!-- Default siteroot -->
<pages>
<uid>19999</uid>
<pid>0</pid>
<tstamp>1644840191</tstamp>
<crdate>1644840051</crdate>
<cruser_id>1</cruser_id>
<deleted>0</deleted>
<hidden>0</hidden>
<starttime>0</starttime>
<endtime>0</endtime>
<fe_group></fe_group>
<sorting>764</sorting>
<rowDescription></rowDescription>
<editlock>0</editlock>
<sys_language_uid>0</sys_language_uid>
<l10n_parent>0</l10n_parent>
<l10n_source>0</l10n_source>
<l10n_state></l10n_state>
<t3_origuid>0</t3_origuid>
<l10n_diffsource>a:47:{s:7:&quot;doktype&quot;;N;s:5:&quot;title&quot;;N;s:4:&quot;slug&quot;;N;s:9:&quot;nav_title&quot;;N;s:8:&quot;subtitle&quot;;N;s:9:&quot;seo_title&quot;;N;s:8:&quot;no_index&quot;;N;s:9:&quot;no_follow&quot;;N;s:14:&quot;canonical_link&quot;;N;s:8:&quot;og_title&quot;;N;s:14:&quot;og_description&quot;;N;s:8:&quot;og_image&quot;;N;s:13:&quot;twitter_title&quot;;N;s:19:&quot;twitter_description&quot;;N;s:13:&quot;twitter_image&quot;;N;s:8:&quot;abstract&quot;;N;s:8:&quot;keywords&quot;;N;s:11:&quot;description&quot;;N;s:6:&quot;author&quot;;N;s:12:&quot;author_email&quot;;N;s:11:&quot;lastUpdated&quot;;N;s:6:&quot;layout&quot;;N;s:8:&quot;newUntil&quot;;N;s:14:&quot;backend_layout&quot;;N;s:25:&quot;backend_layout_next_level&quot;;N;s:16:&quot;content_from_pid&quot;;N;s:6:&quot;target&quot;;N;s:13:&quot;cache_timeout&quot;;N;s:10:&quot;cache_tags&quot;;N;s:11:&quot;is_siteroot&quot;;N;s:9:&quot;no_search&quot;;N;s:13:&quot;php_tree_stop&quot;;N;s:6:&quot;module&quot;;N;s:5:&quot;media&quot;;N;s:17:&quot;tsconfig_includes&quot;;N;s:8:&quot;TSconfig&quot;;N;s:8:&quot;l18n_cfg&quot;;N;s:6:&quot;hidden&quot;;N;s:8:&quot;nav_hide&quot;;N;s:9:&quot;starttime&quot;;N;s:7:&quot;endtime&quot;;N;s:16:&quot;extendToSubpages&quot;;N;s:8:&quot;fe_group&quot;;N;s:13:&quot;fe_login_mode&quot;;N;s:8:&quot;editlock&quot;;N;s:10:&quot;categories&quot;;N;s:14:&quot;rowDescription&quot;;N;}</l10n_diffsource>
<t3ver_oid>0</t3ver_oid>
<t3ver_wsid>0</t3ver_wsid>
<t3ver_state>0</t3ver_state>
<t3ver_stage>0</t3ver_stage>
<t3ver_count>0</t3ver_count>
<t3ver_tstamp>0</t3ver_tstamp>
<t3ver_move_id>0</t3ver_move_id>
<perms_userid>1</perms_userid>
<perms_groupid>0</perms_groupid>
<perms_user>31</perms_user>
<perms_group>27</perms_group>
<perms_everybody>0</perms_everybody>
<title>DLF Testing Site</title>
<slug>/</slug>
<doktype>254</doktype>
<TSconfig></TSconfig>
<is_siteroot>1</is_siteroot>
<php_tree_stop>0</php_tree_stop>
<url></url>
<shortcut>0</shortcut>
<shortcut_mode>0</shortcut_mode>
<subtitle></subtitle>
<layout>0</layout>
<target></target>
<media>0</media>
<lastUpdated>0</lastUpdated>
<keywords></keywords>
<cache_timeout>0</cache_timeout>
<cache_tags></cache_tags>
<newUntil>0</newUntil>
<description></description>
<no_search>0</no_search>
<SYS_LASTCHANGED>1644840191</SYS_LASTCHANGED>
<abstract></abstract>
<module></module>
<extendToSubpages>0</extendToSubpages>
<author></author>
<author_email></author_email>
<nav_title></nav_title>
<nav_hide>0</nav_hide>
<content_from_pid>0</content_from_pid>
<mount_pid>0</mount_pid>
<mount_pid_ol>0</mount_pid_ol>
<l18n_cfg>0</l18n_cfg>
<fe_login_mode>0</fe_login_mode>
<backend_layout></backend_layout>
<backend_layout_next_level></backend_layout_next_level>
<tsconfig_includes></tsconfig_includes>
<legacy_overlay_uid>0</legacy_overlay_uid>
<categories>0</categories>
</pages>
<!-- Default data folder -->
<pages>
<uid>20000</uid>
<pid>19999</pid>
<tstamp>1644840191</tstamp>
<crdate>1644840051</crdate>
<cruser_id>1</cruser_id>
<deleted>0</deleted>
<hidden>0</hidden>
<starttime>0</starttime>
<endtime>0</endtime>
<fe_group></fe_group>
<sorting>764</sorting>
<rowDescription></rowDescription>
<editlock>0</editlock>
<sys_language_uid>0</sys_language_uid>
<l10n_parent>0</l10n_parent>
<l10n_source>0</l10n_source>
<l10n_state></l10n_state>
<t3_origuid>0</t3_origuid>
<l10n_diffsource>a:47:{s:7:&quot;doktype&quot;;N;s:5:&quot;title&quot;;N;s:4:&quot;slug&quot;;N;s:9:&quot;nav_title&quot;;N;s:8:&quot;subtitle&quot;;N;s:9:&quot;seo_title&quot;;N;s:8:&quot;no_index&quot;;N;s:9:&quot;no_follow&quot;;N;s:14:&quot;canonical_link&quot;;N;s:8:&quot;og_title&quot;;N;s:14:&quot;og_description&quot;;N;s:8:&quot;og_image&quot;;N;s:13:&quot;twitter_title&quot;;N;s:19:&quot;twitter_description&quot;;N;s:13:&quot;twitter_image&quot;;N;s:8:&quot;abstract&quot;;N;s:8:&quot;keywords&quot;;N;s:11:&quot;description&quot;;N;s:6:&quot;author&quot;;N;s:12:&quot;author_email&quot;;N;s:11:&quot;lastUpdated&quot;;N;s:6:&quot;layout&quot;;N;s:8:&quot;newUntil&quot;;N;s:14:&quot;backend_layout&quot;;N;s:25:&quot;backend_layout_next_level&quot;;N;s:16:&quot;content_from_pid&quot;;N;s:6:&quot;target&quot;;N;s:13:&quot;cache_timeout&quot;;N;s:10:&quot;cache_tags&quot;;N;s:11:&quot;is_siteroot&quot;;N;s:9:&quot;no_search&quot;;N;s:13:&quot;php_tree_stop&quot;;N;s:6:&quot;module&quot;;N;s:5:&quot;media&quot;;N;s:17:&quot;tsconfig_includes&quot;;N;s:8:&quot;TSconfig&quot;;N;s:8:&quot;l18n_cfg&quot;;N;s:6:&quot;hidden&quot;;N;s:8:&quot;nav_hide&quot;;N;s:9:&quot;starttime&quot;;N;s:7:&quot;endtime&quot;;N;s:16:&quot;extendToSubpages&quot;;N;s:8:&quot;fe_group&quot;;N;s:13:&quot;fe_login_mode&quot;;N;s:8:&quot;editlock&quot;;N;s:10:&quot;categories&quot;;N;s:14:&quot;rowDescription&quot;;N;}</l10n_diffsource>
<t3ver_oid>0</t3ver_oid>
<t3ver_wsid>0</t3ver_wsid>
<t3ver_state>0</t3ver_state>
<t3ver_stage>0</t3ver_stage>
<t3ver_count>0</t3ver_count>
<t3ver_tstamp>0</t3ver_tstamp>
<t3ver_move_id>0</t3ver_move_id>
<perms_userid>1</perms_userid>
<perms_groupid>0</perms_groupid>
<perms_user>31</perms_user>
<perms_group>27</perms_group>
<perms_everybody>0</perms_everybody>
<title>Data</title>
<slug>/data</slug>
<doktype>254</doktype>
<TSconfig></TSconfig>
<is_siteroot>0</is_siteroot>
<php_tree_stop>0</php_tree_stop>
<url></url>
<shortcut>0</shortcut>
<shortcut_mode>0</shortcut_mode>
<subtitle></subtitle>
<layout>0</layout>
<target></target>
<media>0</media>
<lastUpdated>0</lastUpdated>
<keywords></keywords>
<cache_timeout>0</cache_timeout>
<cache_tags></cache_tags>
<newUntil>0</newUntil>
<description></description>
<no_search>0</no_search>
<SYS_LASTCHANGED>1644840191</SYS_LASTCHANGED>
<abstract></abstract>
<module></module>
<extendToSubpages>0</extendToSubpages>
<author></author>
<author_email></author_email>
<nav_title></nav_title>
<nav_hide>0</nav_hide>
<content_from_pid>0</content_from_pid>
<mount_pid>0</mount_pid>
<mount_pid_ol>0</mount_pid_ol>
<l18n_cfg>0</l18n_cfg>
<fe_login_mode>0</fe_login_mode>
<backend_layout></backend_layout>
<backend_layout_next_level></backend_layout_next_level>
<tsconfig_includes></tsconfig_includes>
<legacy_overlay_uid>0</legacy_overlay_uid>
<categories>0</categories>
</pages>
</dataset>

View File

@ -0,0 +1,66 @@
<?php
namespace Kitodo\Dlf\Tests\Functional;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
/**
* Base class for functional test cases. This provides some common configuration
* and collects utility methods for functional tests.
*/
class FunctionalTestCase extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
{
protected $testExtensionsToLoad = [
'typo3conf/ext/dlf',
];
protected $configurationToUseInTestInstance = [
'SYS' => [
'caching' => [
'cacheConfigurations' => [
'tx_dlf_doc' => [
'backend' => \TYPO3\CMS\Core\Cache\Backend\NullBackend::class,
],
],
],
],
'EXTENSIONS' => [
'dlf' => [], // = $this->getDlfConfiguration(), set in constructor
],
];
/** @var ObjectManager */
protected $objectManager;
public function __construct()
{
parent::__construct();
$this->configurationToUseInTestInstance['EXTENSIONS']['dlf'] = $this->getDlfConfiguration();
}
public function setUp(): void
{
parent::setUp();
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
}
protected function getDlfConfiguration()
{
return [];
}
protected function initializeRepository(string $className, int $storagePid)
{
$repository = $this->objectManager->get($className);
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
$querySettings->setStoragePageIds([$storagePid]);
$repository->setDefaultQuerySettings($querySettings);
return $repository;
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace Kitodo\Dlf\Tests\Functional\Repository;
use Kitodo\Dlf\Common\Doc;
use Kitodo\Dlf\Common\MetsDocument;
use Kitodo\Dlf\Domain\Repository\DocumentRepository;
use Kitodo\Dlf\Tests\Functional\FunctionalTestCase;
use TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage;
class DocumentRepositoryTest extends FunctionalTestCase
{
/**
* @var DocumentRepository
*/
protected $documentRepository;
public function setUp(): void
{
parent::setUp();
$this->documentRepository = $this->initializeRepository(DocumentRepository::class, 20000);
$this->importDataSet(__DIR__ . '/../../Fixtures/Common/documents_1.xml');
$this->importDataSet(__DIR__ . '/../../Fixtures/Common/pages.xml');
$this->importDataSet(__DIR__ . '/../../Fixtures/Common/libraries.xml');
}
/**
* @test
*/
public function canRetrieveDocument(): void
{
$document = $this->documentRepository->findByUid(1001);
$this->assertNotNull($document);
$this->assertEquals('METS', $document->getDocumentFormat());
$this->assertNotEmpty($document->getTitle());
$this->assertEquals('Default Library', $document->getOwner()->getLabel());
$doc = Doc::getInstance($document->getLocation());
$this->assertInstanceOf(MetsDocument::class, $doc);
}
/**
* @test
*/
public function canFindOldestDocument(): void
{
$document = $this->documentRepository->findOldestDocument();
$this->assertNotNull($document);
$this->assertEquals(1002, $document->getUid());
}
/**
* @test
*/
public function canGetCollectionsOfDocument(): void
{
$document = $this->documentRepository->findByUid(1001);
$collections = $document->getCollections();
$this->assertInstanceOf(LazyObjectStorage::class, $collections);
$collectionsByLabel = [];
foreach ($collections as $collection) {
$collectionsByLabel[$collection->getLabel()] = $collection;
}
$this->assertArrayHasKey('Musik', $collectionsByLabel);
}
}

View File

@ -71,7 +71,12 @@
"rm -f public/typo3conf/ext/dlf",
"ln -s ../../../ public/typo3conf/ext/dlf"
],
"test": "phpunit -c Build/Test/UnitTests.xml",
"test": [
"@test:unit",
"@test:func"
],
"test:unit": "phpunit -c Build/Test/UnitTests.xml",
"test:func": "Build/Test/runTests.sh -s functional",
"docs:db": "./Build/Documentation/dbdocs/generate.php ./Documentation/Developers/Database.rst",
"docs:setup": "./Build/Documentation/sphinx.sh install",
"docs:serve": "./Build/Documentation/sphinx.sh serve",