diff --git a/.env.dist b/.env.dist
index 6a714de3..3e7a4dea 100644
--- a/.env.dist
+++ b/.env.dist
@@ -1,36 +1,30 @@
-# This file is a "template" of which env vars need to be defined for your application
-# Copy this file to .env file for development, create environment variables when deploying to production
-# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
+### DATABASE CONFIGURATION
+# Replace "user", "password" and "database" with your database connection.
+# Configure the server version, MariaDB requires the "mariadb-" prefix, eg:
+# for MySQL "serverVersion=5.7" and for MariaDB "serverVersion=mariadb-10.5.8"
+DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8&serverVersion=5.7
-###> symfony/framework-bundle ###
+### EMAIL CONFIGURATION
+# Emails will be sent "from":
+MAILER_FROM=kimai@example.com
+
+# Email connection (disabled by default with MAILER_URL=null://null)
+# SMTP: smtp://localhost:25?encryption=&auth_mode=
+# Google: gmail://username:password@default
+# Amazon: ses://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1
+# Mailchimp: mandrill://KEY@default
+# Mailgun: mailgun://KEY:DOMAIN@default
+# Postmark: postmark://ID@default
+# Sendgrid: sendgrid://KEY@default
+# Disable emails: null://null
+MAILER_URL=null://null
+
+### APPLICATION CONFIGURATION
APP_ENV=prod
APP_SECRET=change_this_to_something_unique
-#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
-#TRUSTED_HOSTS=localhost,example.com
-###< symfony/framework-bundle ###
-###> doctrine/doctrine-bundle ###
-# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
-# For a MySQL database, use: "mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=10.2.12&charset=utf8"
-# For a MariaDB database, use: "mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=mariadb-10.2.12"
-# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data/kimai.sqlite"
-# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
-# DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
-DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/kimai.sqlite
-###< doctrine/doctrine-bundle ###
-
-###> nelmio/cors-bundle ###
+# Running in a "special" environment, eg. behind reverse proxies?
+# Check those:
+# TRUSTED_PROXIES=127.0.0.1,127.0.0.2
+# TRUSTED_HOSTS=localhost,example.com
CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$
-###< nelmio/cors-bundle ###
-
-### Email configuration
-# SMTP: smtp://localhost:25?encryption=&auth_mode=
-# Google: gmail://username:password@default
-# Amazon: ses://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1
-# Mailchimp: mandrill://KEY@default
-# Mailgun: mailgun://KEY:DOMAIN@default
-# Postmark: postmark://ID@default
-# Sendgrid: sendgrid://KEY@default
-# Disable emails: null://null
-MAILER_URL=null://null
-MAILER_FROM=kimai@example.com
diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml
index 9e20e5e3..037346c8 100644
--- a/.github/workflows/coverage.yaml
+++ b/.github/workflows/coverage.yaml
@@ -7,6 +7,16 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
+ services:
+ mysql:
+ image: mysql:5.7
+ env:
+ MYSQL_ALLOW_EMPTY_PASSWORD: false
+ MYSQL_ROOT_PASSWORD: kimai
+ MYSQL_DATABASE: kimai
+ ports:
+ - 3306/tcp
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
matrix:
php: ['7.3']
@@ -18,7 +28,7 @@ jobs:
with:
php-version: ${{ matrix.php }}
coverage: pcov
- extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, zip, gd, ldap
+ extensions: mbstring, xml, ctype, iconv, intl, mysql, zip, gd, ldap
- run: |
composer install --no-progress
composer require laminas/laminas-ldap
@@ -27,6 +37,9 @@ jobs:
- name: Run tests
run: vendor/bin/phpunit tests/ --coverage-clover=coverage.xml
env:
+ DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?serverVersion=5.7
+ APP_ENV: dev
+ MAILER_URL: null://localhost
TEST_WITH_BUNDLES: 1
- name: Upload code coverage
uses: codecov/codecov-action@v1
diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml
index dd6b24e7..b564db2a 100644
--- a/.github/workflows/linting.yaml
+++ b/.github/workflows/linting.yaml
@@ -18,7 +18,7 @@ jobs:
with:
php-version: ${{ matrix.php }}
coverage: none
- extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, zip, gd, ldap
+ extensions: mbstring, xml, ctype, iconv, intl, mysql, zip, gd, ldap
tools: cs2pr:1.1.0
- run: composer install --no-progress
- run: composer validate --strict
diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml
index 73dc59f0..77bfb82f 100644
--- a/.github/workflows/testing.yaml
+++ b/.github/workflows/testing.yaml
@@ -28,7 +28,7 @@ jobs:
with:
php-version: ${{ matrix.php }}
coverage: none
- extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, zip, gd, ldap
+ extensions: mbstring, xml, ctype, iconv, intl, mysql, zip, gd, ldap
- run: |
composer install --no-progress
composer require laminas/laminas-ldap
@@ -36,23 +36,22 @@ jobs:
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Run unit tests
run: composer kimai:tests-unit
+ env:
+ DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?serverVersion=5.7
+ APP_ENV: dev
+ MAILER_URL: null://localhost
+ - name: Run integration tests
+ run: composer kimai:tests-integration
+ env:
+ DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?serverVersion=5.7
+ APP_ENV: dev
+ MAILER_URL: null://localhost
- name: Run migrations on MySQL
run: |
bin/console doctrine:database:create --if-not-exists -n
bin/console doctrine:migrations:migrate -n
bin/console doctrine:migrations:migrate first -n
env:
- DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai
+ DATABASE_URL: mysql://root:kimai@127.0.0.1:${{ job.services.mysql.ports['3306'] }}/kimai?serverVersion=5.7
APP_ENV: dev
MAILER_URL: null://localhost
- - name: Run migrations on SQLite
- run: |
- bin/console doctrine:database:create -n
- bin/console doctrine:migrations:migrate -n
- bin/console doctrine:migrations:migrate first -n
- env:
- DATABASE_URL: sqlite:///%kernel.project_dir%/var/data/kimai_migrations.sqlite
- APP_ENV: dev
- MAILER_URL: null://localhost
- - name: Run integration tests
- run: composer kimai:tests-integration
diff --git a/.gitignore b/.gitignore
index 51fbae3d..5f50362e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@ translations/branding.en.xlf
/var/data/*
!/var/data/.gitkeep
-!/var/data/kimai_test.sqlite
/var/coverage/
/var/cache/*
!var/cache/.gitkeep
diff --git a/README.md b/README.md
index 6176028c..1245b538 100644
--- a/README.md
+++ b/README.md
@@ -27,10 +27,10 @@ It is built with modern technologies such as Symfony, Bootstrap, RESTful API, Do
### Requirements
- PHP 7.2.9 or higher
-- Database (MySQL/MariaDB, SQLite for development)
+- MariaDB or MySQL
- Webserver (nginx, Apache)
- A modern browser
-- [Other libraries](https://www.kimai.org/download/)
+- Some PHP extensions, see [composer.json](composer.json) or [here](https://www.kimai.org/download/)
### About
@@ -47,7 +47,6 @@ user specific rates, advanced search & filtering, money and time budgets with re
- [Docker](https://www.kimai.org/documentation/docker.html) - containerized
- [Development](https://www.kimai.org/documentation/installation.html#development-installation) - on your local machine
- [1-click installer](https://www.kimai.org/documentation/installation.html#hosting-and-1-click-installations) - hosted environments
-- [FTP](https://www.kimai.org/documentation/installation.html#ftp-installation) - unfortunately still widely used ;-)
### Updating Kimai
diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml
index 17b60cca..58dbf864 100644
--- a/config/packages/doctrine.yaml
+++ b/config/packages/doctrine.yaml
@@ -13,8 +13,7 @@ doctrine:
default:
# existing migrations will fail if the schema filter is activated
#schema_filter: ~^(?!(bundle_migration_|kimai2_sessions))~
- # Removing "resolve:" would fail eg. SQLite URLs
- url: '%env(resolve:DATABASE_URL)%'
+ url: '%env(DATABASE_URL)%'
driver: 'pdo_mysql'
# this setting prevents automatic database detection and finds a lot of false-negatives on doctrine:migrations:diff
# for null columns with MariaDB. Each migration tries to convert EVERY nullable column.
@@ -40,3 +39,125 @@ doctrine:
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Kimai
+ dql:
+ datetime_functions:
+ addtime: DoctrineExtensions\Query\Mysql\AddTime
+ convert_tz: DoctrineExtensions\Query\Mysql\ConvertTz
+ date: DoctrineExtensions\Query\Mysql\Date
+ date_format: DoctrineExtensions\Query\Mysql\DateFormat
+ dateadd: DoctrineExtensions\Query\Mysql\DateAdd
+ datesub: DoctrineExtensions\Query\Mysql\DateSub
+ datediff: DoctrineExtensions\Query\Mysql\DateDiff
+ day: DoctrineExtensions\Query\Mysql\Day
+ dayname: DoctrineExtensions\Query\Mysql\DayName
+ dayofweek: DoctrineExtensions\Query\Mysql\DayOfWeek
+ dayofyear: DoctrineExtensions\Query\Mysql\DayOfYear
+ div: DoctrineExtensions\Query\Mysql\Div
+ from_unixtime: DoctrineExtensions\Query\Mysql\FromUnixtime
+ hour: DoctrineExtensions\Query\Mysql\Hour
+ last_day: DoctrineExtensions\Query\Mysql\LastDay
+ makedate: DoctrineExtensions\Query\Mysql\MakeDate
+ minute: DoctrineExtensions\Query\Mysql\Minute
+ now: DoctrineExtensions\Query\Mysql\Now
+ month: DoctrineExtensions\Query\Mysql\Month
+ monthname: DoctrineExtensions\Query\Mysql\MonthName
+ period_diff: DoctrineExtensions\Query\Mysql\PeriodDiff
+ second: DoctrineExtensions\Query\Mysql\Second
+ sectotime: DoctrineExtensions\Query\Mysql\SecToTime
+ strtodate: DoctrineExtensions\Query\Mysql\StrToDate
+ time: DoctrineExtensions\Query\Mysql\Time
+ timediff: DoctrineExtensions\Query\Mysql\TimeDiff
+ timestampadd: DoctrineExtensions\Query\Mysql\TimestampAdd
+ timestampdiff: DoctrineExtensions\Query\Mysql\TimestampDiff
+ timetosec: DoctrineExtensions\Query\Mysql\TimeToSec
+ truncate: DoctrineExtensions\Query\Mysql\Truncate
+ week: DoctrineExtensions\Query\Mysql\Week
+ weekday: DoctrineExtensions\Query\Mysql\WeekDay
+ year: DoctrineExtensions\Query\Mysql\Year
+ yearmonth: DoctrineExtensions\Query\Mysql\YearMonth
+ yearweek: DoctrineExtensions\Query\Mysql\YearWeek
+ unix_timestamp: DoctrineExtensions\Query\Mysql\UnixTimestamp
+ utc_timestamp: DoctrineExtensions\Query\Mysql\UtcTimestamp
+ extract: DoctrineExtensions\Query\Mysql\Extract
+
+ numeric_functions:
+ acos: DoctrineExtensions\Query\Mysql\Acos
+ asin: DoctrineExtensions\Query\Mysql\Asin
+ atan2: DoctrineExtensions\Query\Mysql\Atan2
+ atan: DoctrineExtensions\Query\Mysql\Atan
+ bit_count: DoctrineExtensions\Query\Mysql\BitCount
+ bit_xor: DoctrineExtensions\Query\Mysql\BitXor
+ ceil: DoctrineExtensions\Query\Mysql\Ceil
+ cos: DoctrineExtensions\Query\Mysql\Cos
+ cot: DoctrineExtensions\Query\Mysql\Cot
+ degrees: DoctrineExtensions\Query\Mysql\Degrees
+ exp: DoctrineExtensions\Query\Mysql\Exp
+ floor: DoctrineExtensions\Query\Mysql\Floor
+ json_contains: DoctrineExtensions\Query\Mysql\JsonContains
+ json_depth: DoctrineExtensions\Query\Mysql\JsonDepth
+ json_length: DoctrineExtensions\Query\Mysql\JsonLength
+ log: DoctrineExtensions\Query\Mysql\Log
+ log10: DoctrineExtensions\Query\Mysql\Log10
+ log2: DoctrineExtensions\Query\Mysql\Log2
+ pi: DoctrineExtensions\Query\Mysql\Pi
+ power: DoctrineExtensions\Query\Mysql\Power
+ quarter: DoctrineExtensions\Query\Mysql\Quarter
+ radians: DoctrineExtensions\Query\Mysql\Radians
+ rand: DoctrineExtensions\Query\Mysql\Rand
+ round: DoctrineExtensions\Query\Mysql\Round
+ stddev: DoctrineExtensions\Query\Mysql\StdDev
+ sin: DoctrineExtensions\Query\Mysql\Sin
+ std: DoctrineExtensions\Query\Mysql\Std
+ tan: DoctrineExtensions\Query\Mysql\Tan
+ variance: DoctrineExtensions\Query\Mysql\Variance
+
+ string_functions:
+ aes_decrypt: DoctrineExtensions\Query\Mysql\AesDecrypt
+ aes_encrypt: DoctrineExtensions\Query\Mysql\AesEncrypt
+ any_value: DoctrineExtensions\Query\Mysql\AnyValue
+ ascii: DoctrineExtensions\Query\Mysql\Ascii
+ binary: DoctrineExtensions\Query\Mysql\Binary
+ cast: DoctrineExtensions\Query\Mysql\Cast
+ char_length: DoctrineExtensions\Query\Mysql\CharLength
+ collate: DoctrineExtensions\Query\Mysql\Collate
+ concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
+ countif: DoctrineExtensions\Query\Mysql\CountIf
+ crc32: DoctrineExtensions\Query\Mysql\Crc32
+ degrees: DoctrineExtensions\Query\Mysql\Degrees
+ field: DoctrineExtensions\Query\Mysql\Field
+ find_in_set: DoctrineExtensions\Query\Mysql\FindInSet
+ format: DoctrineExtensions\Query\Mysql\Format
+ from_base64: DoctrineExtensions\Query\Mysql\FromBase64
+ greatest: DoctrineExtensions\Query\Mysql\Greatest
+ group_concat: DoctrineExtensions\Query\Mysql\GroupConcat
+ hex: DoctrineExtensions\Query\Mysql\Hex
+ ifelse: DoctrineExtensions\Query\Mysql\IfElse
+ ifnull: DoctrineExtensions\Query\Mysql\IfNull
+ inet_aton: DoctrineExtensions\Query\Mysql\InetAton
+ inet_ntoa: DoctrineExtensions\Query\Mysql\InetNtoa
+ inet6_aton: DoctrineExtensions\Query\Mysql\Inet6Aton
+ inet6_ntoa: DoctrineExtensions\Query\Mysql\Inet6Ntoa
+ instr: DoctrineExtensions\Query\Mysql\Instr
+ is_ipv4: DoctrineExtensions\Query\Mysql\IsIpv4
+ is_ipv4_compat: DoctrineExtensions\Query\Mysql\IsIpv4Compat
+ is_ipv4_mapped: DoctrineExtensions\Query\Mysql\IsIpv4Mapped
+ is_ipv6: DoctrineExtensions\Query\Mysql\IsIpv6
+ lag: DoctrineExtensions\Query\Mysql\Lag
+ lead: DoctrineExtensions\Query\Mysql\Lead
+ least: DoctrineExtensions\Query\Mysql\Least
+ lpad: DoctrineExtensions\Query\Mysql\Lpad
+ match: DoctrineExtensions\Query\Mysql\MatchAgainst
+ md5: DoctrineExtensions\Query\Mysql\Md5
+ nullif: DoctrineExtensions\Query\Mysql\NullIf
+ over: DoctrineExtensions\Query\Mysql\Over
+ radians: DoctrineExtensions\Query\Mysql\Radians
+ regexp: DoctrineExtensions\Query\Mysql\Regexp
+ replace: DoctrineExtensions\Query\Mysql\Replace
+ rpad: DoctrineExtensions\Query\Mysql\Rpad
+ sha1: DoctrineExtensions\Query\Mysql\Sha1
+ sha2: DoctrineExtensions\Query\Mysql\Sha2
+ soundex: DoctrineExtensions\Query\Mysql\Soundex
+ str_to_date: DoctrineExtensions\Query\Mysql\StrToDate
+ substring_index: DoctrineExtensions\Query\Mysql\SubstringIndex
+ unhex: DoctrineExtensions\Query\Mysql\Unhex
+ uuid_short: DoctrineExtensions\Query\Mysql\UuidShort
diff --git a/config/packages/doctrine/mysql.yaml b/config/packages/doctrine/mysql.yaml
deleted file mode 100644
index d152932d..00000000
--- a/config/packages/doctrine/mysql.yaml
+++ /dev/null
@@ -1,118 +0,0 @@
-doctrine:
- orm:
- dql:
- datetime_functions:
- addtime: DoctrineExtensions\Query\Mysql\AddTime
- date: DoctrineExtensions\Query\Mysql\Date
- date_format: DoctrineExtensions\Query\Mysql\DateFormat
- dateadd: DoctrineExtensions\Query\Mysql\DateAdd
- datesub: DoctrineExtensions\Query\Mysql\DateSub
- datediff: DoctrineExtensions\Query\Mysql\DateDiff
- day: DoctrineExtensions\Query\Mysql\Day
- dayname: DoctrineExtensions\Query\Mysql\DayName
- dayofweek: DoctrineExtensions\Query\Mysql\DayOfWeek
- dayofyear: DoctrineExtensions\Query\Mysql\DayOfYear
- div: DoctrineExtensions\Query\Mysql\Div
- from_unixtime: DoctrineExtensions\Query\Mysql\FromUnixtime
- hour: DoctrineExtensions\Query\Mysql\Hour
- last_day: DoctrineExtensions\Query\Mysql\LastDay
- makedate: DoctrineExtensions\Query\Mysql\MakeDate
- minute: DoctrineExtensions\Query\Mysql\Minute
- now: DoctrineExtensions\Query\Mysql\Now
- month: DoctrineExtensions\Query\Mysql\Month
- monthname: DoctrineExtensions\Query\Mysql\MonthName
- period_diff: DoctrineExtensions\Query\Mysql\PeriodDiff
- second: DoctrineExtensions\Query\Mysql\Second
- sectotime: DoctrineExtensions\Query\Mysql\SecToTime
- strtodate: DoctrineExtensions\Query\Mysql\StrToDate
- time: DoctrineExtensions\Query\Mysql\Time
- timediff: DoctrineExtensions\Query\Mysql\TimeDiff
- timestampadd: DoctrineExtensions\Query\Mysql\TimestampAdd
- timestampdiff: DoctrineExtensions\Query\Mysql\TimestampDiff
- timetosec: DoctrineExtensions\Query\Mysql\TimeToSec
- week: DoctrineExtensions\Query\Mysql\Week
- weekday: DoctrineExtensions\Query\Mysql\WeekDay
- year: DoctrineExtensions\Query\Mysql\Year
- yearmonth: DoctrineExtensions\Query\Mysql\YearMonth
- yearweek: DoctrineExtensions\Query\Mysql\YearWeek
- unix_timestamp: DoctrineExtensions\Query\Mysql\UnixTimestamp
- utc_timestamp: DoctrineExtensions\Query\Mysql\UtcTimestamp
- extract: DoctrineExtensions\Query\Mysql\Extract
-
- numeric_functions:
- acos: DoctrineExtensions\Query\Mysql\Acos
- asin: DoctrineExtensions\Query\Mysql\Asin
- atan2: DoctrineExtensions\Query\Mysql\Atan2
- atan: DoctrineExtensions\Query\Mysql\Atan
- bit_count: DoctrineExtensions\Query\Mysql\BitCount
- bit_xor: DoctrineExtensions\Query\Mysql\BitXor
- ceil: DoctrineExtensions\Query\Mysql\Ceil
- cos: DoctrineExtensions\Query\Mysql\Cos
- cot: DoctrineExtensions\Query\Mysql\Cot
- degrees: DoctrineExtensions\Query\Mysql\Degrees
- exp: DoctrineExtensions\Query\Mysql\Exp
- floor: DoctrineExtensions\Query\Mysql\Floor
- log: DoctrineExtensions\Query\Mysql\Log
- log10: DoctrineExtensions\Query\Mysql\Log10
- log2: DoctrineExtensions\Query\Mysql\Log2
- pi: DoctrineExtensions\Query\Mysql\Pi
- power: DoctrineExtensions\Query\Mysql\Power
- quarter: DoctrineExtensions\Query\Mysql\Quarter
- radians: DoctrineExtensions\Query\Mysql\Radians
- rand: DoctrineExtensions\Query\Mysql\Rand
- round: DoctrineExtensions\Query\Mysql\Round
- stddev: DoctrineExtensions\Query\Mysql\StdDev
- sin: DoctrineExtensions\Query\Mysql\Sin
- std: DoctrineExtensions\Query\Mysql\Std
- tan: DoctrineExtensions\Query\Mysql\Tan
- variance: DoctrineExtensions\Query\Mysql\Variance
-
- string_functions:
- aes_decrypt: DoctrineExtensions\Query\Mysql\AesDecrypt
- aes_encrypt: DoctrineExtensions\Query\Mysql\AesEncrypt
- any_value: DoctrineExtensions\Query\Mysql\AnyValue
- ascii: DoctrineExtensions\Query\Mysql\Ascii
- binary: DoctrineExtensions\Query\Mysql\Binary
- cast: DoctrineExtensions\Query\Mysql\Cast
- char_length: DoctrineExtensions\Query\Mysql\CharLength
- collate: DoctrineExtensions\Query\Mysql\Collate
- concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
- countif: DoctrineExtensions\Query\Mysql\CountIf
- crc32: DoctrineExtensions\Query\Mysql\Crc32
- degrees: DoctrineExtensions\Query\Mysql\Degrees
- field: DoctrineExtensions\Query\Mysql\Field
- find_in_set: DoctrineExtensions\Query\Mysql\FindInSet
- format: DoctrineExtensions\Query\Mysql\Format
- greatest: DoctrineExtensions\Query\Mysql\Greatest
- group_concat: DoctrineExtensions\Query\Mysql\GroupConcat
- hex: DoctrineExtensions\Query\Mysql\Hex
- ifelse: DoctrineExtensions\Query\Mysql\IfElse
- ifnull: DoctrineExtensions\Query\Mysql\IfNull
- inet_aton: DoctrineExtensions\Query\Mysql\InetAton
- inet_ntoa: DoctrineExtensions\Query\Mysql\InetNtoa
- inet6_aton: DoctrineExtensions\Query\Mysql\Inet6Aton
- inet6_ntoa: DoctrineExtensions\Query\Mysql\Inet6Ntoa
- instr: DoctrineExtensions\Query\Mysql\Instr
- is_ipv4: DoctrineExtensions\Query\Mysql\IsIpv4
- is_ipv4_compat: DoctrineExtensions\Query\Mysql\IsIpv4Compat
- is_ipv4_mapped: DoctrineExtensions\Query\Mysql\IsIpv4Mapped
- is_ipv6: DoctrineExtensions\Query\Mysql\IsIpv6
- lag: DoctrineExtensions\Query\Mysql\Lag
- lead: DoctrineExtensions\Query\Mysql\Lead
- least: DoctrineExtensions\Query\Mysql\Least
- lpad: DoctrineExtensions\Query\Mysql\Lpad
- match: DoctrineExtensions\Query\Mysql\MatchAgainst
- md5: DoctrineExtensions\Query\Mysql\Md5
- nullif: DoctrineExtensions\Query\Mysql\NullIf
- over: DoctrineExtensions\Query\Mysql\Over
- radians: DoctrineExtensions\Query\Mysql\Radians
- regexp: DoctrineExtensions\Query\Mysql\Regexp
- replace: DoctrineExtensions\Query\Mysql\Replace
- rpad: DoctrineExtensions\Query\Mysql\Rpad
- sha1: DoctrineExtensions\Query\Mysql\Sha1
- sha2: DoctrineExtensions\Query\Mysql\Sha2
- soundex: DoctrineExtensions\Query\Mysql\Soundex
- str_to_date: DoctrineExtensions\Query\Mysql\StrToDate
- substring_index: DoctrineExtensions\Query\Mysql\SubstringIndex
- unhex: DoctrineExtensions\Query\Mysql\Unhex
- uuid_short: DoctrineExtensions\Query\Mysql\UuidShort
diff --git a/config/packages/doctrine/sqlite.yaml b/config/packages/doctrine/sqlite.yaml
deleted file mode 100644
index 6388865e..00000000
--- a/config/packages/doctrine/sqlite.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-doctrine:
- orm:
- dql:
- datetime_functions:
- date: DoctrineExtensions\Query\Sqlite\Date
- date_format: DoctrineExtensions\Query\Sqlite\DateFormat
- #dateadd: DoctrineExtensions\Query\Sqlite\DateAdd
- #datediff: DoctrineExtensions\Query\Sqlite\DateDiff
- day: DoctrineExtensions\Query\Sqlite\Day
- dayname: DoctrineExtensions\Query\Sqlite\DayName
- hour: DoctrineExtensions\Query\Sqlite\Hour
- julianday: DoctrineExtensions\Query\Sqlite\JulianDay
- minute: DoctrineExtensions\Query\Sqlite\Minute
- #month: DoctrineExtensions\Query\Sqlite\Month
- #monthname: DoctrineExtensions\Query\Sqlite\MonthName
- second: DoctrineExtensions\Query\Sqlite\Second
- month: DoctrineExtensions\Query\Sqlite\Month
- strftime: DoctrineExtensions\Query\Sqlite\StrfTime
- #strtodate: DoctrineExtensions\Query\Sqlite\StrToDate
- #time: DoctrineExtensions\Query\Sqlite\Time
- #timestampadd: DoctrineExtensions\Query\Sqlite\TimestampAdd
- #timestampdiff: DoctrineExtensions\Query\Sqlite\TimestampDiff
- week: DoctrineExtensions\Query\Sqlite\Week
- weekday: DoctrineExtensions\Query\Sqlite\WeekDay
- year: DoctrineExtensions\Query\Sqlite\Year
-
-
- string_functions:
-# binary: DoctrineExtensions\Query\Sqlite\Binary
-# char_length: DoctrineExtensions\Query\Sqlite\CharLength
- concat_ws: DoctrineExtensions\Query\Sqlite\ConcatWs
-# countif: DoctrineExtensions\Query\Sqlite\CountIf
-# crc32: DoctrineExtensions\Query\Sqlite\Crc32
-# degrees: DoctrineExtensions\Query\Sqlite\Degrees
-# field: DoctrineExtensions\Query\Sqlite\Field
-# find_in_set: DoctrineExtensions\Query\Sqlite\FindInSet
-# group_concat: DoctrineExtensions\Query\Sqlite\GroupConcat
- greatest: DoctrineExtensions\Query\Sqlite\Greatest
- ifelse: DoctrineExtensions\Query\Sqlite\IfElse
- ifnull: DoctrineExtensions\Query\Sqlite\IfNull
- least: DoctrineExtensions\Query\Sqlite\Least
-# match: DoctrineExtensions\Query\Sqlite\MatchAgainst
-# md5: DoctrineExtensions\Query\Sqlite\Md5
-# nullif: DoctrineExtensions\Query\Sqlite\NullIf
-# radians: DoctrineExtensions\Query\Sqlite\Radians
- random: DoctrineExtensions\Query\Sqlite\Random
-# regexp: DoctrineExtensions\Query\Sqlite\Regexp
- replace: DoctrineExtensions\Query\Sqlite\Replace
-# sha1: DoctrineExtensions\Query\Sqlite\Sha1
-# sha2: DoctrineExtensions\Query\Sqlite\Sha2
-# soundex: DoctrineExtensions\Query\Sqlite\Soundex
-# uuid_short: DoctrineExtensions\Query\Sqlite\UuidShort
-
- numeric_functions:
- round: DoctrineExtensions\Query\Sqlite\Round
diff --git a/config/services.yaml b/config/services.yaml
index afd331ee..0912c8db 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -104,12 +104,6 @@ services:
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
- # make sure, that sqlite supports foreign keys and cascade deletes
- App\Doctrine\SqliteSessionInitSubscriber:
- class: App\Doctrine\SqliteSessionInitSubscriber
- tags:
- - { name: doctrine.event_listener, event: postConnect }
-
# store and retrieve sessions in and from database
App\Security\SessionHandler:
arguments:
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7acbf535..e5fe6f2f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -5,7 +5,7 @@
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.1/phpunit.xsd"
backupGlobals="false"
colors="true"
- bootstrap="vendor/autoload.php"
+ bootstrap="tests/bootstrap.php"
>
@@ -16,9 +16,25 @@
-
+
+
+
+
+
diff --git a/src/Command/ResetCommand.php b/src/Command/AbstractResetCommand.php
similarity index 84%
rename from src/Command/ResetCommand.php
rename to src/Command/AbstractResetCommand.php
index 32056597..2d1e0a32 100644
--- a/src/Command/ResetCommand.php
+++ b/src/Command/AbstractResetCommand.php
@@ -9,6 +9,7 @@
namespace App\Command;
+use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
@@ -20,23 +21,24 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
- * Command used to execute all the basic application bootstrapping AFTER "composer install" was executed.
- *
- * This command is NOT used during runtime and only meant for developers on their local machines.
- * I am too lazy to think about how this could be tested ... and this is one of the rare edge cases where I don't
- * feel like it is necessary, so I "cheat" with:
+ * Base class for all re-installation commands, which are not used during application runtime.
* @codeCoverageIgnore
*/
-class ResetCommand extends Command
+abstract class AbstractResetCommand extends Command
{
/**
* @var string
*/
private $environment;
+ /**
+ * @var EntityManagerInterface
+ */
+ protected $entityManager;
- public function __construct(string $kernelEnvironment)
+ public function __construct(string $kernelEnvironment, EntityManagerInterface $entityManager)
{
$this->environment = $kernelEnvironment;
+ $this->entityManager = $entityManager;
parent::__construct();
}
@@ -46,11 +48,11 @@ class ResetCommand extends Command
protected function configure()
{
$this
- ->setName('kimai:reset-dev')
+ ->setName('kimai:reset-' . $this->getEnvName())
->setDescription('Resets the dev environment')
->setHelp(
<<-n switch to skip the question.
EOT
)
@@ -81,7 +83,8 @@ EOT
if ($this->askConfirmation($input, $output, 'Do you want to create the database y/N ?')) {
try {
$command = $this->getApplication()->find('doctrine:database:create');
- $command->run(new ArrayInput([]), $output);
+ $options = ['--if-not-exists' => true];
+ $command->run(new ArrayInput($options), $output);
} catch (Exception $ex) {
$io->error('Failed to create database: ' . $ex->getMessage());
@@ -130,12 +133,9 @@ EOT
}
try {
- $command = $this->getApplication()->find('doctrine:fixtures:load');
- $cmdInput = new ArrayInput([]);
- $cmdInput->setInteractive(false);
- $command->run($cmdInput, $output);
+ $this->loadData($input, $output);
} catch (Exception $ex) {
- $io->error('Failed to import fixtures: ' . $ex->getMessage());
+ $io->error('Failed to import data: ' . $ex->getMessage());
return 6;
}
@@ -173,4 +173,8 @@ EOT
return $questionHelper->ask($input, $output, $question);
}
+
+ abstract protected function getEnvName(): string;
+
+ abstract protected function loadData(InputInterface $input, OutputInterface $output): void;
}
diff --git a/src/Command/CreateReleaseCommand.php b/src/Command/CreateReleaseCommand.php
deleted file mode 100644
index 04041b08..00000000
--- a/src/Command/CreateReleaseCommand.php
+++ /dev/null
@@ -1,159 +0,0 @@
-rootDir = realpath($projectDirectory);
- $this->environment = $kernelEnvironment;
- parent::__construct();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function configure()
- {
- $this
- ->setName('kimai:create-release')
- ->setDescription('Create a pre-installed release package')
- ->setHelp('This command will create a release package with pre-installed composer, SQLite database and user.')
- ->addOption('directory', null, InputOption::VALUE_OPTIONAL, 'Directory where the release package will be stored', '/tmp/')
- ->addOption('release', null, InputOption::VALUE_OPTIONAL, 'The version that should be zipped', Constants::VERSION)
- ;
- }
-
- /**
- * Make sure that this command CANNOT be executed in production.
- *
- * @return bool
- */
- public function isEnabled()
- {
- return $this->environment !== 'prod';
- }
-
- /**
- * @param InputInterface $input
- * @param OutputInterface $output
- * @return int|null
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $io = new SymfonyStyle($input, $output);
-
- $directory = $input->getOption('directory');
-
- if ($directory[0] === '/') {
- $directory = realpath($directory);
- } else {
- $directory = realpath($this->rootDir . '/' . $directory);
- }
-
- $tmpDir = $directory . '/' . uniqid('kimai_release_');
-
- if (!is_dir($directory)) {
- $io->error('Given directory is not existing: ' . $directory);
-
- return 1;
- }
-
- if (is_dir($directory) && !is_writable($directory)) {
- $io->error('Cannot write in directory: ' . $directory);
-
- return 1;
- }
-
- $version = $input->getOption('release');
-
- $io->success('Prepare new packages for Kimai ' . $version . ' in ' . $tmpDir);
-
- $gitCmd = sprintf(self::CLONE_CMD, $version);
- $zip = 'kimai-release-' . $version . '.zip';
-
- $prefix = 'APP_ENV=prod DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/kimai.sqlite';
-
- $commands = [
- 'Clone repository' => $gitCmd . ' ' . $tmpDir,
- 'Install composer dependencies' => sprintf('cd %s && %s composer install --no-dev --optimize-autoloader', $tmpDir, $prefix),
- 'Create database' => sprintf('cd %s && %s bin/console kimai:install -n', $tmpDir, $prefix),
- ];
-
- $filesToDelete = [
- '.git*',
- '.codecov.yml',
- '.editorconfig',
- '.php_cs.dist',
- 'phpstan.neon',
- 'phpunit.xml.dist',
- 'webpack.config.js',
- // this seems to be required, see https://github.com/kevinpapst/kimai2/issues/1586
- //'assets/',
- 'tests/',
- 'var/cache/*',
- 'var/data/kimai_test.sqlite',
- 'var/log/*.log',
- 'var/sessions/*',
- ];
-
- foreach ($filesToDelete as $deleteMe) {
- $commands['Delete ' . $deleteMe] = 'cd ' . $tmpDir . ' && rm -rf ' . $deleteMe;
- }
-
- $commands = array_merge($commands, [
- 'Create release zip' => 'cd ' . $tmpDir . ' && zip -q -r ' . $directory . '/' . $zip . ' .',
- 'Remove tmp directory' => 'rm -rf ' . $tmpDir,
- ]);
-
- $exitCode = 0;
- foreach ($commands as $title => $command) {
- passthru($command, $exitCode);
- if ($exitCode !== 0) {
- $io->error('Failed with command: ' . $command);
-
- return -1;
- } else {
- $io->success($title);
- }
- }
-
- $io->success(
- 'New release package available at: ' . PHP_EOL .
- $directory . '/' . $zip
- );
-
- return 0;
- }
-}
diff --git a/src/Command/InstallCommand.php b/src/Command/InstallCommand.php
index 83912c7b..72ff048f 100644
--- a/src/Command/InstallCommand.php
+++ b/src/Command/InstallCommand.php
@@ -24,6 +24,8 @@ use Symfony\Component\HttpKernel\KernelInterface;
/**
* Command used to do the basic installation steps for Kimai.
+ *
+ * @codeCoverageIgnore
*/
final class InstallCommand extends Command
{
@@ -156,10 +158,7 @@ final class InstallCommand extends Command
throw new \Exception('Skipped database creation, aborting installation');
}
- $options = [];
- if ($this->connection->getDatabasePlatform()->getName() !== 'sqlite') {
- $options = ['--if-not-exists' => true];
- }
+ $options = ['--if-not-exists' => true];
$command = $this->getApplication()->find('doctrine:database:create');
$result = $command->run(new ArrayInput($options), $output);
diff --git a/src/Command/ResetDevelopmentCommand.php b/src/Command/ResetDevelopmentCommand.php
new file mode 100644
index 00000000..7269568f
--- /dev/null
+++ b/src/Command/ResetDevelopmentCommand.php
@@ -0,0 +1,38 @@
+getApplication()->find('doctrine:fixtures:load');
+ $cmdInput = new ArrayInput([]);
+ $cmdInput->setInteractive(false);
+ $command->run($cmdInput, $output);
+ }
+}
diff --git a/src/Command/ResetTestCommand.php b/src/Command/ResetTestCommand.php
new file mode 100644
index 00000000..d017be91
--- /dev/null
+++ b/src/Command/ResetTestCommand.php
@@ -0,0 +1,137 @@
+setName('Test');
+ $activity->setComment('Test comment');
+ $activity->setVisible(true);
+ $activity->setTimeBudget(100000);
+ $activity->setBudget(1000);
+ $this->entityManager->persist($activity);
+
+ $customer = new Customer();
+ $customer->setNumber('1');
+ $customer->setComment('Test comment');
+ $customer->setContact('Test');
+ $customer->setAddress('Test');
+ $customer->setCompany('Test');
+ $customer->setName('Test');
+ $customer->setCountry('DE');
+ $customer->setCurrency('EUR');
+ $customer->setPhone('111');
+ $customer->setFax('222');
+ $customer->setMobile('333');
+ $customer->setEmail('test@example.com');
+ $customer->setTimeBudget(100000);
+ $customer->setBudget(1000);
+ $customer->setTimezone('Europe/Berlin');
+ $this->entityManager->persist($customer);
+
+ $project = new Project();
+ $project->setComment('Test comment');
+ $project->setName('Test');
+ $project->setOrderNumber('111');
+ $project->setTimeBudget(100000);
+ $project->setBudget(1000);
+ $project->setCustomer($customer);
+ $this->entityManager->persist($project);
+
+ $users = [
+ // 0=id, 1=hourly rate, 2=Alias, 3=registration date, 4=title, 5=avatar, 6=enabled, 7=password, 8=roles, 9=username, 10=username canonical, 11=email, 12=email canonical, 13=salt, 14=last login, 15=confirmation token, 16=password requested at, 17=api_token
+ [1, 53, 'Clara Haynes', '2018-02-06 23:28:57', 'CFO', 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=monsterid&f=y', 1, '$2y$04$kKBYJ8sKCOhhakCjm9sCp.TQdwLTS1FPkPiWn2KBmaCA7xFL0NA42', ['ROLE_CUSTOMER'], 'clara_customer', 'clara_customer', 'clara_customer@example.com', 'clara_customer@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [2, 82, 'John Doe', '2018-02-06 23:28:57', 'Developer', 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', 1, '$2y$04$36P/xyhP6FbnfFYbXy7V0.ioSe8HjMlJQFYnlIzz2T6Agfi8ob6jK', [], 'john_user', 'john_user', 'john_user@example.com', 'john_user@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [3, 35, 'Chris Deactive', '2018-02-06 23:28:57', 'Developer (left company)', 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', 0, '$2y$04$MLtQBZ9JLzWu1Y01QnNjsuoLm8qC9XRkpUywf6DIbpd9OAL1mEcCi', [], 'chris_user', 'chris_user', 'chris_user@example.com', 'chris_user@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [4, 35, 'Tony Maier', '2018-02-06 23:28:57', 'Head of Development', 'https://en.gravatar.com/userimage/3533186/bf2163b1dd23f3107a028af0195624e9.jpeg', 1, '$2y$04$rqxiiExfUVzIYRVL2x4JJumQWNPIG6PazXwrSJm/VQFEesR08Uj5i', ['ROLE_TEAMLEAD'], 'tony_teamlead', 'tony_teamlead', 'tony_teamlead@example.com', 'tony_teamlead@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [5, 81, 'Anna Smith', '2018-02-06 23:28:57', 'Administrator', null, 1, '$2y$04$ct/rVb.naDzYZECnvfTJ2uns/zPHv8.8KcunhTjYFwWQeg1dywI8G', ['ROLE_ADMIN'], 'anna_admin', 'anna_admin', 'anna_admin@example.com', 'anna_admin@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [6, 46, null, '2018-02-06 23:28:57', 'Super Administrator', '/bundles/avanzuadmintheme/img/avatar.png', 1, '$2y$04$kuhEEPw/CBMYc3x7SOv27eC1hQSmrtFvgJI2ULRuJeddAVDyrPKJ2', ['ROLE_SUPER_ADMIN'], 'susan_super', 'susan_super', 'susan_super@example.com', 'susan_super@example.com', null, '2020-04-14 09:50:38', null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [7, null, 'Test User 1', null, 'Quality Tester 1', null, 1, '$2y$04$kuhEEPw/CBMYc3x7SOv27eC1hQSmrtFvgJI2ULRuJeddAVDyrPKJ2', [], 'test_user_1', 'test_user_1', 'test_user_1@example.com', 'test_user_1@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ [8, null, 'Test User 2', null, 'Quality Tester 2', null, 1, '$2y$04$kuhEEPw/CBMYc3x7SOv27eC1hQSmrtFvgJI2ULRuJeddAVDyrPKJ2', [], 'test_user_2', 'test_user_2', 'test_user_2@example.com', 'test_user_2@example.com', null, null, null, null, '$2y$13$X8/msijlFUgvRaiGLCJP/ep2hRyjpd.TSNz3cuutZLp05FpuBsYfO'],
+ ];
+
+ $userEntities = [];
+ foreach ($users as $userConf) {
+ $user = new User();
+ if ($userConf[1] !== null) {
+ $user->setPreferenceValue(UserPreference::HOURLY_RATE, $userConf[1]);
+ }
+ if ($userConf[2] !== null) {
+ $user->setAlias($userConf[2]);
+ }
+ if ($userConf[3] !== null) {
+ $user->setRegisteredAt(new \DateTime($userConf[3]));
+ }
+ if ($userConf[4] !== null) {
+ $user->setTitle($userConf[4]);
+ }
+ if ($userConf[5] !== null) {
+ $user->setAvatar($userConf[5]);
+ }
+ if ($userConf[6] !== null) {
+ $user->setEnabled((bool) $userConf[6]);
+ }
+ $user->setPassword($userConf[7]);
+ if ($userConf[8] !== null && !empty($userConf[8])) {
+ $user->setRoles($userConf[8]);
+ } else {
+ $user->setRoles(['ROLE_USER']);
+ }
+ $user->setUsername($userConf[9]);
+ if ($userConf[10] !== null) {
+ $user->setUsernameCanonical($userConf[10]);
+ }
+ if ($userConf[11] !== null) {
+ $user->setEmail($userConf[11]);
+ }
+ if ($userConf[12] !== null) {
+ $user->setEmailCanonical($userConf[12]);
+ }
+ if ($userConf[17] !== null) {
+ $user->setApiToken($userConf[17]);
+ }
+
+ $this->entityManager->persist($user);
+ $userEntities[] = $user;
+ }
+
+ $team = new Team();
+ $team->setName('Test team');
+ $team->setTeamLead($userEntities[6]);
+ $team->addUser($userEntities[7]);
+ $this->entityManager->persist($team);
+
+ $this->entityManager->flush();
+ }
+}
diff --git a/src/DependencyInjection/Compiler/DoctrineCompilerPass.php b/src/DependencyInjection/Compiler/DoctrineCompilerPass.php
deleted file mode 100644
index cb0e67a4..00000000
--- a/src/DependencyInjection/Compiler/DoctrineCompilerPass.php
+++ /dev/null
@@ -1,134 +0,0 @@
- 'mysql',
- 'sqlite' => 'sqlite',
- ];
-
- private function getEnvVar(string $name): ?string
- {
- $envVarValue = null;
-
- if (isset($_ENV[$name])) {
- $envVarValue = $_ENV[$name];
- }
-
- if ($envVarValue === null && isset($_SERVER[$name])) {
- $envVarValue = $_SERVER[$name];
- }
-
- if ($envVarValue === null) {
- $envVarValue = getenv($name);
- }
-
- if ($envVarValue === false || empty($envVarValue)) {
- return null;
- }
-
- return $envVarValue;
- }
-
- /**
- * @return string
- * @throws \Exception
- */
- private function findEngine(): string
- {
- $engine = null;
-
- if (null !== ($databaseUrl = $this->getEnvVar('DATABASE_URL'))) {
- $urlParts = explode('://', $databaseUrl);
- $engine = $urlParts[0] ?: null;
- }
-
- if ($engine === null) {
- $engine = $this->getEnvVar('DATABASE_ENGINE');
- }
-
- if ($engine === null) {
- throw new \Exception(
- 'Could not detect database engine, make sure DATABASE_URL is available from $_SERVER or $_ENV. Check your .env file.'
- );
- }
-
- if (!\array_key_exists($engine, $this->allowedEngines)) {
- throw new \Exception(
- 'Unsupported database engine: ' . $engine . '. Kimai only supports one of: ' .
- implode(', ', array_keys($this->allowedEngines))
- );
- }
-
- return $this->allowedEngines[$engine];
- }
-
- /**
- * @param ContainerBuilder $container
- * @return string
- * @throws \Exception
- */
- protected function getConfigFile(ContainerBuilder $container)
- {
- $engine = $this->findEngine();
-
- $configDir = realpath(
- $container->getParameter('kernel.project_dir') . '/config/packages/doctrine/'
- );
-
- $configFile = $configDir . '/' . $engine . '.yaml';
-
- if (!file_exists($configFile)) {
- throw new \Exception('Could not find config file for database engine. Looked at ' . $configFile);
- }
-
- return $configFile;
- }
-
- /**
- * @param ContainerBuilder $container
- * @throws \Exception
- */
- public function process(ContainerBuilder $container)
- {
- $configFile = $this->getConfigFile($container);
- $config = Yaml::parse(file_get_contents($configFile));
-
- if (!isset($config['doctrine']['orm']['dql']) || empty($config['doctrine']['orm']['dql'])) {
- throw new \Exception('could not load custom Doctrine functions from: ' . $configFile);
- }
-
- $sql = $config['doctrine']['orm']['dql'];
-
- $ormConfig = $container->getDefinition('doctrine.orm.default_configuration');
-
- foreach ($sql['string_functions'] as $name => $function) {
- $ormConfig->addMethodCall('addCustomStringFunction', [$name, $function]);
- }
- foreach ($sql['numeric_functions'] as $name => $function) {
- $ormConfig->addMethodCall('addCustomNumericFunction', [$name, $function]);
- }
- foreach ($sql['datetime_functions'] as $name => $function) {
- $ormConfig->addMethodCall('addCustomDatetimeFunction', [$name, $function]);
- }
- }
-}
diff --git a/src/Doctrine/AbstractMigration.php b/src/Doctrine/AbstractMigration.php
index e85d49f8..81504135 100644
--- a/src/Doctrine/AbstractMigration.php
+++ b/src/Doctrine/AbstractMigration.php
@@ -55,29 +55,29 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
}
/**
- * Whether we should deactivate foreign key support for SQLite.
- * This is required, if columns are changed.
- * SQLite will drop the table and all referenced data, if we don't deactivate this.
- *
- * @return bool
+ * @deprecated since 1.14 - will be removed with 2.0
*/
protected function isSupportingForeignKeys(): bool
{
+ @trigger_error('isSupportingForeignKeys() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
+
return true;
}
+ /**
+ * @deprecated since 1.14 - will be removed with 2.0
+ */
protected function deactivateForeignKeysOnSqlite()
{
- if ($this->isPlatformSqlite() && !$this->isSupportingForeignKeys()) {
- $this->addSql('PRAGMA foreign_keys = OFF;');
- }
+ @trigger_error('deactivateForeignKeysOnSqlite() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
}
+ /**
+ * @deprecated since 1.14 - will be removed with 2.0
+ */
private function activateForeignKeysOnSqlite()
{
- if ($this->isPlatformSqlite() && !$this->isSupportingForeignKeys()) {
- $this->addSql('PRAGMA foreign_keys = ON;');
- }
+ @trigger_error('activateForeignKeysOnSqlite() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
}
/**
@@ -87,16 +87,6 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
public function preUp(Schema $schema): void
{
$this->abortIfPlatformNotSupported();
- $this->deactivateForeignKeysOnSqlite();
- }
-
- /**
- * @param Schema $schema
- * @throws DBALException
- */
- public function postUp(Schema $schema): void
- {
- $this->activateForeignKeysOnSqlite();
}
/**
@@ -106,16 +96,6 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
public function preDown(Schema $schema): void
{
$this->abortIfPlatformNotSupported();
- $this->deactivateForeignKeysOnSqlite();
- }
-
- /**
- * @param Schema $schema
- * @throws DBALException
- */
- public function postDown(Schema $schema): void
- {
- $this->activateForeignKeysOnSqlite();
}
/**
@@ -126,25 +106,22 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
protected function abortIfPlatformNotSupported()
{
$platform = $this->getPlatform();
- if (!\in_array($platform, ['sqlite', 'mysql'])) {
+ if (!$this->isPlatformMysql()) {
$this->abortIf(true, 'Unsupported database platform: ' . $platform);
}
}
/**
- * @return bool
- * @throws DBALException
+ * @deprecated since 1.14 - will be removed with 2.0
*/
- protected function isPlatformSqlite()
+ protected function isPlatformSqlite(): bool
{
+ @trigger_error('isPlatformSqlite() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
+
return ($this->getPlatform() === 'sqlite');
}
- /**
- * @return bool
- * @throws DBALException
- */
- protected function isPlatformMysql()
+ protected function isPlatformMysql(): bool
{
return ($this->getPlatform() === 'mysql');
}
@@ -173,19 +150,12 @@ abstract class AbstractMigration extends BaseAbstractMigration implements Contai
}
/**
- * we do it via addSql instead of $schema->getTable($users)->dropIndex()
- * otherwise the commands will be executed as last ones.
- *
- * @param string $indexName
- * @param string $tableName
- * @throws DBALException
+ * @deprecated since 1.14 - will be removed with 2.0
*/
protected function addSqlDropIndex($indexName, $tableName)
{
- $dropSql = 'DROP INDEX ' . $indexName;
- if (!$this->isPlatformSqlite()) {
- $dropSql .= ' ON ' . $tableName;
- }
- $this->addSql($dropSql);
+ @trigger_error('addSqlDropIndex() is deprecated and will be removed with 2.0', E_USER_DEPRECATED);
+
+ $this->addSql('DROP INDEX ' . $indexName . ' ON ' . $tableName);
}
}
diff --git a/src/Doctrine/SqliteSessionInitSubscriber.php b/src/Doctrine/SqliteSessionInitSubscriber.php
deleted file mode 100644
index 1e05b606..00000000
--- a/src/Doctrine/SqliteSessionInitSubscriber.php
+++ /dev/null
@@ -1,40 +0,0 @@
-getConnection()->getDatabasePlatform()->getName())) {
- return;
- }
-
- $args->getConnection()->exec('PRAGMA foreign_keys = ON;');
- }
-}
diff --git a/src/Kernel.php b/src/Kernel.php
index 0d0b8bb6..edbfa62a 100644
--- a/src/Kernel.php
+++ b/src/Kernel.php
@@ -10,7 +10,6 @@
namespace App;
use App\DependencyInjection\AppExtension;
-use App\DependencyInjection\Compiler\DoctrineCompilerPass;
use App\DependencyInjection\Compiler\ExportServiceCompilerPass;
use App\DependencyInjection\Compiler\InvoiceServiceCompilerPass;
use App\DependencyInjection\Compiler\TwigContextCompilerPass;
@@ -198,7 +197,6 @@ class Kernel extends BaseKernel
$loader->load($confDir . '/services-*' . self::CONFIG_EXTS, 'glob');
$loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
- $container->addCompilerPass(new DoctrineCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
$container->addCompilerPass(new TwigContextCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
$container->addCompilerPass(new InvoiceServiceCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
$container->addCompilerPass(new ExportServiceCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
diff --git a/src/Migrations/Version20180701120000.php b/src/Migrations/Version20180701120000.php
index a02749fc..6ed54128 100644
--- a/src/Migrations/Version20180701120000.php
+++ b/src/Migrations/Version20180701120000.php
@@ -30,38 +30,18 @@ final class Version20180701120000 extends AbstractMigration
$timesheets = 'kimai2_timesheet';
$invoiceTemplates = 'kimai2_invoice_templates';
- if ($this->isPlatformSqlite()) {
- $this->addSql('CREATE TABLE ' . $users . ' (id INTEGER NOT NULL, name VARCHAR(60) NOT NULL, mail VARCHAR(160) NOT NULL, password VARCHAR(254) DEFAULT NULL, alias VARCHAR(60) DEFAULT NULL, active BOOLEAN NOT NULL, registration_date DATETIME DEFAULT NULL, title VARCHAR(50) DEFAULT NULL, avatar VARCHAR(255) DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:array)
- , PRIMARY KEY(id))');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_B9AC5BCE5E237E06 ON ' . $users . ' (name)');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_B9AC5BCE5126AC48 ON ' . $users . ' (mail)');
- $this->addSql('CREATE TABLE ' . $userPreferences . ' (id INTEGER NOT NULL, user_id INTEGER DEFAULT NULL, name VARCHAR(50) NOT NULL, value VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE INDEX IDX_8D08F631A76ED395 ON ' . $userPreferences . ' (user_id)');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_8D08F631A76ED3955E237E06 ON ' . $userPreferences . ' (user_id, name)');
- $this->addSql('CREATE TABLE ' . $customers . ' (id INTEGER NOT NULL, name VARCHAR(150) NOT NULL, number VARCHAR(50) DEFAULT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, company VARCHAR(255) DEFAULT NULL, contact VARCHAR(255) DEFAULT NULL, address CLOB DEFAULT NULL, country VARCHAR(2) NOT NULL, currency VARCHAR(3) NOT NULL, phone VARCHAR(255) DEFAULT NULL, fax VARCHAR(255) DEFAULT NULL, mobile VARCHAR(255) DEFAULT NULL, mail VARCHAR(255) DEFAULT NULL, homepage VARCHAR(255) DEFAULT NULL, timezone VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE TABLE ' . $projects . ' (id INTEGER NOT NULL, customer_id INTEGER DEFAULT NULL, name VARCHAR(150) NOT NULL, order_number CLOB DEFAULT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, budget NUMERIC(10, 2) NOT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE INDEX IDX_407F12069395C3F3 ON ' . $projects . ' (customer_id)');
- $this->addSql('CREATE TABLE ' . $activities . ' (id INTEGER NOT NULL, project_id INTEGER DEFAULT NULL, name VARCHAR(150) NOT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE INDEX IDX_8811FE1C166D1F9C ON ' . $activities . ' (project_id)');
- $this->addSql('CREATE TABLE ' . $timesheets . ' (id INTEGER NOT NULL, user INTEGER DEFAULT NULL, activity_id INTEGER DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL, rate NUMERIC(10, 2) NOT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheets . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheets . ' (activity_id)');
- $this->addSql('CREATE TABLE ' . $invoiceTemplates . ' (id INTEGER NOT NULL, name VARCHAR(60) NOT NULL, title VARCHAR(255) NOT NULL, company VARCHAR(255) NOT NULL, address CLOB DEFAULT NULL, due_days INTEGER NOT NULL, vat INTEGER DEFAULT NULL, calculator VARCHAR(20) NOT NULL, number_generator VARCHAR(20) NOT NULL, renderer VARCHAR(20) NOT NULL, payment_terms CLOB DEFAULT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_1626CFE95E237E06 ON ' . $invoiceTemplates . ' (name)');
- } else {
- $this->addSql('CREATE TABLE ' . $users . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(60) NOT NULL, mail VARCHAR(160) NOT NULL, password VARCHAR(254) DEFAULT NULL, alias VARCHAR(60) DEFAULT NULL, active TINYINT(1) NOT NULL, registration_date DATETIME DEFAULT NULL, title VARCHAR(50) DEFAULT NULL, avatar VARCHAR(255) DEFAULT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', UNIQUE INDEX UNIQ_B9AC5BCE5E237E06 (name), UNIQUE INDEX UNIQ_B9AC5BCE5126AC48 (mail), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $userPreferences . ' (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, name VARCHAR(50) NOT NULL, value VARCHAR(255) DEFAULT NULL, INDEX IDX_8D08F631A76ED395 (user_id), UNIQUE INDEX UNIQ_8D08F631A76ED3955E237E06 (user_id, name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $customers . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(150) NOT NULL, number VARCHAR(50) DEFAULT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, company VARCHAR(255) DEFAULT NULL, contact VARCHAR(255) DEFAULT NULL, address TEXT DEFAULT NULL, country VARCHAR(2) NOT NULL, currency VARCHAR(3) NOT NULL, phone VARCHAR(255) DEFAULT NULL, fax VARCHAR(255) DEFAULT NULL, mobile VARCHAR(255) DEFAULT NULL, mail VARCHAR(255) DEFAULT NULL, homepage VARCHAR(255) DEFAULT NULL, timezone VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $projects . ' (id INT AUTO_INCREMENT NOT NULL, customer_id INT DEFAULT NULL, name VARCHAR(150) NOT NULL, order_number TINYTEXT DEFAULT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, budget NUMERIC(10, 2) NOT NULL, INDEX IDX_407F12069395C3F3 (customer_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $activities . ' (id INT AUTO_INCREMENT NOT NULL, project_id INT DEFAULT NULL, name VARCHAR(150) NOT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, INDEX IDX_8811FE1C166D1F9C (project_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $timesheets . ' (id INT AUTO_INCREMENT NOT NULL, user INT DEFAULT NULL, activity_id INT DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INT DEFAULT NULL, description TEXT DEFAULT NULL, rate NUMERIC(10, 2) NOT NULL, INDEX IDX_4F60C6B18D93D649 (user), INDEX IDX_4F60C6B181C06096 (activity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('CREATE TABLE ' . $invoiceTemplates . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(60) NOT NULL, title VARCHAR(255) NOT NULL, company VARCHAR(255) NOT NULL, address TEXT DEFAULT NULL, due_days INT NOT NULL, vat INT DEFAULT NULL, calculator VARCHAR(20) NOT NULL, number_generator VARCHAR(20) NOT NULL, renderer VARCHAR(20) NOT NULL, payment_terms TEXT DEFAULT NULL, UNIQUE INDEX UNIQ_1626CFE95E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- $this->addSql('ALTER TABLE ' . $userPreferences . ' ADD CONSTRAINT FK_8D08F631A76ED395 FOREIGN KEY (user_id) REFERENCES ' . $users . ' (id) ON DELETE CASCADE');
- $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
- $this->addSql('ALTER TABLE ' . $activities . ' ADD CONSTRAINT FK_8811FE1C166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE');
- $this->addSql('ALTER TABLE ' . $timesheets . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id)');
- $this->addSql('ALTER TABLE ' . $timesheets . ' ADD CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE');
- }
+ $this->addSql('CREATE TABLE ' . $users . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(60) NOT NULL, mail VARCHAR(160) NOT NULL, password VARCHAR(254) DEFAULT NULL, alias VARCHAR(60) DEFAULT NULL, active TINYINT(1) NOT NULL, registration_date DATETIME DEFAULT NULL, title VARCHAR(50) DEFAULT NULL, avatar VARCHAR(255) DEFAULT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', UNIQUE INDEX UNIQ_B9AC5BCE5E237E06 (name), UNIQUE INDEX UNIQ_B9AC5BCE5126AC48 (mail), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $userPreferences . ' (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, name VARCHAR(50) NOT NULL, value VARCHAR(255) DEFAULT NULL, INDEX IDX_8D08F631A76ED395 (user_id), UNIQUE INDEX UNIQ_8D08F631A76ED3955E237E06 (user_id, name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $customers . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(150) NOT NULL, number VARCHAR(50) DEFAULT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, company VARCHAR(255) DEFAULT NULL, contact VARCHAR(255) DEFAULT NULL, address TEXT DEFAULT NULL, country VARCHAR(2) NOT NULL, currency VARCHAR(3) NOT NULL, phone VARCHAR(255) DEFAULT NULL, fax VARCHAR(255) DEFAULT NULL, mobile VARCHAR(255) DEFAULT NULL, mail VARCHAR(255) DEFAULT NULL, homepage VARCHAR(255) DEFAULT NULL, timezone VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $projects . ' (id INT AUTO_INCREMENT NOT NULL, customer_id INT DEFAULT NULL, name VARCHAR(150) NOT NULL, order_number TINYTEXT DEFAULT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, budget NUMERIC(10, 2) NOT NULL, INDEX IDX_407F12069395C3F3 (customer_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $activities . ' (id INT AUTO_INCREMENT NOT NULL, project_id INT DEFAULT NULL, name VARCHAR(150) NOT NULL, comment TEXT DEFAULT NULL, visible TINYINT(1) NOT NULL, INDEX IDX_8811FE1C166D1F9C (project_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $timesheets . ' (id INT AUTO_INCREMENT NOT NULL, user INT DEFAULT NULL, activity_id INT DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INT DEFAULT NULL, description TEXT DEFAULT NULL, rate NUMERIC(10, 2) NOT NULL, INDEX IDX_4F60C6B18D93D649 (user), INDEX IDX_4F60C6B181C06096 (activity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE ' . $invoiceTemplates . ' (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(60) NOT NULL, title VARCHAR(255) NOT NULL, company VARCHAR(255) NOT NULL, address TEXT DEFAULT NULL, due_days INT NOT NULL, vat INT DEFAULT NULL, calculator VARCHAR(20) NOT NULL, number_generator VARCHAR(20) NOT NULL, renderer VARCHAR(20) NOT NULL, payment_terms TEXT DEFAULT NULL, UNIQUE INDEX UNIQ_1626CFE95E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
+ $this->addSql('ALTER TABLE ' . $userPreferences . ' ADD CONSTRAINT FK_8D08F631A76ED395 FOREIGN KEY (user_id) REFERENCES ' . $users . ' (id) ON DELETE CASCADE');
+ $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
+ $this->addSql('ALTER TABLE ' . $activities . ' ADD CONSTRAINT FK_8811FE1C166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE');
+ $this->addSql('ALTER TABLE ' . $timesheets . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id)');
+ $this->addSql('ALTER TABLE ' . $timesheets . ' ADD CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE');
}
public function down(Schema $schema): void
diff --git a/src/Migrations/Version20180715160326.php b/src/Migrations/Version20180715160326.php
index bdb6fcfe..f8ebe923 100644
--- a/src/Migrations/Version20180715160326.php
+++ b/src/Migrations/Version20180715160326.php
@@ -44,22 +44,13 @@ final class Version20180715160326 extends AbstractMigration
foreach ($indexesOld as $index) {
if (\in_array('name', $index->getColumns()) || \in_array('mail', $index->getColumns())) {
$this->indexesOld[] = $index;
- $this->addSqlDropIndex($index->getName(), $users);
+ $this->addSql('DROP INDEX ' . $index->getName() . ' ON ' . $users);
}
}
- if ($this->isPlatformSqlite()) {
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $users . ' AS SELECT id, name, mail, password, alias, active, registration_date, title, avatar, roles FROM ' . $users);
- $this->addSql('DROP TABLE ' . $users);
- $this->addSql('CREATE TABLE ' . $users . ' (id INTEGER NOT NULL, alias VARCHAR(60) DEFAULT NULL COLLATE BINARY, registration_date DATETIME DEFAULT NULL, title VARCHAR(50) DEFAULT NULL COLLATE BINARY, avatar VARCHAR(255) DEFAULT NULL COLLATE BINARY, enabled BOOLEAN NOT NULL, password VARCHAR(255) NOT NULL, roles CLOB NOT NULL --(DC2Type:array)
- , username VARCHAR(180) NOT NULL, username_canonical VARCHAR(180) NOT NULL, email VARCHAR(180) NOT NULL, email_canonical VARCHAR(180) NOT NULL, salt VARCHAR(255) DEFAULT NULL, last_login DATETIME DEFAULT NULL, confirmation_token VARCHAR(180) DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, PRIMARY KEY(id))');
- $this->addSql('INSERT INTO ' . $users . ' (id, username, username_canonical, email, email_canonical, password, alias, enabled, registration_date, title, avatar, roles) SELECT id, name, name, mail, mail, password, alias, active, registration_date, title, avatar, roles FROM __temp__' . $users);
- $this->addSql('DROP TABLE __temp__' . $users);
- } else {
- $this->addSql('ALTER TABLE ' . $users . ' CHANGE name username VARCHAR(180) NOT NULL, ADD username_canonical VARCHAR(180) NOT NULL, CHANGE mail email VARCHAR(180) NOT NULL, ADD email_canonical VARCHAR(180) NOT NULL, ADD salt VARCHAR(255) DEFAULT NULL, ADD last_login DATETIME DEFAULT NULL, ADD confirmation_token VARCHAR(180) DEFAULT NULL, ADD password_requested_at DATETIME DEFAULT NULL, CHANGE password password VARCHAR(255) NOT NULL, CHANGE alias alias VARCHAR(60) DEFAULT NULL, CHANGE registration_date registration_date DATETIME DEFAULT NULL, CHANGE title title VARCHAR(50) DEFAULT NULL, CHANGE avatar avatar VARCHAR(255) DEFAULT NULL, CHANGE roles roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', CHANGE active enabled TINYINT(1) NOT NULL');
- $this->addSql('UPDATE ' . $users . ' set username_canonical = username');
- $this->addSql('UPDATE ' . $users . ' set email_canonical = email');
- }
+ $this->addSql('ALTER TABLE ' . $users . ' CHANGE name username VARCHAR(180) NOT NULL, ADD username_canonical VARCHAR(180) NOT NULL, CHANGE mail email VARCHAR(180) NOT NULL, ADD email_canonical VARCHAR(180) NOT NULL, ADD salt VARCHAR(255) DEFAULT NULL, ADD last_login DATETIME DEFAULT NULL, ADD confirmation_token VARCHAR(180) DEFAULT NULL, ADD password_requested_at DATETIME DEFAULT NULL, CHANGE password password VARCHAR(255) NOT NULL, CHANGE alias alias VARCHAR(60) DEFAULT NULL, CHANGE registration_date registration_date DATETIME DEFAULT NULL, CHANGE title title VARCHAR(50) DEFAULT NULL, CHANGE avatar avatar VARCHAR(255) DEFAULT NULL, CHANGE roles roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', CHANGE active enabled TINYINT(1) NOT NULL');
+ $this->addSql('UPDATE ' . $users . ' set username_canonical = username');
+ $this->addSql('UPDATE ' . $users . ' set email_canonical = email');
$this->addSql('UPDATE ' . $users . ' SET roles = \'a:1:{i:0;s:16:"ROLE_SUPER_ADMIN";}\' WHERE roles LIKE "%ROLE_SUPER_ADMIN%"');
$this->addSql('UPDATE ' . $users . ' SET roles = \'a:1:{i:0;s:10:"ROLE_ADMIN";}\' WHERE roles LIKE "%ROLE_ADMIN%"');
@@ -84,20 +75,11 @@ final class Version20180715160326 extends AbstractMigration
$users = 'kimai2_users';
$indexToDelete = ['UNIQ_B9AC5BCE92FC23A8', 'UNIQ_B9AC5BCEA0D96FBF', 'UNIQ_B9AC5BCEC05FB297', 'UNIQ_B9AC5BCEF85E0677', 'UNIQ_B9AC5BCEE7927C74'];
- foreach ($indexToDelete as $index) {
- $this->addSqlDropIndex($index, $users);
+ foreach ($indexToDelete as $indexName) {
+ $this->addSql('DROP INDEX ' . $indexName . ' ON ' . $users);
}
- if ($this->isPlatformSqlite()) {
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $users . ' AS SELECT id, username, email, enabled, password, roles, alias, registration_date, title, avatar FROM ' . $users);
- $this->addSql('DROP TABLE ' . $users);
- $this->addSql('CREATE TABLE ' . $users . ' (id INTEGER NOT NULL, alias VARCHAR(60) DEFAULT NULL, registration_date DATETIME DEFAULT NULL, title VARCHAR(50) DEFAULT NULL, avatar VARCHAR(255) DEFAULT NULL, active BOOLEAN NOT NULL, password VARCHAR(254) DEFAULT NULL COLLATE BINARY, roles CLOB NOT NULL COLLATE BINARY --(DC2Type:array)
- , name VARCHAR(60) NOT NULL COLLATE BINARY, mail VARCHAR(160) NOT NULL COLLATE BINARY, PRIMARY KEY(id))');
- $this->addSql('INSERT INTO ' . $users . ' (id, name, mail, active, password, roles, alias, registration_date, title, avatar) SELECT id, username, email, enabled, password, roles, alias, registration_date, title, avatar FROM __temp__' . $users);
- $this->addSql('DROP TABLE __temp__' . $users);
- } else {
- $this->addSql('ALTER TABLE ' . $users . ' CHANGE username name VARCHAR(60) NOT NULL COLLATE utf8mb4_unicode_ci, CHANGE email mail VARCHAR(160) NOT NULL COLLATE utf8mb4_unicode_ci, DROP username_canonical, DROP email_canonical, DROP salt, DROP last_login, DROP confirmation_token, DROP password_requested_at, CHANGE password password VARCHAR(254) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE roles roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', CHANGE alias alias VARCHAR(60) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE registration_date registration_date DATETIME DEFAULT NULL, CHANGE title title VARCHAR(50) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE avatar avatar VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE enabled active TINYINT(1) NOT NULL');
- }
+ $this->addSql('ALTER TABLE ' . $users . ' CHANGE username name VARCHAR(60) NOT NULL COLLATE utf8mb4_unicode_ci, CHANGE email mail VARCHAR(160) NOT NULL COLLATE utf8mb4_unicode_ci, DROP username_canonical, DROP email_canonical, DROP salt, DROP last_login, DROP confirmation_token, DROP password_requested_at, CHANGE password password VARCHAR(254) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE roles roles LONGTEXT NOT NULL COMMENT \'(DC2Type:array)\', CHANGE alias alias VARCHAR(60) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE registration_date registration_date DATETIME DEFAULT NULL, CHANGE title title VARCHAR(50) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE avatar avatar VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE enabled active TINYINT(1) NOT NULL');
$this->addSql('UPDATE ' . $users . ' SET roles = \'["ROLE_SUPER_ADMIN"]\' WHERE roles LIKE "%ROLE_SUPER_ADMIN%"');
$this->addSql('UPDATE ' . $users . ' SET roles = \'["ROLE_ADMIN"]\' WHERE roles LIKE "%ROLE_ADMIN%"');
diff --git a/src/Migrations/Version20180730044139.php b/src/Migrations/Version20180730044139.php
index 6059a8ef..737ded9b 100644
--- a/src/Migrations/Version20180730044139.php
+++ b/src/Migrations/Version20180730044139.php
@@ -37,20 +37,8 @@ final class Version20180730044139 extends AbstractMigration
$user = 'kimai2_users';
$activity = 'kimai2_activities';
- if ($this->isPlatformSqlite()) {
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $timesheet . ' AS SELECT id, user, activity_id, start_time, end_time, duration, description, rate FROM ' . $timesheet);
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER NOT NULL, user INTEGER DEFAULT NULL, activity_id INTEGER DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL COLLATE BINARY, rate NUMERIC(10, 2) NOT NULL, PRIMARY KEY(id), CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $user . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activity . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, start_time, end_time, duration, description, rate) SELECT id, user, activity_id, start_time, end_time, duration, description, rate FROM __temp__' . $timesheet);
- $this->addSql('DROP TABLE __temp__' . $timesheet);
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- } else {
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $user . ' (id) ON DELETE CASCADE');
- }
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $user . ' (id) ON DELETE CASCADE');
}
/**
@@ -62,19 +50,7 @@ final class Version20180730044139 extends AbstractMigration
$timesheet = 'kimai2_timesheet';
$user = 'kimai2_users';
- if ($this->isPlatformSqlite()) {
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $timesheet . ' AS SELECT id, user, activity_id, start_time, end_time, duration, description, rate FROM ' . $timesheet);
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER NOT NULL, user INTEGER DEFAULT NULL, activity_id INTEGER DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL, rate NUMERIC(10, 2) NOT NULL, PRIMARY KEY(id))');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, start_time, end_time, duration, description, rate) SELECT id, user, activity_id, start_time, end_time, duration, description, rate FROM __temp__' . $timesheet);
- $this->addSql('DROP TABLE __temp__' . $timesheet);
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- } else {
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $user . ' (id)');
- }
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $user . ' (id)');
}
}
diff --git a/src/Migrations/Version20180924111853.php b/src/Migrations/Version20180924111853.php
index 2efc268a..8844411d 100644
--- a/src/Migrations/Version20180924111853.php
+++ b/src/Migrations/Version20180924111853.php
@@ -25,35 +25,14 @@ final class Version20180924111853 extends AbstractMigration
{
$invoiceTemplates = 'kimai2_invoice_templates';
- if ($this->isPlatformSqlite()) {
- $this->addSql('UPDATE ' . $invoiceTemplates . ' SET name=substr(name, 1, 60)');
- $this->addSql('DROP INDEX UNIQ_1626CFE95E237E06');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $invoiceTemplates . ' AS SELECT id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms FROM ' . $invoiceTemplates);
- $this->addSql('DROP TABLE ' . $invoiceTemplates);
- $this->addSql('CREATE TABLE ' . $invoiceTemplates . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL COLLATE BINARY, company VARCHAR(255) NOT NULL COLLATE BINARY, address CLOB DEFAULT NULL COLLATE BINARY, due_days INTEGER NOT NULL, calculator VARCHAR(20) NOT NULL COLLATE BINARY, number_generator VARCHAR(20) NOT NULL COLLATE BINARY, renderer VARCHAR(20) NOT NULL COLLATE BINARY, payment_terms CLOB DEFAULT NULL COLLATE BINARY, name VARCHAR(60) NOT NULL, vat DOUBLE PRECISION DEFAULT 0)');
- $this->addSql('INSERT INTO ' . $invoiceTemplates . ' (id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms) SELECT id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms FROM __temp__' . $invoiceTemplates);
- $this->addSql('DROP TABLE __temp__' . $invoiceTemplates);
- $this->addSql('CREATE UNIQUE INDEX UNIQ_1626CFE95E237E06 ON ' . $invoiceTemplates . ' (name)');
- } else {
- $this->addSql('UPDATE ' . $invoiceTemplates . ' SET name=SUBSTRING(name, 1, 60)');
- $this->addSql('ALTER TABLE ' . $invoiceTemplates . ' CHANGE name name VARCHAR(60) NOT NULL, CHANGE vat vat DOUBLE PRECISION DEFAULT 0');
- }
+ $this->addSql('UPDATE ' . $invoiceTemplates . ' SET name=SUBSTRING(name, 1, 60)');
+ $this->addSql('ALTER TABLE ' . $invoiceTemplates . ' CHANGE name name VARCHAR(60) NOT NULL, CHANGE vat vat DOUBLE PRECISION DEFAULT 0');
}
public function down(Schema $schema): void
{
$invoiceTemplates = 'kimai2_invoice_templates';
- if ($this->isPlatformSqlite()) {
- $this->addSql('DROP INDEX UNIQ_1626CFE95E237E06');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $invoiceTemplates . ' AS SELECT id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms FROM ' . $invoiceTemplates);
- $this->addSql('DROP TABLE ' . $invoiceTemplates);
- $this->addSql('CREATE TABLE ' . $invoiceTemplates . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL, company VARCHAR(255) NOT NULL, address CLOB DEFAULT NULL, due_days INTEGER NOT NULL, calculator VARCHAR(20) NOT NULL, number_generator VARCHAR(20) NOT NULL, renderer VARCHAR(20) NOT NULL, payment_terms CLOB DEFAULT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, vat INTEGER DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $invoiceTemplates . ' (id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms) SELECT id, name, title, company, address, due_days, vat, calculator, number_generator, renderer, payment_terms FROM __temp__' . $invoiceTemplates);
- $this->addSql('DROP TABLE __temp__' . $invoiceTemplates);
- $this->addSql('CREATE UNIQUE INDEX UNIQ_1626CFE95E237E06 ON ' . $invoiceTemplates . ' (name)');
- } else {
- $this->addSql('ALTER TABLE ' . $invoiceTemplates . ' CHANGE name name VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, CHANGE vat vat INT DEFAULT NULL');
- }
+ $this->addSql('ALTER TABLE ' . $invoiceTemplates . ' CHANGE name name VARCHAR(255) NOT NULL COLLATE utf8mb4_unicode_ci, CHANGE vat vat INT DEFAULT NULL');
}
}
diff --git a/src/Migrations/Version20181031220003.php b/src/Migrations/Version20181031220003.php
index 18cfabc1..307aee78 100644
--- a/src/Migrations/Version20181031220003.php
+++ b/src/Migrations/Version20181031220003.php
@@ -28,60 +28,24 @@ final class Version20181031220003 extends AbstractMigration
$users = 'kimai2_users';
$customers = 'kimai2_customers';
- if ($this->isPlatformSqlite()) {
- // project table
- $this->addSql('DROP INDEX IDX_407F12069395C3F3');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $projects . ' AS SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM ' . $projects);
- $this->addSql('DROP TABLE ' . $projects);
- $this->addSql('CREATE TABLE ' . $projects . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, customer_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, order_number CLOB DEFAULT NULL COLLATE BINARY, comment CLOB DEFAULT NULL COLLATE BINARY, visible BOOLEAN NOT NULL, budget NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL, CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $projects . ' (id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate) SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM __temp__' . $projects);
- $this->addSql('DROP TABLE __temp__' . $projects);
- $this->addSql('CREATE INDEX IDX_407F12069395C3F3 ON ' . $projects . ' (customer_id)');
- // timesheet table
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $timesheet . ' AS SELECT id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM ' . $timesheet);
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user INTEGER DEFAULT NULL, activity_id INTEGER DEFAULT NULL, project_id INTEGER DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL COLLATE BINARY, rate NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL, CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B1166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate) SELECT id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM __temp__' . $timesheet);
- $this->addSql('DROP TABLE __temp__' . $timesheet);
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
- } else {
- // project table
- $this->addSql('ALTER TABLE ' . $projects . ' DROP FOREIGN KEY FK_407F12069395C3F3');
- $this->addSql('ALTER TABLE ' . $projects . ' CHANGE customer_id customer_id INT NOT NULL');
- $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
- // timesheet table
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD project_id INT DEFAULT NULL AFTER activity_id');
- $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
- }
+ // project table
+ $this->addSql('ALTER TABLE ' . $projects . ' DROP FOREIGN KEY FK_407F12069395C3F3');
+ $this->addSql('ALTER TABLE ' . $projects . ' CHANGE customer_id customer_id INT NOT NULL');
+ $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
+ // timesheet table
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD project_id INT DEFAULT NULL AFTER activity_id');
+ $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
// update timesheet table and insert project_id from activity table
$this->addSql('UPDATE ' . $timesheet . ' SET project_id = (SELECT project_id FROM ' . $activities . ' WHERE id = activity_id)');
// now update the timesheet table and disallow null values for all required columns (that was a bug before)
- if ($this->isPlatformSqlite()) {
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $timesheet . ' AS SELECT id, user, activity_id, project_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM ' . $timesheet);
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user INTEGER NOT NULL, activity_id INTEGER NOT NULL, project_id INTEGER NOT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL COLLATE BINARY, rate NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL, CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B1166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, project_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate) SELECT id, user, activity_id, project_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM __temp__' . $timesheet);
- $this->addSql('DROP TABLE __temp__' . $timesheet);
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
- } else {
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B181C06096');
- $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE project_id project_id INT NOT NULL, CHANGE user user INT NOT NULL, CHANGE activity_id activity_id INT NOT NULL');
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B1166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE');
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id) ON DELETE CASCADE');
- $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE');
- }
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B18D93D649');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B181C06096');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE project_id project_id INT NOT NULL, CHANGE user user INT NOT NULL, CHANGE activity_id activity_id INT NOT NULL');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B1166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id) ON DELETE CASCADE');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' ADD CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE');
}
public function down(Schema $schema): void
@@ -90,35 +54,13 @@ final class Version20181031220003 extends AbstractMigration
$projects = 'kimai2_projects';
$customers = 'kimai2_customers';
- if ($this->isPlatformSqlite()) {
- // project table
- $this->addSql('DROP INDEX IDX_407F12069395C3F3');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $projects . ' AS SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM ' . $projects);
- $this->addSql('DROP TABLE ' . $projects);
- $this->addSql('CREATE TABLE ' . $projects . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, order_number CLOB DEFAULT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, budget NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL, customer_id INTEGER DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $projects . ' (id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate) SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM __temp__' . $projects);
- $this->addSql('DROP TABLE __temp__' . $projects);
- $this->addSql('CREATE INDEX IDX_407F12069395C3F3 ON ' . $projects . ' (customer_id)');
- // timesheet table
- $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C');
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('CREATE TEMPORARY TABLE __temp__' . $timesheet . ' AS SELECT id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM ' . $timesheet);
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user INTEGER DEFAULT NULL, activity_id INTEGER DEFAULT NULL, start_time DATETIME NOT NULL, end_time DATETIME DEFAULT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL, rate NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate) SELECT id, user, activity_id, start_time, end_time, duration, description, rate, fixed_rate, hourly_rate FROM __temp__' . $timesheet);
- $this->addSql('DROP TABLE __temp__' . $timesheet);
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- } else {
- // project table
- $this->addSql('ALTER TABLE ' . $projects . ' DROP FOREIGN KEY FK_407F12069395C3F3');
- $this->addSql('ALTER TABLE ' . $projects . ' CHANGE customer_id customer_id INT DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
- // timesheet table
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B1166D1F9C');
- $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet);
- $this->addSql('ALTER TABLE ' . $timesheet . ' DROP project_id, CHANGE user user INT DEFAULT NULL, CHANGE activity_id activity_id INT DEFAULT NULL');
- }
+ // project table
+ $this->addSql('ALTER TABLE ' . $projects . ' DROP FOREIGN KEY FK_407F12069395C3F3');
+ $this->addSql('ALTER TABLE ' . $projects . ' CHANGE customer_id customer_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $projects . ' ADD CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE');
+ // timesheet table
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP FOREIGN KEY FK_4F60C6B1166D1F9C');
+ $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet);
+ $this->addSql('ALTER TABLE ' . $timesheet . ' DROP project_id, CHANGE user user INT DEFAULT NULL, CHANGE activity_id activity_id INT DEFAULT NULL');
}
}
diff --git a/src/Migrations/Version20190201150324.php b/src/Migrations/Version20190201150324.php
index 876bdb0a..8db8e7bd 100644
--- a/src/Migrations/Version20190201150324.php
+++ b/src/Migrations/Version20190201150324.php
@@ -26,11 +26,7 @@ final class Version20190201150324 extends AbstractMigration
{
$timezone = date_default_timezone_get();
- if ($this->isPlatformSqlite()) {
- $this->addSql('ALTER TABLE kimai2_timesheet ADD COLUMN timezone VARCHAR(64) DEFAULT NULL');
- } else {
- $this->addSql('ALTER TABLE kimai2_timesheet ADD timezone VARCHAR(64) NOT NULL');
- }
+ $this->addSql('ALTER TABLE kimai2_timesheet ADD timezone VARCHAR(64) NOT NULL');
$this->addSql('UPDATE kimai2_timesheet SET timezone = "' . $timezone . '"');
}
diff --git a/src/Migrations/Version20190305152308.php b/src/Migrations/Version20190305152308.php
index 02f7e267..d5481a37 100644
--- a/src/Migrations/Version20190305152308.php
+++ b/src/Migrations/Version20190305152308.php
@@ -16,7 +16,6 @@ use Doctrine\DBAL\Schema\Schema;
/**
* - rename mail to email in customer table
- * - introducing foreign keys in SQLite tables
* - converts all decimal to float values, as decimals are treated as string in PHP:
* https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#decimal
*
@@ -32,54 +31,10 @@ final class Version20190305152308 extends AbstractMigration
$timesheet = 'kimai2_timesheet';
$users = 'kimai2_users';
- if ($this->isPlatformSqlite()) {
- // first backup of ALL tables
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_timesheet AS SELECT id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported FROM ' . $timesheet);
-
- $this->addSql('DROP INDEX IDX_8811FE1C166D1F9C');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_activities AS SELECT id, project_id, name, comment, visible, fixed_rate, hourly_rate FROM ' . $activities);
-
- $this->addSql('DROP INDEX IDX_407F12069395C3F3');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_projects AS SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM ' . $projects);
-
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_customers AS SELECT id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, mail, homepage, timezone, fixed_rate, hourly_rate FROM ' . $customers);
-
- // now we can drop and re-create the tables
- $this->addSql('DROP TABLE ' . $customers);
- $this->addSql('CREATE TABLE ' . $customers . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, number VARCHAR(50) DEFAULT NULL COLLATE BINARY, comment CLOB DEFAULT NULL COLLATE BINARY, visible BOOLEAN NOT NULL, company VARCHAR(255) DEFAULT NULL COLLATE BINARY, contact VARCHAR(255) DEFAULT NULL COLLATE BINARY, address CLOB DEFAULT NULL COLLATE BINARY, country VARCHAR(2) NOT NULL COLLATE BINARY, currency VARCHAR(3) NOT NULL COLLATE BINARY, phone VARCHAR(255) DEFAULT NULL COLLATE BINARY, fax VARCHAR(255) DEFAULT NULL COLLATE BINARY, mobile VARCHAR(255) DEFAULT NULL COLLATE BINARY, email VARCHAR(255) DEFAULT NULL COLLATE BINARY, homepage VARCHAR(255) DEFAULT NULL COLLATE BINARY, timezone VARCHAR(255) NOT NULL COLLATE BINARY, fixed_rate DOUBLE PRECISION DEFAULT NULL, hourly_rate DOUBLE PRECISION DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $customers . ' (id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, email, homepage, timezone, fixed_rate, hourly_rate) SELECT id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, mail, homepage, timezone, fixed_rate, hourly_rate FROM __temp__kimai2_customers');
- $this->addSql('DROP TABLE __temp__kimai2_customers');
-
- $this->addSql('DROP TABLE ' . $projects);
- $this->addSql('CREATE TABLE ' . $projects . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, customer_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, order_number CLOB DEFAULT NULL COLLATE BINARY, comment CLOB DEFAULT NULL COLLATE BINARY, visible BOOLEAN NOT NULL, budget DOUBLE PRECISION NOT NULL, fixed_rate DOUBLE PRECISION DEFAULT NULL, hourly_rate DOUBLE PRECISION DEFAULT NULL, CONSTRAINT FK_407F12069395C3F3 FOREIGN KEY (customer_id) REFERENCES ' . $customers . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $projects . ' (id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate) SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM __temp__kimai2_projects');
- $this->addSql('DROP TABLE __temp__kimai2_projects');
- $this->addSql('CREATE INDEX IDX_407F12069395C3F3 ON ' . $projects . ' (customer_id)');
-
- $this->addSql('DROP TABLE ' . $activities);
- $this->addSql('CREATE TABLE ' . $activities . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, project_id INTEGER DEFAULT NULL, name VARCHAR(255) NOT NULL COLLATE BINARY, comment CLOB DEFAULT NULL COLLATE BINARY, visible BOOLEAN NOT NULL, fixed_rate DOUBLE PRECISION DEFAULT NULL, hourly_rate DOUBLE PRECISION DEFAULT NULL, CONSTRAINT FK_8811FE1C166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $activities . ' (id, project_id, name, comment, visible, fixed_rate, hourly_rate) SELECT id, project_id, name, comment, visible, fixed_rate, hourly_rate FROM __temp__kimai2_activities');
- $this->addSql('DROP TABLE __temp__kimai2_activities');
- $this->addSql('CREATE INDEX IDX_8811FE1C166D1F9C ON ' . $activities . ' (project_id)');
-
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user INTEGER NOT NULL, activity_id INTEGER NOT NULL, project_id INTEGER NOT NULL, start_time DATETIME NOT NULL --(DC2Type:datetime)
- , timezone VARCHAR(64) NOT NULL COLLATE BINARY, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL COLLATE BINARY, exported BOOLEAN NOT NULL, end_time DATETIME DEFAULT NULL --(DC2Type:datetime)
- , rate DOUBLE PRECISION NOT NULL, fixed_rate DOUBLE PRECISION DEFAULT NULL, hourly_rate DOUBLE PRECISION DEFAULT NULL, CONSTRAINT FK_4F60C6B18D93D649 FOREIGN KEY (user) REFERENCES ' . $users . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B181C06096 FOREIGN KEY (activity_id) REFERENCES ' . $activities . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_4F60C6B1166D1F9C FOREIGN KEY (project_id) REFERENCES ' . $projects . ' (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported) SELECT id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported FROM __temp__kimai2_timesheet');
- $this->addSql('DROP TABLE __temp__kimai2_timesheet');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
- } else {
- $this->addSql('ALTER TABLE ' . $activities . ' CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $customers . ' CHANGE mail email VARCHAR(255) DEFAULT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $projects . ' CHANGE budget budget DOUBLE PRECISION NOT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE rate rate DOUBLE PRECISION NOT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
- }
+ $this->addSql('ALTER TABLE ' . $activities . ' CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $customers . ' CHANGE mail email VARCHAR(255) DEFAULT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $projects . ' CHANGE budget budget DOUBLE PRECISION NOT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE rate rate DOUBLE PRECISION NOT NULL, CHANGE fixed_rate fixed_rate DOUBLE PRECISION DEFAULT NULL, CHANGE hourly_rate hourly_rate DOUBLE PRECISION DEFAULT NULL');
}
public function down(Schema $schema): void
@@ -89,53 +44,9 @@ final class Version20190305152308 extends AbstractMigration
$activities = 'kimai2_activities';
$timesheet = 'kimai2_timesheet';
- if ($this->isPlatformSqlite()) {
- // first backup of ALL tables
- $this->addSql('DROP INDEX IDX_8811FE1C166D1F9C');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_activities AS SELECT id, project_id, name, comment, visible, fixed_rate, hourly_rate FROM ' . $activities);
-
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_customers AS SELECT id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, email, homepage, timezone, fixed_rate, hourly_rate FROM ' . $customers);
-
- $this->addSql('DROP INDEX IDX_407F12069395C3F3');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_projects AS SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM ' . $projects);
-
- $this->addSql('DROP INDEX IDX_4F60C6B1166D1F9C');
- $this->addSql('DROP INDEX IDX_4F60C6B18D93D649');
- $this->addSql('DROP INDEX IDX_4F60C6B181C06096');
- $this->addSql('CREATE TEMPORARY TABLE __temp__kimai2_timesheet AS SELECT id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported FROM ' . $timesheet);
-
- // now we can drop and re-create the tables
- $this->addSql('DROP TABLE ' . $activities);
- $this->addSql('CREATE TABLE ' . $activities . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, project_id INTEGER DEFAULT NULL, name VARCHAR(255) NOT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $activities . ' (id, project_id, name, comment, visible, fixed_rate, hourly_rate) SELECT id, project_id, name, comment, visible, fixed_rate, hourly_rate FROM __temp__kimai2_activities');
- $this->addSql('DROP TABLE __temp__kimai2_activities');
- $this->addSql('CREATE INDEX IDX_8811FE1C166D1F9C ON ' . $activities . ' (project_id)');
-
- $this->addSql('DROP TABLE ' . $customers);
- $this->addSql('CREATE TABLE ' . $customers . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, number VARCHAR(50) DEFAULT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, company VARCHAR(255) DEFAULT NULL, contact VARCHAR(255) DEFAULT NULL, address CLOB DEFAULT NULL, country VARCHAR(2) NOT NULL, currency VARCHAR(3) NOT NULL, phone VARCHAR(255) DEFAULT NULL, fax VARCHAR(255) DEFAULT NULL, mobile VARCHAR(255) DEFAULT NULL, mail VARCHAR(255) DEFAULT NULL, homepage VARCHAR(255) DEFAULT NULL, timezone VARCHAR(255) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $customers . ' (id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, mail, homepage, timezone, fixed_rate, hourly_rate) SELECT id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, email, homepage, timezone, fixed_rate, hourly_rate FROM __temp__kimai2_customers');
- $this->addSql('DROP TABLE __temp__kimai2_customers');
-
- $this->addSql('DROP TABLE ' . $projects);
- $this->addSql('CREATE TABLE ' . $projects . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, customer_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, order_number CLOB DEFAULT NULL, comment CLOB DEFAULT NULL, visible BOOLEAN NOT NULL, budget NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $projects . ' (id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate) SELECT id, customer_id, name, order_number, comment, visible, budget, fixed_rate, hourly_rate FROM __temp__kimai2_projects');
- $this->addSql('DROP TABLE __temp__kimai2_projects');
- $this->addSql('CREATE INDEX IDX_407F12069395C3F3 ON ' . $projects . ' (customer_id)');
-
- $this->addSql('DROP TABLE ' . $timesheet);
- $this->addSql('CREATE TABLE ' . $timesheet . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user INTEGER NOT NULL, activity_id INTEGER NOT NULL, project_id INTEGER NOT NULL, start_time DATETIME NOT NULL --(DC2Type:datetime)
- , timezone VARCHAR(64) NOT NULL, duration INTEGER DEFAULT NULL, description CLOB DEFAULT NULL, exported BOOLEAN NOT NULL, end_time DATETIME DEFAULT NULL --(DC2Type:datetime)
- , rate NUMERIC(10, 2) NOT NULL, fixed_rate NUMERIC(10, 2) DEFAULT NULL, hourly_rate NUMERIC(10, 2) DEFAULT NULL)');
- $this->addSql('INSERT INTO ' . $timesheet . ' (id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported) SELECT id, user, activity_id, project_id, start_time, end_time, timezone, duration, description, rate, fixed_rate, hourly_rate, exported FROM __temp__kimai2_timesheet');
- $this->addSql('DROP TABLE __temp__kimai2_timesheet');
- $this->addSql('CREATE INDEX IDX_4F60C6B1166D1F9C ON ' . $timesheet . ' (project_id)');
- $this->addSql('CREATE INDEX IDX_4F60C6B18D93D649 ON ' . $timesheet . ' (user)');
- $this->addSql('CREATE INDEX IDX_4F60C6B181C06096 ON ' . $timesheet . ' (activity_id)');
- } else {
- $this->addSql('ALTER TABLE ' . $activities . ' CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $customers . ' CHANGE email mail VARCHAR(255) DEFAULT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $projects . ' CHANGE budget budget NUMERIC(10, 2) NOT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
- $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE rate rate NUMERIC(10, 2) NOT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
- }
+ $this->addSql('ALTER TABLE ' . $activities . ' CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $customers . ' CHANGE email mail VARCHAR(255) DEFAULT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $projects . ' CHANGE budget budget NUMERIC(10, 2) NOT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
+ $this->addSql('ALTER TABLE ' . $timesheet . ' CHANGE rate rate NUMERIC(10, 2) NOT NULL, CHANGE fixed_rate fixed_rate NUMERIC(10, 2) DEFAULT NULL, CHANGE hourly_rate hourly_rate NUMERIC(10, 2) DEFAULT NULL');
}
}
diff --git a/src/Migrations/Version20190321181243.php b/src/Migrations/Version20190321181243.php
index 9add572e..240195c2 100644
--- a/src/Migrations/Version20190321181243.php
+++ b/src/Migrations/Version20190321181243.php
@@ -23,17 +23,12 @@ final class Version20190321181243 extends AbstractMigration
{
public function getDescription(): string
{
- return '';
+ return 'Create system configuration table';
}
public function up(Schema $schema): void
{
- if ($this->isPlatformSqlite()) {
- $this->addSql('CREATE TABLE kimai2_configuration (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(100) NOT NULL, value VARCHAR(255) DEFAULT NULL)');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_1C5D63D85E237E06 ON kimai2_configuration (name)');
- } else {
- $this->addSql('CREATE TABLE kimai2_configuration (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) NOT NULL, value VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_1C5D63D85E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
- }
+ $this->addSql('CREATE TABLE kimai2_configuration (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) NOT NULL, value VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_1C5D63D85E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
}
public function down(Schema $schema): void
diff --git a/src/Migrations/Version20190605171157.php b/src/Migrations/Version20190605171157.php
index 0cca9a68..7cd8a272 100644
--- a/src/Migrations/Version20190605171157.php
+++ b/src/Migrations/Version20190605171157.php
@@ -26,21 +26,6 @@ final class Version20190605171157 extends AbstractMigration
return 'Creates the budget columns on: customer, project, activity';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$customers = $schema->getTable('kimai2_customers');
diff --git a/src/Migrations/Version20190706224219.php b/src/Migrations/Version20190706224219.php
index 9ea49d9d..ee9c572c 100644
--- a/src/Migrations/Version20190706224219.php
+++ b/src/Migrations/Version20190706224219.php
@@ -26,21 +26,6 @@ final class Version20190706224219 extends AbstractMigration
return 'Creates several indices to improve speed for default queries.';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$timesheet = $schema->getTable('kimai2_timesheet');
diff --git a/src/Migrations/Version20190729162655.php b/src/Migrations/Version20190729162655.php
index f44f1187..3e4672ee 100644
--- a/src/Migrations/Version20190729162655.php
+++ b/src/Migrations/Version20190729162655.php
@@ -26,21 +26,6 @@ final class Version20190729162655 extends AbstractMigration
return 'Adds missing foreign keys on tag table';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$timesheetTags = $schema->getTable('kimai2_timesheet_tags');
diff --git a/src/Migrations/Version20190813162649.php b/src/Migrations/Version20190813162649.php
index 7fb3b955..ad317187 100644
--- a/src/Migrations/Version20190813162649.php
+++ b/src/Migrations/Version20190813162649.php
@@ -26,21 +26,6 @@ final class Version20190813162649 extends AbstractMigration
return 'Changing column sizes to prevent index length errors';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$activity = $schema->getTable('kimai2_activities');
diff --git a/src/Migrations/Version20191024100951.php b/src/Migrations/Version20191024100951.php
index 4a226b51..566d1ae8 100644
--- a/src/Migrations/Version20191024100951.php
+++ b/src/Migrations/Version20191024100951.php
@@ -26,21 +26,6 @@ final class Version20191024100951 extends AbstractMigration
return 'Adds the order_date column to the projects table';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$projects = $schema->getTable('kimai2_projects');
diff --git a/src/Migrations/Version20191108151534.php b/src/Migrations/Version20191108151534.php
index 0d52acab..5cd3e5a2 100644
--- a/src/Migrations/Version20191108151534.php
+++ b/src/Migrations/Version20191108151534.php
@@ -26,21 +26,6 @@ final class Version20191108151534 extends AbstractMigration
return 'Adds the user roles and role permissions table';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$roles = $schema->createTable('kimai2_roles');
diff --git a/src/Migrations/Version20191113132640.php b/src/Migrations/Version20191113132640.php
index 587ffbe9..7dcd9c59 100644
--- a/src/Migrations/Version20191113132640.php
+++ b/src/Migrations/Version20191113132640.php
@@ -26,21 +26,6 @@ final class Version20191113132640 extends AbstractMigration
return 'Fixes foreign keys on tag table';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$timesheetTags = $schema->getTable('kimai2_timesheet_tags');
diff --git a/src/Migrations/Version20191116110124.php b/src/Migrations/Version20191116110124.php
index cb604fb8..329af7ff 100644
--- a/src/Migrations/Version20191116110124.php
+++ b/src/Migrations/Version20191116110124.php
@@ -26,21 +26,6 @@ final class Version20191116110124 extends AbstractMigration
return 'New Vat ID columns and invoice template improvements';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$customers = $schema->getTable('kimai2_customers');
diff --git a/src/Migrations/Version20200125123942.php b/src/Migrations/Version20200125123942.php
index 4526af2e..ca7bb855 100644
--- a/src/Migrations/Version20200125123942.php
+++ b/src/Migrations/Version20200125123942.php
@@ -26,21 +26,6 @@ final class Version20200125123942 extends AbstractMigration
return 'Adds a column to the user table to identify authenticator';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$users = $schema->getTable('kimai2_users');
diff --git a/src/Migrations/Version20200204124425.php b/src/Migrations/Version20200204124425.php
index 4537d85b..88a258b3 100644
--- a/src/Migrations/Version20200204124425.php
+++ b/src/Migrations/Version20200204124425.php
@@ -26,21 +26,6 @@ final class Version20200204124425 extends AbstractMigration
return 'Adds language and decimal_duration column to invoice template table';
}
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
-
public function up(Schema $schema): void
{
$invoiceTemplates = $schema->getTable('kimai2_invoice_templates');
diff --git a/src/Migrations/Version20200705152310.php b/src/Migrations/Version20200705152310.php
index 35e3b60d..9f556074 100644
--- a/src/Migrations/Version20200705152310.php
+++ b/src/Migrations/Version20200705152310.php
@@ -45,19 +45,4 @@ final class Version20200705152310 extends AbstractMigration
$timesheet->dropColumn('category');
$timesheet->dropColumn('modified_at');
}
-
- protected function isSupportingForeignKeys(): bool
- {
- return false;
- }
-
- public function isTransactional(): bool
- {
- if ($this->isPlatformSqlite()) {
- // does fail if we use transactions, as tables are re-created and foreign keys would fail
- return false;
- }
-
- return true;
- }
}
diff --git a/tests/API/ActivityControllerTest.php b/tests/API/ActivityControllerTest.php
index e07a6e85..756b4ef3 100644
--- a/tests/API/ActivityControllerTest.php
+++ b/tests/API/ActivityControllerTest.php
@@ -15,12 +15,12 @@ use App\Entity\ActivityMeta;
use App\Entity\ActivityRate;
use App\Entity\Customer;
use App\Entity\Project;
+use App\Entity\RateInterface;
use App\Entity\User;
use App\Repository\ActivityRateRepository;
use App\Repository\ActivityRepository;
use App\Tests\Mocks\ActivityTestMetaFieldSubscriberMock;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\HttpKernelBrowser;
/**
* @group integration
@@ -29,6 +29,20 @@ class ActivityControllerTest extends APIControllerBaseTest
{
use RateControllerTestTrait;
+ /**
+ * @param ActivityRate $rate
+ * @param bool $isCollection
+ * @return string
+ */
+ protected function getRateUrlByRate(RateInterface $rate, bool $isCollection): string
+ {
+ if ($isCollection) {
+ return $this->getRateUrl($rate->getActivity()->getId());
+ }
+
+ return $this->getRateUrl($rate->getActivity()->getId(), $rate->getId());
+ }
+
protected function getRateUrl($id = '1', $rateId = null): string
{
if (null !== $rateId) {
@@ -77,7 +91,7 @@ class ActivityControllerTest extends APIControllerBaseTest
$this->assertUrlIsSecured('/api/activities');
}
- protected function loadActivityTestData(HttpKernelBrowser $client)
+ protected function loadActivityTestData(): array
{
$em = $this->getEntityManager();
@@ -116,15 +130,33 @@ class ActivityControllerTest extends APIControllerBaseTest
$em->persist($activity);
$em->flush();
+
+ return [$project, $project2];
}
/**
* @dataProvider getCollectionTestData
*/
- public function testGetCollection($url, $parameters, $expected)
+ public function testGetCollection($url, $project, $parameters, $expected)
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->loadActivityTestData($client);
+ $imports = $this->loadActivityTestData();
+
+ $projectId = $project !== null ? $imports[$project]->getId() : null;
+ if ($projectId !== null) {
+ if (\array_key_exists('project', $parameters)) {
+ $parameters['project'] = $projectId;
+ }
+
+ if (\array_key_exists('projects', $parameters)) {
+ if (stripos($parameters['projects'], ',') !== false) {
+ $parameters['projects'] = $projectId . ',' . $projectId;
+ } else {
+ $parameters['projects'] = (string) $projectId;
+ }
+ }
+ }
+
$this->assertAccessIsGranted($client, $url, 'GET', $parameters);
$result = json_decode($client->getResponse()->getContent(), true);
@@ -135,31 +167,31 @@ class ActivityControllerTest extends APIControllerBaseTest
$activity = $result[$i];
$hasProject = $expected[$i][0];
self::assertApiResponseTypeStructure('ActivityCollection', $activity);
- if ($hasProject) {
- $this->assertEquals($expected[$i][1], $activity['project']);
+ if ($hasProject && $projectId !== null) {
+ $this->assertEquals($projectId, $activity['project']);
}
}
}
public function getCollectionTestData()
{
- yield ['/api/activities', [], [[false], [true, 2], [true, 2], [null], [true, 1]]];
+ yield ['/api/activities', null, [], [[false], [true, 2], [true, 2], [null], [true, 1]]];
//yield ['/api/activities', [], [[false], [false], [true, 2], [true, 1], [true, 2]]];
- yield ['/api/activities', ['globals' => 'true'], [[false], [false]]];
- yield ['/api/activities', ['globals' => 'true', 'visible' => 3], [[false], [false], [false]]];
- yield ['/api/activities', ['globals' => 'true', 'visible' => '2'], [[false]]];
- yield ['/api/activities', ['globals' => 'true', 'visible' => 1], [[false], [false]]];
- yield ['/api/activities', ['project' => '1'], [[false], [false], [true, 1]]];
- yield ['/api/activities', ['project' => '2', 'projects' => '2', 'visible' => 1], [[false], [true, 2], [true, 2], [false]]];
- yield ['/api/activities', ['project' => '2', 'projects' => '2,2', 'visible' => '3'], [[false], [true, 2], [true, 2], [true, 2], [false], [false]]];
- yield ['/api/activities', ['projects' => '2,2', 'visible' => 2], [[true, 2], [false]]];
- yield ['/api/activities', ['projects' => '2', 'visible' => 2], [[true, 2], [false]]];
+ yield ['/api/activities', null, ['globals' => 'true'], [[false], [false]]];
+ yield ['/api/activities', null, ['globals' => 'true', 'visible' => 3], [[false], [false], [false]]];
+ yield ['/api/activities', null, ['globals' => 'true', 'visible' => '2'], [[false]]];
+ yield ['/api/activities', null, ['globals' => 'true', 'visible' => 1], [[false], [false]]];
+ yield ['/api/activities', 0, ['project' => '1'], [[false], [false], [true, 1]]];
+ yield ['/api/activities', 1, ['project' => '2', 'projects' => '2', 'visible' => 1], [[true, 2], [true, 2], [false], [false]]];
+ yield ['/api/activities', 1, ['project' => '2', 'projects' => '2,2', 'visible' => '3'], [[true, 2], [true, 2], [true, 2], [false], [false], [false]]];
+ yield ['/api/activities', 1, ['projects' => '2,2', 'visible' => 2], [[true, 2], [false]]];
+ yield ['/api/activities', 1, ['projects' => '2', 'visible' => 2], [[true, 2], [false]]];
}
public function testGetCollectionWithQuery()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->loadActivityTestData($client);
+ $imports = $this->loadActivityTestData();
$query = ['order' => 'ASC', 'orderBy' => 'project'];
$this->assertAccessIsGranted($client, '/api/activities', 'GET', $query);
@@ -169,9 +201,9 @@ class ActivityControllerTest extends APIControllerBaseTest
$this->assertNotEmpty($result);
$this->assertEquals(5, \count($result));
self::assertApiResponseTypeStructure('ActivityCollection', $result[0]);
- $this->assertEquals(1, $result[4]['project']);
- $this->assertEquals(2, $result[3]['project']);
- $this->assertEquals(2, $result[2]['project']);
+ $this->assertEquals($imports[0]->getId(), $result[4]['project']);
+ $this->assertEquals($imports[1]->getId(), $result[3]['project']);
+ $this->assertEquals($imports[1]->getId(), $result[2]['project']);
}
public function testGetEntity()
diff --git a/tests/API/CustomerControllerTest.php b/tests/API/CustomerControllerTest.php
index 292891b4..350e7f8d 100644
--- a/tests/API/CustomerControllerTest.php
+++ b/tests/API/CustomerControllerTest.php
@@ -15,6 +15,7 @@ use App\Entity\Customer;
use App\Entity\CustomerMeta;
use App\Entity\CustomerRate;
use App\Entity\Project;
+use App\Entity\RateInterface;
use App\Entity\Team;
use App\Entity\User;
use App\Repository\CustomerRateRepository;
@@ -29,6 +30,20 @@ class CustomerControllerTest extends APIControllerBaseTest
{
use RateControllerTestTrait;
+ /**
+ * @param CustomerRate $rate
+ * @param bool $isCollection
+ * @return string
+ */
+ protected function getRateUrlByRate(RateInterface $rate, bool $isCollection): string
+ {
+ if ($isCollection) {
+ return $this->getRateUrl($rate->getCustomer()->getId());
+ }
+
+ return $this->getRateUrl($rate->getCustomer()->getId(), $rate->getId());
+ }
+
protected function getRateUrl($id = '1', $rateId = null): string
{
if (null !== $rateId) {
diff --git a/tests/API/ProjectControllerTest.php b/tests/API/ProjectControllerTest.php
index 5d07b836..3e09903b 100644
--- a/tests/API/ProjectControllerTest.php
+++ b/tests/API/ProjectControllerTest.php
@@ -14,6 +14,7 @@ use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\ProjectMeta;
use App\Entity\ProjectRate;
+use App\Entity\RateInterface;
use App\Entity\Team;
use App\Entity\User;
use App\Repository\ProjectRateRepository;
@@ -30,6 +31,20 @@ class ProjectControllerTest extends APIControllerBaseTest
{
use RateControllerTestTrait;
+ /**
+ * @param ProjectRate $rate
+ * @param bool $isCollection
+ * @return string
+ */
+ protected function getRateUrlByRate(RateInterface $rate, bool $isCollection): string
+ {
+ if ($isCollection) {
+ return $this->getRateUrl($rate->getProject()->getId());
+ }
+
+ return $this->getRateUrl($rate->getProject()->getId(), $rate->getId());
+ }
+
protected function getRateUrl($id = '1', $rateId = null): string
{
if (null !== $rateId) {
@@ -139,15 +154,32 @@ class ProjectControllerTest extends APIControllerBaseTest
$em->persist($project);
$em->flush();
+
+ return [$customer, $customer2, $customer3];
}
/**
* @dataProvider getCollectionTestData
*/
- public function testGetCollectionWithParams($url, $parameters, $expected)
+ public function testGetCollectionWithParams($url, $customer, $parameters, $expected)
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->loadProjectTestData($client);
+ $imports = $this->loadProjectTestData($client);
+
+ $customerId = $customer !== null ? $imports[$customer]->getId() : null;
+
+ if ($customerId !== null) {
+ if (\array_key_exists('customer', $parameters)) {
+ $parameters['customer'] = $customerId;
+ } elseif (\array_key_exists('customers', $parameters)) {
+ if (stripos($parameters['customers'], ',') !== false) {
+ $parameters['customers'] = $customerId . ',' . $customerId;
+ } else {
+ $parameters['customers'] = (string) $customerId;
+ }
+ }
+ }
+
$this->assertAccessIsGranted($client, $url, 'GET', $parameters);
$result = json_decode($client->getResponse()->getContent(), true);
@@ -156,29 +188,30 @@ class ProjectControllerTest extends APIControllerBaseTest
for ($i = 0; $i < \count($expected); $i++) {
$project = $result[$i];
- $compare = $expected[$i];
self::assertApiResponseTypeStructure('ProjectCollection', $project);
- $this->assertEquals($compare[1], $project['customer']);
+ if ($customerId !== null) {
+ $this->assertEquals($customerId, $project['customer']);
+ }
}
}
public function getCollectionTestData()
{
- // if you wonder why: SQLite does case-sensitive ordering, so "Title" > "fifth”
- yield ['/api/projects', [], [[true, 1], [false, 1], [false, 3]]];
- yield ['/api/projects', ['customer' => '1'], [[true, 1], [false, 1]]];
- yield ['/api/projects', ['customer' => '1', 'visible' => VisibilityInterface::SHOW_VISIBLE], [[true, 1], [false, 1]]];
- yield ['/api/projects', ['customer' => '1', 'visible' => VisibilityInterface::SHOW_BOTH], [[true, 1], [false, 1], [false, 1]]];
- yield ['/api/projects', ['customer' => '1', 'visible' => VisibilityInterface::SHOW_HIDDEN], [[false, 1]]];
+ // if you wonder why: case-sensitive ordering feels strange ... "Title" > "fifth”
+ yield ['/api/projects', null, [], [[true, 1], [false, 1], [false, 3]]];
+ yield ['/api/projects', 0, ['customer' => '1'], [[true, 1], [false, 1]]];
+ yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_VISIBLE], [[true, 1], [false, 1]]];
+ yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_BOTH], [[true, 1], [false, 1], [false, 1]]];
+ yield ['/api/projects', 0, ['customer' => '1', 'visible' => VisibilityInterface::SHOW_HIDDEN], [[false, 1]]];
// customer is invisible, so nothing should be returned
- yield ['/api/projects', ['customer' => '2', 'visible' => VisibilityInterface::SHOW_VISIBLE], []];
- yield ['/api/projects', ['customer' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
- yield ['/api/projects', ['customer' => '2', 'customers' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
- yield ['/api/projects', ['customer' => '2', 'customers' => '2,2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
+ yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_VISIBLE], []];
+ yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
+ yield ['/api/projects', 1, ['customer' => '2', 'customers' => '2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
+ yield ['/api/projects', 1, ['customer' => '2', 'customers' => '2,2', 'visible' => VisibilityInterface::SHOW_BOTH], [[false, 2], [false, 2]]];
// customer is invisible, so nothing should be returned
- yield ['/api/projects', ['customer' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
- yield ['/api/projects', ['customers' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
- yield ['/api/projects', ['customers' => '2,2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
+ yield ['/api/projects', 1, ['customer' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
+ yield ['/api/projects', 1, ['customers' => '2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
+ yield ['/api/projects', 1, ['customers' => '2,2', 'visible' => VisibilityInterface::SHOW_HIDDEN, 'start' => '2010-12-11T23:59:59', 'end' => '2030-12-11T23:59:59'], []];
}
public function testGetEntity()
@@ -207,8 +240,9 @@ class ProjectControllerTest extends APIControllerBaseTest
->setEnd($endDate)
;
$em->persist($project);
+ $em->flush();
- $this->assertAccessIsGranted($client, '/api/projects/2');
+ $this->assertAccessIsGranted($client, '/api/projects/' . $project->getId());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
@@ -216,8 +250,8 @@ class ProjectControllerTest extends APIControllerBaseTest
$expected = [
'parentTitle' => 'first one',
- 'customer' => 2,
- 'id' => 2,
+ 'customer' => $customer->getId(),
+ 'id' => $project->getId(),
'name' => 'first',
'orderNumber' => null,
// make sure the timezone is properly applied in serializer (see #1858)
diff --git a/tests/API/RateControllerTestTrait.php b/tests/API/RateControllerTestTrait.php
index fb376fdb..8e7be685 100644
--- a/tests/API/RateControllerTestTrait.php
+++ b/tests/API/RateControllerTestTrait.php
@@ -9,6 +9,7 @@
namespace App\Tests\API;
+use App\Entity\RateInterface;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Response;
@@ -24,9 +25,11 @@ trait RateControllerTestTrait
*/
abstract protected function getRateUrl($id = '1', $rateId = null): string;
+ abstract protected function getRateUrlByRate(RateInterface $rate, bool $isCollection): string;
+
/**
* @param string|int $id
- * @return array
+ * @return RateInterface[]
*/
abstract protected function importTestRates($id): array;
@@ -160,12 +163,12 @@ trait RateControllerTestTrait
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$expectedRates = $this->importTestRates(1);
- $this->request($client, $this->getRateUrl(1, 1), 'DELETE');
+ $this->request($client, $this->getRateUrlByRate($expectedRates[0], false), 'DELETE');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertEmpty($client->getResponse()->getContent());
// fetch rates to validate that one was removed
- $this->request($client, $this->getRateUrl(1));
+ $this->request($client, $this->getRateUrlByRate($expectedRates[0], true));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
diff --git a/tests/API/TagControllerTest.php b/tests/API/TagControllerTest.php
index db827438..05d930d6 100644
--- a/tests/API/TagControllerTest.php
+++ b/tests/API/TagControllerTest.php
@@ -9,24 +9,28 @@
namespace App\Tests\API;
+use App\Entity\Tag;
use App\Entity\User;
use App\Tests\DataFixtures\TagFixtures;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\HttpKernelBrowser;
/**
* @group integration
*/
class TagControllerTest extends APIControllerBaseTest
{
- protected function importTagFixtures(HttpKernelBrowser $client): void
+ /**
+ * @return Tag[]
+ */
+ protected function importTagFixtures(): array
{
$tagList = ['Test', 'Administration', 'Support', '#2018-001', '#2018-002', '#2018-003', 'Development',
'Marketing', 'First Level Support', 'Bug Fixing'];
$fixture = new TagFixtures();
$fixture->setTagArray($tagList);
- $this->importFixture($fixture);
+
+ return $this->importFixture($fixture);
}
public function testIsSecure()
@@ -37,7 +41,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testGetCollection()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$this->assertAccessIsGranted($client, '/api/tags');
$result = json_decode($client->getResponse()->getContent(), true);
@@ -50,7 +54,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testEmptyCollection()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$query = ['name' => 'nothing'];
$this->assertAccessIsGranted($client, '/api/tags', 'GET', $query);
$result = json_decode($client->getResponse()->getContent(), true);
@@ -63,7 +67,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testPostAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$data = [
'name' => 'foo',
'color' => '#000FFF'
@@ -81,7 +85,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testPostActionWithValidationErrors()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$data = [
'name' => '1',
'color' => '11231231231',
@@ -95,7 +99,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testPostActionWithInvalidUser()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$data = [
'name' => 'foo',
];
@@ -110,7 +114,7 @@ class TagControllerTest extends APIControllerBaseTest
public function testPartOfEntries()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importTagFixtures($client);
+ $this->importTagFixtures();
$query = ['name' => 'in'];
$this->assertAccessIsGranted($client, '/api/tags', 'GET', $query);
$result = json_decode($client->getResponse()->getContent(), true);
@@ -127,9 +131,10 @@ class TagControllerTest extends APIControllerBaseTest
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTagFixtures($client);
+ $tags = $this->importTagFixtures();
+ $id = $tags[0]->getId();
- $this->request($client, '/api/tags/1', 'DELETE');
+ $this->request($client, '/api/tags/' . $id, 'DELETE');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
$this->assertEmpty($client->getResponse()->getContent());
@@ -142,6 +147,6 @@ class TagControllerTest extends APIControllerBaseTest
public function testDeleteActionWithUnknownTimesheet()
{
- $this->assertEntityNotFoundForDelete(User::ROLE_ADMIN, '/api/tags/255');
+ $this->assertEntityNotFoundForDelete(User::ROLE_ADMIN, '/api/tags/' . PHP_INT_MAX);
}
}
diff --git a/tests/API/TeamControllerTest.php b/tests/API/TeamControllerTest.php
index e2a1070c..7f1951c1 100644
--- a/tests/API/TeamControllerTest.php
+++ b/tests/API/TeamControllerTest.php
@@ -9,21 +9,25 @@
namespace App\Tests\API;
+use App\Entity\Team;
use App\Entity\User;
use App\Tests\DataFixtures\TeamFixtures;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\HttpKernelBrowser;
/**
* @group integration
*/
class TeamControllerTest extends APIControllerBaseTest
{
- protected function importTeamFixtures(HttpKernelBrowser $client): void
+ /**
+ * @return Team[]
+ */
+ protected function importTeamFixtures(): array
{
$fixture = new TeamFixtures();
$fixture->setAmount(1);
- $this->importFixture($fixture);
+
+ return $this->importFixture($fixture);
}
public function testIsSecure()
@@ -50,7 +54,7 @@ class TeamControllerTest extends APIControllerBaseTest
public function testGetCollection()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTeamFixtures($client);
+ $this->importTeamFixtures();
$this->assertAccessIsGranted($client, '/api/teams');
$result = json_decode($client->getResponse()->getContent(), true);
@@ -63,8 +67,10 @@ class TeamControllerTest extends APIControllerBaseTest
public function testGetEntity()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTeamFixtures($client);
- $this->assertAccessIsGranted($client, '/api/teams/2');
+ $teams = $this->importTeamFixtures();
+ $id = $teams[0]->getId();
+
+ $this->assertAccessIsGranted($client, '/api/teams/' . $id);
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
@@ -178,8 +184,9 @@ class TeamControllerTest extends APIControllerBaseTest
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTeamFixtures($client);
- $this->assertAccessIsGranted($client, '/api/teams/2');
+ $teams = $this->importTeamFixtures();
+ $id = $teams[0]->getId();
+ $this->assertAccessIsGranted($client, '/api/teams/' . $id);
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
diff --git a/tests/API/TimesheetControllerTest.php b/tests/API/TimesheetControllerTest.php
index 02867739..80b9fae4 100644
--- a/tests/API/TimesheetControllerTest.php
+++ b/tests/API/TimesheetControllerTest.php
@@ -31,7 +31,11 @@ class TimesheetControllerTest extends APIControllerBaseTest
public const DATE_FORMAT_HTML5 = 'Y-m-d\TH:i:s';
public const TEST_TIMEZONE = 'Europe/London';
- protected function importFixtureForUser(string $role)
+ /**
+ * @param string $role
+ * @return Timesheet[]
+ */
+ protected function importFixtureForUser(string $role): array
{
$fixture = new TimesheetFixtures();
$fixture
@@ -43,7 +47,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
->setStartDate((new \DateTime('first day of this month'))->setTime(0, 0, 1))
;
- $this->importFixture($fixture);
+ return $this->importFixture($fixture);
}
public function testIsSecure()
@@ -300,8 +304,9 @@ class TimesheetControllerTest extends APIControllerBaseTest
->addTag($tag)
;
$em->persist($timesheet);
+ $em->flush();
- $this->assertAccessIsGranted($client, '/api/timesheets/1');
+ $this->assertAccessIsGranted($client, '/api/timesheets/' . $timesheet->getId());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
@@ -314,7 +319,6 @@ class TimesheetControllerTest extends APIControllerBaseTest
'tags' => [
0 => 'test'
],
- 'id' => 1,
// make sure the timezone is properly applied in serializer (see #1858)
// minute and second are different from the above datetime object, because of applied default minute rounding
'begin' => '2020-03-27T14:35:00+1300',
@@ -337,16 +341,17 @@ class TimesheetControllerTest extends APIControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->importFixtureForUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_ADMIN);
+ $timesheets = $this->importFixtureForUser(User::ROLE_ADMIN);
+ $this->assertCount(10, $timesheets);
- $this->assertApiAccessDenied($client, '/api/timesheets/15', 'You are not allowed to view this timesheet');
+ $this->assertApiAccessDenied($client, '/api/timesheets/' . $timesheets[0]->getId(), 'You are not allowed to view this timesheet');
}
public function testGetEntityAccessAllowedForAdmin()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importFixtureForUser(User::ROLE_USER);
- $this->assertAccessIsGranted($client, '/api/timesheets/1');
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $this->assertAccessIsGranted($client, '/api/timesheets/' . $timesheets[0]->getId());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
@@ -355,7 +360,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testGetEntityNotFound()
{
- $this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/20');
+ $this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/' . PHP_INT_MAX);
}
public function testPostAction()
@@ -496,7 +501,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
{
$dateTime = new DateTimeFactory(new \DateTimeZone(self::TEST_TIMEZONE));
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
$data = [
'activity' => 1,
'project' => 1,
@@ -505,7 +510,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
'description' => 'foo',
'exported' => true,
];
- $this->request($client, '/api/timesheets/1', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $timesheets[0]->getId(), 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -530,7 +535,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
->setStartDate(new \DateTime('-10 days'))
->setAllowEmptyDescriptions(false)
;
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
$data = [
'activity' => 1,
@@ -540,7 +545,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
'description' => 'foo',
'exported' => true,
];
- $this->request($client, '/api/timesheets/15', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $timesheets[0]->getId(), 'PATCH', [], json_encode($data));
$response = $client->getResponse();
$this->assertFalse($response->isSuccessful());
$this->assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode());
@@ -556,7 +561,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testInvalidPatchAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
$data = [
'activity' => 10,
@@ -565,7 +570,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
'end' => (new \DateTime('- 7 hours'))->format('Y-m-d H:m'),
'description' => 'foo',
];
- $this->request($client, '/api/timesheets/1', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $timesheets[0]->getId(), 'PATCH', [], json_encode($data));
$response = $client->getResponse();
$this->assertEquals(400, $response->getStatusCode());
@@ -577,8 +582,8 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
- $this->assertAccessIsGranted($client, '/api/timesheets/1');
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $this->assertAccessIsGranted($client, '/api/timesheets/' . $timesheets[0]->getId());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
@@ -600,11 +605,9 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testDeleteActionForDifferentUser()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
- $id = 1;
-
- $this->request($client, '/api/timesheets/' . $id, 'DELETE');
+ $this->request($client, '/api/timesheets/' . $timesheets[0]->getId(), 'DELETE');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
$this->assertEmpty($client->getResponse()->getContent());
@@ -614,9 +617,9 @@ class TimesheetControllerTest extends APIControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$this->importFixtureForUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_ADMIN);
+ $timesheets = $this->importFixtureForUser(User::ROLE_ADMIN);
- $this->request($client, '/api/timesheets/15', 'DELETE');
+ $this->request($client, '/api/timesheets/' . $timesheets[0]->getId(), 'DELETE');
$response = $client->getResponse();
$this->assertFalse($response->isSuccessful());
@@ -632,12 +635,13 @@ class TimesheetControllerTest extends APIControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
+ $id = $timesheet->getId();
$timesheet->setExported(true);
$em->persist($timesheet);
$em->flush();
- $this->request($client, '/api/timesheets/1', 'DELETE');
+ $this->request($client, '/api/timesheets/' . $id, 'DELETE');
$this->assertApiResponseAccessDenied($client->getResponse(), 'You are not allowed to delete this timesheet');
}
@@ -648,12 +652,13 @@ class TimesheetControllerTest extends APIControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
+ $id = $timesheet->getId();
$timesheet->setExported(true);
$em->persist($timesheet);
$em->flush();
- $this->request($client, '/api/timesheets/1', 'DELETE');
+ $this->request($client, '/api/timesheets/' . $id, 'DELETE');
$this->assertTrue($client->getResponse()->isSuccessful());
}
@@ -731,9 +736,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
->setStartDate($start)
->setAmountRunning(1)
;
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ $id = $timesheets[0]->getId();
- $this->request($client, '/api/timesheets/11/stop', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/stop', 'PATCH');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -743,15 +749,16 @@ class TimesheetControllerTest extends APIControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
}
public function testStopActionFailsOnStoppedEntry()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
- $this->request($client, '/api/timesheets/1/stop', 'PATCH');
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
+ $this->request($client, '/api/timesheets/' . $id . '/stop', 'PATCH');
$this->assertApiException($client->getResponse(), 'Timesheet entry already stopped');
}
@@ -777,9 +784,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
->setStartDate($start)
->setAmountRunning(3)
;
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ $id = $timesheets[3]->getId();
- $this->request($client, '/api/timesheets/12/stop', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/stop', 'PATCH');
$this->assertApiResponseAccessDenied($client->getResponse(), 'You are not allowed to stop this timesheet');
}
@@ -806,7 +814,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
$this->assertIsArray($result);
$this->assertNotEmpty($result);
- $this->assertEquals(5, \count($result));
+ $this->assertEquals(10, \count($result));
self::assertApiResponseTypeStructure('TimesheetCollection', $result[0]);
$query = ['tags' => 'Test,Admin'];
@@ -831,15 +839,16 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testRestartAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
$data = [
'description' => 'foo',
'tags' => 'another,testing,bar'
];
- $this->request($client, '/api/timesheets/1', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $id, 'PATCH', [], json_encode($data));
- $this->request($client, '/api/timesheets/1/restart', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/restart', 'PATCH');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -861,16 +870,17 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testRestartActionWithBegin()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
$data = [
'description' => 'foo',
'tags' => 'another,testing,bar'
];
- $this->request($client, '/api/timesheets/1', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $id, 'PATCH', [], json_encode($data));
$begin = new \DateTime('2019-11-27 13:55:00');
- $this->request($client, '/api/timesheets/1/restart', 'PATCH', ['begin' => $begin->format(BaseApiController::DATE_FORMAT_PHP)]);
+ $this->request($client, '/api/timesheets/' . $id . '/restart', 'PATCH', ['begin' => $begin->format(BaseApiController::DATE_FORMAT_PHP)]);
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -893,11 +903,12 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testRestartActionWithCopyData()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$timesheet->setDescription('foo');
$timesheet->addTag((new Tag())->setName('another'));
$timesheet->addTag((new Tag())->setName('testing'));
@@ -908,10 +919,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
$em->persist($timesheet);
$em->flush();
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertEquals('foo', $timesheet->getDescription());
- $this->request($client, '/api/timesheets/1/restart', 'PATCH', ['copy' => 'all']);
+ $this->request($client, '/api/timesheets/' . $id . '/restart', 'PATCH', ['copy' => 'all']);
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -946,9 +957,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
->setStartDate($start)
->setAmountRunning(3)
;
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ $id = $timesheets[0]->getId();
- $this->request($client, '/api/timesheets/2/restart', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/restart', 'PATCH');
$this->assertApiResponseAccessDenied($client->getResponse(), 'You are not allowed to re-start this timesheet');
}
@@ -999,56 +1011,61 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testExportAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertFalse($timesheet->isExported());
- $this->request($client, '/api/timesheets/1/export', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/export', 'PATCH');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
self::assertApiResponseTypeStructure('TimesheetEntity', $result);
$em->clear();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertTrue($timesheet->isExported());
- $this->request($client, '/api/timesheets/1/export', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/export', 'PATCH');
$this->assertTrue($client->getResponse()->isSuccessful());
$em->clear();
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertFalse($timesheet->isExported());
}
public function testExportNotAllowedForUser()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
- $this->request($client, '/api/timesheets/1/export', 'PATCH');
+ $this->request($client, '/api/timesheets/' . $id . '/export', 'PATCH');
$this->assertApiResponseAccessDenied($client->getResponse(), 'You are not allowed to lock this timesheet');
}
public function testExportThrowsNotFound()
{
- $this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/export', []);
+ $id = PHP_INT_MAX;
+ $this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/' . $id . '/export', []);
}
public function testMetaActionThrowsNotFound()
{
- $this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/meta', []);
+ $id = PHP_INT_MAX;
+ $this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/' . $id . '/meta', []);
}
public function testMetaActionThrowsExceptionOnMissingName()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
- return $this->assertExceptionForMethod($client, '/api/timesheets/1/meta', 'PATCH', ['value' => 'X'], [
+ return $this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['value' => 'X'], [
'code' => 400,
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
]);
@@ -1057,9 +1074,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testMetaActionThrowsExceptionOnMissingValue()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
- return $this->assertExceptionForMethod($client, '/api/timesheets/1/meta', 'PATCH', ['name' => 'X'], [
+ return $this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['name' => 'X'], [
'code' => 400,
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
]);
@@ -1068,9 +1086,10 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testMetaActionThrowsExceptionOnMissingMetafield()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
- return $this->assertExceptionForMethod($client, '/api/timesheets/1/meta', 'PATCH', ['name' => 'X', 'value' => 'Y'], [
+ return $this->assertExceptionForMethod($client, '/api/timesheets/' . $id . '/meta', 'PATCH', ['name' => 'X', 'value' => 'Y'], [
'code' => 500,
'message' => 'Unknown meta-field requested'
]);
@@ -1079,14 +1098,15 @@ class TimesheetControllerTest extends APIControllerBaseTest
public function testMetaAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
- $this->importFixtureForUser(User::ROLE_USER);
+ $timesheets = $this->importFixtureForUser(User::ROLE_USER);
+ $id = $timesheets[0]->getId();
static::$container->get('event_dispatcher')->addSubscriber(new TimesheetTestMetaFieldSubscriberMock());
$data = [
'name' => 'metatestmock',
'value' => 'another,testing,bar'
];
- $this->request($client, '/api/timesheets/1/meta', 'PATCH', [], json_encode($data));
+ $this->request($client, '/api/timesheets/' . $id . '/meta', 'PATCH', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -1096,7 +1116,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertEquals('another,testing,bar', $timesheet->getMetaField('metatestmock')->getValue());
}
}
diff --git a/tests/Command/CreateReleaseCommandTest.php b/tests/Command/CreateReleaseCommandTest.php
deleted file mode 100644
index db5fb844..00000000
--- a/tests/Command/CreateReleaseCommandTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
- 'test']);
- $application = new Application($kernel);
- $application->add(new CreateReleaseCommand(realpath(__DIR__ . '/../../'), 'test'));
-
- $command = $application->find('kimai:create-release');
- self::assertTrue($command->isEnabled());
- self::assertInstanceOf(CreateReleaseCommand::class, $command);
- }
-
- public function testCommandNameIsNotAvailableInProd()
- {
- $command = new CreateReleaseCommand(realpath(__DIR__ . '/../../'), 'prod');
- self::assertFalse($command->isEnabled());
- }
-}
diff --git a/tests/Command/InstallCommandTest.php b/tests/Command/InstallCommandTest.php
index c4b7f252..19ac22e7 100644
--- a/tests/Command/InstallCommandTest.php
+++ b/tests/Command/InstallCommandTest.php
@@ -10,11 +10,9 @@
namespace App\Tests\Command;
use App\Command\InstallCommand;
-use App\Constants;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Tester\CommandTester;
/**
* @covers \App\Command\InstallCommand
@@ -40,30 +38,4 @@ class InstallCommandTest extends KernelTestCase
return $this->application->find('kimai:install');
}
-
- public function testFullRunWithEverythingPreInstalled()
- {
- $command = $this->getCommand();
- $commandTester = new CommandTester($command);
- $commandTester->setInputs(['no']);
- $commandTester->execute([
- 'command' => $command->getName(),
- ]);
-
- $result = $commandTester->getDisplay();
-
- self::assertStringContainsString('Kimai installation running', $result);
- // create database is skipped
- self::assertStringContainsString('[NOTE] Database is existing and connection could be established', $result);
- // make sure migrations run always
- self::assertStringContainsString('Application Migrations', $result);
- self::assertStringContainsString('No migrations to execute.', $result);
-
- self::assertStringContainsString(
- sprintf('[OK] Congratulations! Successfully installed Kimai 2 version %s (%s)', Constants::VERSION, Constants::STATUS),
- $result
- );
-
- self::assertEquals(0, $commandTester->getStatusCode());
- }
}
diff --git a/tests/Command/InvoiceCreateCommandTest.php b/tests/Command/InvoiceCreateCommandTest.php
index 9e4cf865..ec072991 100644
--- a/tests/Command/InvoiceCreateCommandTest.php
+++ b/tests/Command/InvoiceCreateCommandTest.php
@@ -21,7 +21,7 @@ use App\Repository\ProjectRepository;
use App\Repository\TimesheetRepository;
use App\Repository\UserRepository;
use App\Tests\DataFixtures\CustomerFixtures;
-use App\Tests\DataFixtures\InvoiceFixtures;
+use App\Tests\DataFixtures\InvoiceTemplateFixtures;
use App\Tests\DataFixtures\ProjectFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
use App\Tests\KernelTestTrait;
@@ -176,7 +176,7 @@ class InvoiceCreateCommandTest extends KernelTestCase
public function testCreateInvoice()
{
- $fixture = new InvoiceFixtures();
+ $fixture = new InvoiceTemplateFixtures();
$this->importFixture($fixture);
$commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--set-exported' => null, '--customer' => 1, '--template' => 'Invoice', '--start' => '2020-01-01', '--end' => '2020-03-01']);
@@ -185,7 +185,7 @@ class InvoiceCreateCommandTest extends KernelTestCase
$this->assertStringContainsString('+----+----------+-------+------------- Created 1 invoice(s) --------------------------------------+', $output);
$this->assertStringContainsString('| ID | Customer | Total | Filename |', $output);
$this->assertStringContainsString('+----+----------+-------+-------------------------------------------------------------------------+', $output);
- $this->assertStringContainsString('| 1 | Test | 0 EUR | /', $output);
+ $this->assertStringContainsString('| Test | 0 EUR | /', $output);
$this->assertStringContainsString('/tests/_data/invoices/' . ((new \DateTime())->format('Y')) . '-001-Test.html |', $output);
}
@@ -201,22 +201,24 @@ class InvoiceCreateCommandTest extends KernelTestCase
$meta->setValue('Invoice');
$customer->setMetaField($meta);
});
- $this->importFixture($fixture);
+ $customer = $this->importFixture($fixture)[0];
$fixture = new ProjectFixtures();
- $fixture->setCustomers([$em->getRepository(Customer::class)->find(2)]);
+ $fixture->setCustomers([$customer]);
$fixture->setAmount(1);
- $this->importFixture($fixture);
+ $projects = $this->importFixture($fixture);
$fixture = new TimesheetFixtures();
$fixture->setUser($this->getUserByName(UserFixtures::USERNAME_SUPER_ADMIN));
$fixture->setAmount(20);
$fixture->setStartDate($start);
- $fixture->setProjects([$em->getRepository(Project::class)->find(2)]);
+ $fixture->setProjects($projects);
$this->importFixture($fixture);
- $fixture = new InvoiceFixtures();
+ $fixture = new InvoiceTemplateFixtures();
$this->importFixture($fixture);
+
+ return [$customer];
}
public function testCreateInvoiceByCustomer()
@@ -237,9 +239,10 @@ class InvoiceCreateCommandTest extends KernelTestCase
$start = new \DateTime('-2 months');
$end = new \DateTime();
- $this->prepareFixtures($start);
+ $imports = $this->prepareFixtures($start);
+ $customer = $imports[0]->getId();
- $commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => '2,1', '--template-meta' => 'template', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
+ $commandTester = $this->createInvoice(['--user' => UserFixtures::USERNAME_SUPER_ADMIN, '--customer' => $customer . ',1', '--template-meta' => 'template', '--start' => $start->format('Y-m-d'), '--end' => $end->format('Y-m-d')]);
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Created 1 invoice(s) ', $output);
diff --git a/tests/Command/ResetCommandTest.php b/tests/Command/ResetDevelopmentCommandTest.php
similarity index 58%
rename from tests/Command/ResetCommandTest.php
rename to tests/Command/ResetDevelopmentCommandTest.php
index 13a94436..f9750fa0 100644
--- a/tests/Command/ResetCommandTest.php
+++ b/tests/Command/ResetDevelopmentCommandTest.php
@@ -9,29 +9,30 @@
namespace App\Tests\Command;
-use App\Command\ResetCommand;
+use App\Command\ResetDevelopmentCommand;
+use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
- * @covers \App\Command\ResetCommand
+ * @covers \App\Command\ResetDevelopmentCommand
* @group integration
*/
-class ResetCommandTest extends KernelTestCase
+class ResetDevelopmentCommandTest extends KernelTestCase
{
public function testCommandName()
{
$kernel = self::bootKernel();
$application = new Application($kernel);
- $application->add(new ResetCommand('test'));
+ $application->add(new ResetDevelopmentCommand('test', $this->createMock(EntityManagerInterface::class)));
$command = $application->find('kimai:reset-dev');
- self::assertInstanceOf(ResetCommand::class, $command);
+ self::assertInstanceOf(ResetDevelopmentCommand::class, $command);
}
public function testCommandNameIsNotEnabledInProd()
{
- $command = new ResetCommand('prod');
+ $command = new ResetDevelopmentCommand('prod', $this->createMock(EntityManagerInterface::class));
self::assertFalse($command->isEnabled());
}
}
diff --git a/tests/Command/ResetTestCommandTest.php b/tests/Command/ResetTestCommandTest.php
new file mode 100644
index 00000000..366e85fe
--- /dev/null
+++ b/tests/Command/ResetTestCommandTest.php
@@ -0,0 +1,38 @@
+add(new ResetTestCommand('test', $this->createMock(EntityManagerInterface::class)));
+
+ $command = $application->find('kimai:reset-test');
+ self::assertInstanceOf(ResetTestCommand::class, $command);
+ }
+
+ public function testCommandNameIsNotEnabledInProd()
+ {
+ $command = new ResetTestCommand('prod', $this->createMock(EntityManagerInterface::class));
+ self::assertFalse($command->isEnabled());
+ }
+}
diff --git a/tests/ConsoleApplicationTest.php b/tests/ConsoleApplicationTest.php
new file mode 100644
index 00000000..db7de04c
--- /dev/null
+++ b/tests/ConsoleApplicationTest.php
@@ -0,0 +1,29 @@
+createMock(KernelInterface::class);
+ $sut = new ConsoleApplication($kernel);
+ self::assertEquals(Constants::SOFTWARE, $sut->getName());
+ self::assertEquals(Constants::VERSION, $sut->getVersion());
+ }
+}
diff --git a/tests/Controller/ActivityControllerTest.php b/tests/Controller/ActivityControllerTest.php
index 2e86a8e2..cbacf262 100644
--- a/tests/Controller/ActivityControllerTest.php
+++ b/tests/Controller/ActivityControllerTest.php
@@ -180,7 +180,11 @@ class ActivityControllerTest extends ControllerBaseTest
$client->followRedirect();
$this->assertHasDataTable($client);
- $this->request($client, '/admin/activity/2/edit');
+ $activities = $this->getEntityManager()->getRepository(Activity::class)->findAll();
+ $activity = array_pop($activities);
+ $id = $activity->getId();
+
+ $this->request($client, '/admin/activity/' . $id . '/edit');
$editForm = $client->getCrawler()->filter('form[name=activity_edit_form]')->form();
$this->assertEquals('An AcTiVitY Name', $editForm->get('activity_edit_form[name]')->getValue());
// make sure customer and project are pre-selected for none global activities
@@ -240,15 +244,16 @@ class ActivityControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Activity $activity */
- $activity = $em->getRepository(Activity::class)->find(1);
+ $activity = $em->getRepository(Activity::class)->findAll()[0];
self::assertEquals(0, $activity->getTeams()->count());
+ $id = $activity->getId();
$fixture = new TeamFixtures();
$fixture->setAmount(2);
$fixture->setAddCustomer(false);
$this->importFixture($fixture);
- $this->assertAccessIsGranted($client, '/admin/activity/1/permissions');
+ $this->assertAccessIsGranted($client, '/admin/activity/' . $id . '/permissions');
$form = $client->getCrawler()->filter('form[name=activity_team_permission_form]')->form();
/** @var ChoiceFormField $team1 */
$team1 = $form->get('activity_team_permission_form[teams][0]');
@@ -263,7 +268,7 @@ class ActivityControllerTest extends ControllerBaseTest
$this->assertHasDataTable($client);
/** @var Activity $activity */
- $activity = $em->getRepository(Activity::class)->find(1);
+ $activity = $em->getRepository(Activity::class)->find($id);
self::assertEquals(2, $activity->getTeams()->count());
}
@@ -342,10 +347,9 @@ class ActivityControllerTest extends ControllerBaseTest
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasNoEntriesWithFilter($client);
- // SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
- // $em->clear();
- // $timesheets = $em->getRepository(Timesheet::class)->findAll();
- // $this->assertEquals(0, count($timesheets));
+ $em->clear();
+ $timesheets = $em->getRepository(Timesheet::class)->findAll();
+ $this->assertEquals(0, \count($timesheets));
$this->request($client, '/admin/activity/1/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
@@ -364,7 +368,9 @@ class ActivityControllerTest extends ControllerBaseTest
$this->importFixture($fixture);
$fixture = new ActivityFixtures();
$fixture->setAmount(1)->setIsGlobal(true)->setIsVisible(true);
- $this->importFixture($fixture);
+ $activities = $this->importFixture($fixture);
+ $activity = $activities[0];
+ $id = $activity->getId();
$timesheets = $em->getRepository(Timesheet::class)->findAll();
$this->assertEquals(10, \count($timesheets));
@@ -381,7 +387,7 @@ class ActivityControllerTest extends ControllerBaseTest
$this->assertStringEndsWith($this->createUrl('/admin/activity/1/delete'), $form->getUri());
$client->submit($form, [
'form' => [
- 'activity' => 2
+ 'activity' => $id
]
]);
@@ -395,7 +401,7 @@ class ActivityControllerTest extends ControllerBaseTest
/** @var Timesheet $entry */
foreach ($timesheets as $entry) {
- $this->assertEquals(2, $entry->getActivity()->getId());
+ $this->assertEquals($id, $entry->getActivity()->getId());
}
$this->request($client, '/admin/activity/1/edit');
diff --git a/tests/Controller/CustomerControllerTest.php b/tests/Controller/CustomerControllerTest.php
index f0f7bcb8..2795b064 100644
--- a/tests/Controller/CustomerControllerTest.php
+++ b/tests/Controller/CustomerControllerTest.php
@@ -10,6 +10,7 @@
namespace App\Tests\Controller;
use App\Entity\Customer;
+use App\Entity\CustomerComment;
use App\Entity\CustomerMeta;
use App\Entity\Timesheet;
use App\Entity\User;
@@ -176,9 +177,12 @@ class CustomerControllerTest extends ControllerBaseTest
$node = $client->getCrawler()->filter('div.box#comments_box .direct-chat-msg');
self::assertStringContainsString('Blah foo bar', $node->html());
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.confirmation-link');
- self::assertEquals($this->createUrl('/admin/customer/1/comment_delete'), $node->attr('href'));
+ self::assertStringEndsWith('/comment_delete', $node->attr('href'));
- $this->request($client, '/admin/customer/1/comment_delete');
+ $comments = $this->getEntityManager()->getRepository(CustomerComment::class)->findAll();
+ $id = $comments[0]->getId();
+
+ $this->request($client, '/admin/customer/' . $id . '/comment_delete');
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body');
@@ -202,12 +206,15 @@ class CustomerControllerTest extends ControllerBaseTest
$node = $client->getCrawler()->filter('div.box#comments_box .direct-chat-text a.btn.active');
self::assertEquals(0, $node->count());
- $this->request($client, '/admin/customer/1/comment_pin');
+ $comments = $this->getEntityManager()->getRepository(CustomerComment::class)->findAll();
+ $id = $comments[0]->getId();
+
+ $this->request($client, '/admin/customer/' . $id . '/comment_pin');
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.btn.active');
self::assertEquals(1, $node->count());
- self::assertEquals($this->createUrl('/admin/customer/1/comment_pin'), $node->attr('href'));
+ self::assertEquals($this->createUrl('/admin/customer/' . $id . '/comment_pin'), $node->attr('href'));
}
public function testCreateDefaultTeamAction()
@@ -278,7 +285,7 @@ class CustomerControllerTest extends ControllerBaseTest
'name' => 'Test Customer',
]
]);
- $this->assertIsRedirect($client, $this->createUrl('/admin/customer/2/details'));
+ $this->assertIsRedirect($client, '/details');
$client->followRedirect();
$this->assertHasFlashSuccess($client);
}
@@ -352,22 +359,24 @@ class CustomerControllerTest extends ControllerBaseTest
$fixture = new CustomerFixtures();
$fixture->setAmount(1);
- $this->importFixture($fixture);
+ $customers = $this->importFixture($fixture);
+ $customer = $customers[0];
+ $id = $customer->getId();
- $this->request($client, '/admin/customer/2/edit');
+ $this->request($client, '/admin/customer/' . $id . '/edit');
$this->assertTrue($client->getResponse()->isSuccessful());
- $this->request($client, '/admin/customer/2/delete');
+ $this->request($client, '/admin/customer/' . $id . '/delete');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
- $this->assertStringEndsWith($this->createUrl('/admin/customer/2/delete'), $form->getUri());
+ $this->assertStringEndsWith($this->createUrl('/admin/customer/' . $id . '/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasDataTable($client);
$this->assertHasFlashSuccess($client);
- $this->request($client, '/admin/customer/2/edit');
+ $this->request($client, '/admin/customer/' . $id . '/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
}
@@ -401,10 +410,9 @@ class CustomerControllerTest extends ControllerBaseTest
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasNoEntriesWithFilter($client);
- // SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
- // $em->clear();
- // $timesheets = $em->getRepository(Timesheet::class)->findAll();
- // $this->assertEquals(0, count($timesheets));
+ $em->clear();
+ $timesheets = $em->getRepository(Timesheet::class)->findAll();
+ $this->assertEquals(0, \count($timesheets));
$this->request($client, '/admin/customer/1/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
@@ -421,7 +429,9 @@ class CustomerControllerTest extends ControllerBaseTest
$this->importFixture($fixture);
$fixture = new CustomerFixtures();
$fixture->setAmount(1)->setIsVisible(true);
- $this->importFixture($fixture);
+ $customers = $this->importFixture($fixture);
+ $customer = $customers[0];
+ $id = $customer->getId();
$timesheets = $em->getRepository(Timesheet::class)->findAll();
$this->assertEquals(10, \count($timesheets));
@@ -438,7 +448,7 @@ class CustomerControllerTest extends ControllerBaseTest
$this->assertStringEndsWith($this->createUrl('/admin/customer/1/delete'), $form->getUri());
$client->submit($form, [
'form' => [
- 'customer' => 2
+ 'customer' => $id
]
]);
@@ -452,7 +462,7 @@ class CustomerControllerTest extends ControllerBaseTest
/** @var Timesheet $entry */
foreach ($timesheets as $entry) {
- $this->assertEquals(2, $entry->getProject()->getCustomer()->getId());
+ $this->assertEquals($id, $entry->getProject()->getCustomer()->getId());
}
$this->request($client, '/admin/customer/1/edit');
diff --git a/tests/Controller/InvoiceControllerTest.php b/tests/Controller/InvoiceControllerTest.php
index b43e7f79..fe0cf2c8 100644
--- a/tests/Controller/InvoiceControllerTest.php
+++ b/tests/Controller/InvoiceControllerTest.php
@@ -9,13 +9,13 @@
namespace App\Tests\Controller;
+use App\Entity\Invoice;
use App\Entity\InvoiceTemplate;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Form\Type\DateRangeType;
-use App\Tests\DataFixtures\InvoiceFixtures;
+use App\Tests\DataFixtures\InvoiceTemplateFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
-use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
/**
@@ -69,10 +69,11 @@ class InvoiceControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $templates = $this->importFixture($fixture);
+ $id = $templates[0]->getId();
- $this->request($client, '/invoice/?customer=1&template=1&preview=');
+ $this->request($client, '/invoice/?customer=1&template=' . $id . '&preview=');
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasNoEntriesWithFilter($client);
@@ -82,7 +83,7 @@ class InvoiceControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $fixture = new InvoiceFixtures();
+ $fixture = new InvoiceTemplateFixtures();
$this->importFixture($fixture);
$this->request($client, '/invoice/template');
@@ -117,15 +118,13 @@ class InvoiceControllerTest extends ControllerBaseTest
public function testCopyTemplateAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $em = $this->getEntityManager();
-
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $templates = $this->importFixture($fixture);
/** @var InvoiceTemplate $template */
- $template = $em->getRepository(InvoiceTemplate::class)->find(1);
+ $template = $templates[0];
- $this->request($client, '/invoice/template/create/1');
+ $this->request($client, '/invoice/template/create/' . $template->getId());
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=invoice_template_form]')->form();
@@ -144,11 +143,10 @@ class InvoiceControllerTest extends ControllerBaseTest
public function testCreateAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- /** @var EntityManager $em */
- $em = $this->getEntityManager();
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $templates = $this->importFixture($fixture);
+ $template = $templates[0];
$begin = new \DateTime('first day of this month');
$end = new \DateTime('last day of this month');
@@ -158,7 +156,10 @@ class InvoiceControllerTest extends ControllerBaseTest
->setAmount(20)
->setStartDate($begin)
;
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ foreach ($timesheets as $timesheet) {
+ $this->assertFalse($timesheet->isExported());
+ }
$this->request($client, '/invoice/');
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -170,7 +171,7 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?preview='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $template->getId(),
'daterange' => $dateRange,
'customer' => 1,
]);
@@ -188,7 +189,7 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?create='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $template->getId(),
'daterange' => $dateRange,
'customer' => 1,
'projects' => [1],
@@ -200,7 +201,10 @@ class InvoiceControllerTest extends ControllerBaseTest
$this->assertEquals(1, $node->count());
$this->assertEquals('invoice_print', $node->getIterator()[0]->getAttribute('class'));
+ $em = $this->getEntityManager();
+ $em->clear();
$timesheets = $em->getRepository(Timesheet::class)->findAll();
+ $this->assertCount(20, $timesheets);
/** @var Timesheet $timesheet */
foreach ($timesheets as $timesheet) {
$this->assertTrue($timesheet->isExported());
@@ -210,11 +214,10 @@ class InvoiceControllerTest extends ControllerBaseTest
public function testPrintAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- /** @var EntityManager $em */
- $em = $this->getEntityManager();
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $templates = $this->importFixture($fixture);
+ $id = $templates[0]->getId();
$begin = new \DateTime('first day of this month');
$end = new \DateTime('last day of this month');
@@ -236,7 +239,7 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?preview='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $id,
'daterange' => $dateRange,
'customer' => 1,
]);
@@ -254,7 +257,7 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?print='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $id,
'daterange' => $dateRange,
'customer' => 1,
'projects' => [1],
@@ -269,11 +272,10 @@ class InvoiceControllerTest extends ControllerBaseTest
public function testCreateActionAsAdminWithDownloadAndStatusChangeAndDelete()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- /** @var EntityManager $em */
- $em = $this->getEntityManager();
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $templates = $this->importFixture($fixture);
+ $template = $templates[0];
$begin = new \DateTime('first day of this month');
$end = new \DateTime('last day of this month');
@@ -295,7 +297,7 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?preview='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $template->getId(),
'daterange' => $dateRange,
'customer' => 1,
]);
@@ -313,14 +315,17 @@ class InvoiceControllerTest extends ControllerBaseTest
$node->setAttribute('action', $this->createUrl('/invoice/?create='));
$node->setAttribute('method', 'GET');
$client->submit($form, [
- 'template' => 1,
+ 'template' => $template->getId(),
'daterange' => $dateRange,
'customer' => 1,
'projects' => [1],
'markAsExported' => 1,
]);
- $this->assertIsRedirect($client, '/invoice/show?id=1');
+ $invoices = $this->getEntityManager()->getRepository(Invoice::class)->findAll();
+ $id = $invoices[0]->getId();
+
+ $this->assertIsRedirect($client, '/invoice/show?id=' . $id);
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -330,28 +335,28 @@ class InvoiceControllerTest extends ControllerBaseTest
$this->assertDataTableRowCount($client, 'datatable_invoices', 1);
// make sure the invoice is saved
- $this->request($client, '/invoice/download/1');
+ $this->request($client, '/invoice/download/' . $id);
$response = $client->getResponse();
$this->assertTrue($response->isSuccessful());
self::assertInstanceOf(BinaryFileResponse::class, $response);
self::assertFileExists($response->getFile());
- $this->request($client, '/invoice/change-status/1/pending');
+ $this->request($client, '/invoice/change-status/' . $id . '/pending');
$this->assertIsRedirect($client, '/invoice/show');
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
- $this->request($client, '/invoice/change-status/1/paid');
+ $this->request($client, '/invoice/change-status/' . $id . '/paid');
$this->assertIsRedirect($client, '/invoice/show');
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
- $this->request($client, '/invoice/change-status/1/new');
+ $this->request($client, '/invoice/change-status/' . $id . '/new');
$this->assertIsRedirect($client, '/invoice/show');
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
- $this->request($client, '/invoice/delete/1');
+ $this->request($client, '/invoice/delete/' . $id);
$this->assertIsRedirect($client, '/invoice/show');
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -361,10 +366,11 @@ class InvoiceControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $template = $this->importFixture($fixture);
+ $id = $template[0]->getId();
- $this->request($client, '/invoice/template/1/edit?page=1');
+ $this->request($client, '/invoice/template/' . $id . '/edit?page=1');
$form = $client->getCrawler()->filter('form[name=invoice_template_form]')->form();
$client->submit($form, [
'invoice_template_form' => [
@@ -387,26 +393,25 @@ class InvoiceControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $em = $this->getEntityManager();
- $fixture = new InvoiceFixtures();
- $this->importFixture($fixture);
+ $fixture = new InvoiceTemplateFixtures();
+ $template = $this->importFixture($fixture);
+ $id = $template[0]->getId();
- $this->request($client, '/invoice/template/1/delete');
+ $this->request($client, '/invoice/template/' . $id . '/delete');
$this->assertIsRedirect($client, '/invoice/template');
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSuccess($client);
- $this->assertEquals(0, $em->getRepository(InvoiceTemplate::class)->count([]));
+ $this->assertEquals(0, $this->getEntityManager()->getRepository(InvoiceTemplate::class)->count([]));
}
public function testUploadDocumentAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
- $em = $this->getEntityManager();
- $fixture = new InvoiceFixtures();
+ $fixture = new InvoiceTemplateFixtures();
$this->importFixture($fixture);
$this->request($client, '/invoice/document_upload');
diff --git a/tests/Controller/PermissionControllerTest.php b/tests/Controller/PermissionControllerTest.php
index 232b68ad..a73a6ccf 100644
--- a/tests/Controller/PermissionControllerTest.php
+++ b/tests/Controller/PermissionControllerTest.php
@@ -10,6 +10,7 @@
namespace App\Tests\Controller;
use App\DataFixtures\UserFixtures;
+use App\Entity\Role;
use App\Entity\RolePermission;
use App\Entity\User;
use Symfony\Component\Security\Csrf\CsrfToken;
@@ -104,6 +105,15 @@ class PermissionControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/admin/permissions'));
$client->followRedirect();
+ $roles = $this->getEntityManager()->getRepository(Role::class)->findAll();
+ $id = null;
+ foreach ($roles as $role) {
+ if ($role->getName() === 'TEST_ROLE') {
+ $id = $role->getId();
+ break;
+ }
+ }
+
$content = $client->getResponse()->getContent();
self::assertStringContainsString('| ', $content);
@@ -126,7 +136,7 @@ class PermissionControllerTest extends ControllerBaseTest
/** @var CsrfToken $token */
$token = static::$kernel->getContainer()->get('security.csrf.token_manager')->getToken('user_role_permissions');
- $this->request($client, '/admin/permissions/roles/1/delete/' . $token->getValue());
+ $this->request($client, '/admin/permissions/roles/' . $id . '/delete/' . $token->getValue());
$this->assertIsRedirect($client, $this->createUrl('/admin/permissions'));
$client->followRedirect();
@@ -166,9 +176,18 @@ class PermissionControllerTest extends ControllerBaseTest
$rolePermissions = $em->getRepository(RolePermission::class)->findAll();
$this->assertEquals(0, \count($rolePermissions));
+ $roles = $em->getRepository(Role::class)->findAll();
+ $id = null;
+ foreach ($roles as $role) {
+ if ($role->getName() === 'TEST_ROLE') {
+ $id = $role->getId();
+ break;
+ }
+ }
+
// create the permission
$token = static::$kernel->getContainer()->get('security.csrf.token_manager')->getToken('user_role_permissions');
- $this->request($client, '/admin/permissions/roles/1/view_user/1/' . $token->getValue(), 'POST');
+ $this->request($client, '/admin/permissions/roles/' . $id . '/view_user/1/' . $token->getValue(), 'POST');
self::assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
@@ -182,14 +201,14 @@ class PermissionControllerTest extends ControllerBaseTest
self::assertEquals('view_user', $permission->getPermission());
self::assertTrue($permission->isAllowed());
self::assertEquals('TEST_ROLE', $permission->getRole()->getName());
- self::assertEquals(1, $permission->getRole()->getId());
+ self::assertEquals($id, $permission->getRole()->getId());
// flush the cache to prevent wrong results
$em->clear();
// update the permission
$token = static::$kernel->getContainer()->get('security.csrf.token_manager')->getToken('user_role_permissions');
- $this->request($client, '/admin/permissions/roles/1/view_user/0/' . $token->getValue(), 'POST');
+ $this->request($client, '/admin/permissions/roles/' . $id . '/view_user/0/' . $token->getValue(), 'POST');
self::assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
diff --git a/tests/Controller/ProjectControllerTest.php b/tests/Controller/ProjectControllerTest.php
index bb5d3c1d..d04d058a 100644
--- a/tests/Controller/ProjectControllerTest.php
+++ b/tests/Controller/ProjectControllerTest.php
@@ -13,6 +13,7 @@ use App\Entity\Activity;
use App\Entity\ActivityMeta;
use App\Entity\ActivityRate;
use App\Entity\Project;
+use App\Entity\ProjectComment;
use App\Entity\ProjectMeta;
use App\Entity\ProjectRate;
use App\Entity\Team;
@@ -213,7 +214,7 @@ class ProjectControllerTest extends ControllerBaseTest
$em->persist($rate);
$this->request($client, '/admin/project/1/duplicate');
- $this->assertIsRedirect($client, $this->createUrl('/admin/project/2/details'));
+ $this->assertIsRedirect($client, '/details');
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#project_rates_box');
self::assertEquals(1, $node->count());
@@ -253,9 +254,12 @@ class ProjectControllerTest extends ControllerBaseTest
$node = $client->getCrawler()->filter('div.box#comments_box .direct-chat-text');
self::assertStringContainsString('Foo bar blub', $node->html());
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.confirmation-link');
- self::assertEquals($this->createUrl('/admin/project/1/comment_delete'), $node->attr('href'));
- $this->request($client, '/admin/project/1/comment_delete');
+ $comments = $this->getEntityManager()->getRepository(ProjectComment::class)->findAll();
+ $id = $comments[0]->getId();
+
+ self::assertEquals($this->createUrl('/admin/project/' . $id . '/comment_delete'), $node->attr('href'));
+ $this->request($client, '/admin/project/' . $id . '/comment_delete');
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body');
@@ -279,12 +283,15 @@ class ProjectControllerTest extends ControllerBaseTest
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.btn.active');
self::assertEquals(0, $node->count());
- $this->request($client, '/admin/project/1/comment_pin');
+ $comments = $this->getEntityManager()->getRepository(ProjectComment::class)->findAll();
+ $id = $comments[0]->getId();
+
+ $this->request($client, '/admin/project/' . $id . '/comment_pin');
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#comments_box .box-body a.btn.active');
self::assertEquals(1, $node->count());
- self::assertEquals($this->createUrl('/admin/project/1/comment_pin'), $node->attr('href'));
+ self::assertEquals($this->createUrl('/admin/project/' . $id . '/comment_pin'), $node->attr('href'));
}
public function testCreateDefaultTeamAction()
@@ -346,7 +353,7 @@ class ProjectControllerTest extends ControllerBaseTest
'customer' => 1,
]
]);
- $this->assertIsRedirect($client, $this->createUrl('/admin/project/2/details'));
+ $this->assertIsRedirect($client, '/details');
$client->followRedirect();
$this->assertHasFlashSuccess($client);
}
@@ -418,22 +425,24 @@ class ProjectControllerTest extends ControllerBaseTest
$fixture = new ProjectFixtures();
$fixture->setAmount(1);
- $this->importFixture($fixture);
+ /** @var Project[] $projects */
+ $projects = $this->importFixture($fixture);
+ $id = $projects[0]->getId();
- $this->request($client, '/admin/project/2/edit');
+ $this->request($client, '/admin/project/' . $id . '/edit');
$this->assertTrue($client->getResponse()->isSuccessful());
- $this->request($client, '/admin/project/2/delete');
+ $this->request($client, '/admin/project/' . $id . '/delete');
$this->assertTrue($client->getResponse()->isSuccessful());
$form = $client->getCrawler()->filter('form[name=form]')->form();
- $this->assertStringEndsWith($this->createUrl('/admin/project/2/delete'), $form->getUri());
+ $this->assertStringEndsWith($this->createUrl('/admin/project/' . $id . '/delete'), $form->getUri());
$client->submit($form);
$client->followRedirect();
$this->assertHasDataTable($client);
$this->assertHasFlashSuccess($client);
- $this->request($client, '/admin/project/2/edit');
+ $this->request($client, '/admin/project/' . $id . '/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
}
@@ -467,10 +476,9 @@ class ProjectControllerTest extends ControllerBaseTest
$this->assertHasFlashDeleteSuccess($client);
$this->assertHasNoEntriesWithFilter($client);
- // SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
- // $em->clear();
- // $timesheets = $em->getRepository(Timesheet::class)->findAll();
- // $this->assertEquals(0, count($timesheets));
+ $em->clear();
+ $timesheets = $em->getRepository(Timesheet::class)->findAll();
+ $this->assertEquals(0, \count($timesheets));
$this->request($client, '/admin/project/1/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
@@ -487,7 +495,8 @@ class ProjectControllerTest extends ControllerBaseTest
$this->importFixture($fixture);
$fixture = new ProjectFixtures();
$fixture->setAmount(1)->setIsVisible(true);
- $this->importFixture($fixture);
+ $projects = $this->importFixture($fixture);
+ $id = $projects[0]->getId();
$timesheets = $em->getRepository(Timesheet::class)->findAll();
$this->assertEquals(10, \count($timesheets));
@@ -504,7 +513,7 @@ class ProjectControllerTest extends ControllerBaseTest
$this->assertStringEndsWith($this->createUrl('/admin/project/1/delete'), $form->getUri());
$client->submit($form, [
'form' => [
- 'project' => 2
+ 'project' => $id
]
]);
@@ -518,7 +527,7 @@ class ProjectControllerTest extends ControllerBaseTest
/** @var Timesheet $entry */
foreach ($timesheets as $entry) {
- $this->assertEquals(2, $entry->getProject()->getId());
+ $this->assertEquals($id, $entry->getProject()->getId());
}
$this->request($client, '/admin/project/1/edit');
diff --git a/tests/Controller/TagControllerTest.php b/tests/Controller/TagControllerTest.php
index 1a6613ab..05bd30f5 100644
--- a/tests/Controller/TagControllerTest.php
+++ b/tests/Controller/TagControllerTest.php
@@ -12,21 +12,24 @@ namespace App\Tests\Controller;
use App\Entity\Tag;
use App\Entity\User;
use App\Tests\DataFixtures\TagFixtures;
-use Symfony\Component\HttpKernel\HttpKernelBrowser;
/**
* @group integration
*/
class TagControllerTest extends ControllerBaseTest
{
- protected function importTags(HttpKernelBrowser $client): void
+ /**
+ * @return Tag[]
+ */
+ protected function importTags(): array
{
$tagList = ['Test', 'Administration', 'Support', '#2018-001', '#2018-002', '#2018-003', 'Development',
'Marketing', 'First Level Support', 'Bug Fixing'];
$fixture = new TagFixtures();
$fixture->setTagArray($tagList);
- $this->importFixture($fixture);
+
+ return $this->importFixture($fixture);
}
public function testIsSecure()
@@ -37,7 +40,7 @@ class TagControllerTest extends ControllerBaseTest
public function testIndexAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- $this->importTags($client);
+ $this->importTags();
$this->assertAccessIsGranted($client, '/admin/tags/');
$this->assertHasDataTable($client);
@@ -47,7 +50,7 @@ class TagControllerTest extends ControllerBaseTest
public function testIndexActionWithSearchTermQuery()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- $this->importTags($client);
+ $this->importTags();
$this->request($client, '/admin/tags/');
$this->assertTrue($client->getResponse()->isSuccessful());
@@ -76,7 +79,9 @@ class TagControllerTest extends ControllerBaseTest
$client->followRedirect();
$this->assertHasDataTable($client);
- $this->request($client, '/admin/tags/1/edit');
+ $id = $this->getEntityManager()->getRepository(Tag::class)->findAll()[0]->getId();
+
+ $this->request($client, '/admin/tags/' . $id . '/edit');
$editForm = $client->getCrawler()->filter('form[name=tag_edit_form]')->form();
$this->assertEquals('A tAG Name!', $editForm->get('tag_edit_form[name]')->getValue());
}
@@ -84,9 +89,10 @@ class TagControllerTest extends ControllerBaseTest
public function testEditAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
- $this->importTags($client);
+ $tags = $this->importTags();
+ $id = $tags[0]->getId();
- $this->assertAccessIsGranted($client, '/admin/tags/1/edit');
+ $this->assertAccessIsGranted($client, '/admin/tags/' . $id . '/edit');
$form = $client->getCrawler()->filter('form[name=tag_edit_form]')->form();
$client->submit($form, [
'tag_edit_form' => ['name' => 'Test 2 updated']
@@ -94,7 +100,7 @@ class TagControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/admin/tags/'));
$client->followRedirect();
$this->assertHasDataTable($client);
- $this->request($client, '/admin/tags/1/edit');
+ $this->request($client, '/admin/tags/' . $id . '/edit');
$editForm = $client->getCrawler()->filter('form[name=tag_edit_form]')->form();
$this->assertEquals('Test 2 updated', $editForm->get('tag_edit_form[name]')->getValue());
}
@@ -102,7 +108,7 @@ class TagControllerTest extends ControllerBaseTest
public function testMultiDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
- $this->importTags($client);
+ $this->importTags();
$this->assertAccessIsGranted($client, '/admin/tags/');
diff --git a/tests/Controller/TeamControllerTest.php b/tests/Controller/TeamControllerTest.php
index e75d11ad..aeee1b95 100644
--- a/tests/Controller/TeamControllerTest.php
+++ b/tests/Controller/TeamControllerTest.php
@@ -78,16 +78,15 @@ class TeamControllerTest extends ControllerBaseTest
$this->assertAccessIsGranted($client, '/admin/teams/create');
$form = $client->getCrawler()->filter('form[name=team_edit_form]')->form();
- $editForm = $client->getCrawler()->filter('form[name=team_edit_form]')->form();
- $this->assertEquals('', $editForm->get('team_edit_form[name]')->getValue());
- $this->assertEquals('5', $editForm->get('team_edit_form[teamlead]')->getValue());
+ $this->assertEquals('', $form->get('team_edit_form[name]')->getValue());
+ $this->assertEquals('5', $form->get('team_edit_form[teamlead]')->getValue());
$client->submit($form, [
'team_edit_form' => [
- 'name' => 'Test Team',
+ 'name' => 'Test Team' . uniqid(),
]
]);
- $this->assertIsRedirect($client, $this->createUrl('/admin/teams/2/edit'));
+ $this->assertIsRedirect($client, '/edit');
$client->followRedirect();
$this->assertHasFlashSuccess($client);
$this->assertHasCustomerAndProjectPermissionBoxes($client);
@@ -210,7 +209,7 @@ class TeamControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$this->request($client, '/admin/teams/1/duplicate');
- $this->assertIsRedirect($client, $this->createUrl('/admin/teams/2/edit'));
+ $this->assertIsRedirect($client, '/edit');
$client->followRedirect();
$node = $client->getCrawler()->filter('#team_edit_form_name');
self::assertEquals(1, $node->count());
diff --git a/tests/Controller/TimesheetControllerTest.php b/tests/Controller/TimesheetControllerTest.php
index 20beacd8..8de64993 100644
--- a/tests/Controller/TimesheetControllerTest.php
+++ b/tests/Controller/TimesheetControllerTest.php
@@ -181,7 +181,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertNull($timesheet->getEnd());
$this->assertEquals('Testing is fun!', $timesheet->getDescription());
@@ -218,7 +218,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals($expectedDuration, $timesheet->getDuration());
@@ -293,7 +293,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals(50, $timesheet->getRate());
@@ -327,7 +327,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals(50, $timesheet->getRate());
@@ -428,7 +428,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
$this->assertEquals(800, $timesheet->getRate());
@@ -450,9 +450,10 @@ class TimesheetControllerTest extends ControllerBaseTest
$fixture->setAmount(10);
$fixture->setUser($this->getUserByRole(User::ROLE_USER));
$fixture->setStartDate('2017-05-01');
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ $id = $timesheets[0]->getId();
- $this->request($client, '/timesheet/1/edit');
+ $this->request($client, '/timesheet/' . $id . '/edit');
$response = $client->getResponse();
$this->assertTrue($response->isSuccessful());
@@ -478,7 +479,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertEquals('foo-bar', $timesheet->getDescription());
}
diff --git a/tests/Controller/TimesheetTeamControllerTest.php b/tests/Controller/TimesheetTeamControllerTest.php
index fbaa37ca..fa90d41e 100644
--- a/tests/Controller/TimesheetTeamControllerTest.php
+++ b/tests/Controller/TimesheetTeamControllerTest.php
@@ -192,7 +192,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->findAll()[0];
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
$this->assertNull($timesheet->getEnd());
$this->assertEquals('Testing is fun!', $timesheet->getDescription());
@@ -271,9 +271,10 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$fixture->setAmount(10);
$fixture->setUser($user);
$fixture->setStartDate('2017-05-01');
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
+ $id = $timesheets[0]->getId();
- $this->request($client, '/team/timesheet/1/edit');
+ $this->request($client, '/team/timesheet/' . $id . '/edit');
$response = $client->getResponse();
$this->assertTrue($response->isSuccessful());
@@ -300,7 +301,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$em = $this->getEntityManager();
/** @var Timesheet $timesheet */
- $timesheet = $em->getRepository(Timesheet::class)->find(1);
+ $timesheet = $em->getRepository(Timesheet::class)->find($id);
$this->assertEquals('foo-bar', $timesheet->getDescription());
$this->assertEquals($teamlead->getId(), $timesheet->getUser()->getId());
}
diff --git a/tests/Controller/UserControllerTest.php b/tests/Controller/UserControllerTest.php
index d1d78037..a5050ecf 100644
--- a/tests/Controller/UserControllerTest.php
+++ b/tests/Controller/UserControllerTest.php
@@ -98,7 +98,7 @@ class UserControllerTest extends ControllerBaseTest
public function testCreateAction()
{
- $username = '亚历山德拉';
+ $username = '亚历山德拉' . uniqid();
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/user/create');
$form = $client->getCrawler()->filter('form[name=user_create]')->form();
@@ -188,10 +188,9 @@ class UserControllerTest extends ControllerBaseTest
$client->followRedirect();
$this->assertHasFlashDeleteSuccess($client);
- // SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
- // $em->clear();
- // $timesheets = $em->getRepository(Timesheet::class)->count([]);
- // $this->assertEquals(0, $timesheets);
+ $em->clear();
+ $timesheets = $em->getRepository(Timesheet::class)->count([]);
+ $this->assertEquals(0, $timesheets);
$this->request($client, '/admin/user/' . $user->getId() . '/edit');
$this->assertFalse($client->getResponse()->isSuccessful());
diff --git a/tests/DataFixtures/ActivityFixtures.php b/tests/DataFixtures/ActivityFixtures.php
index 8d3dc466..a47149c8 100644
--- a/tests/DataFixtures/ActivityFixtures.php
+++ b/tests/DataFixtures/ActivityFixtures.php
@@ -11,14 +11,13 @@ namespace App\Tests\DataFixtures;
use App\Entity\Activity;
use App\Entity\Project;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in during controller tests.
*/
-final class ActivityFixtures extends Fixture
+final class ActivityFixtures implements TestFixture
{
/**
* @var int
@@ -95,10 +94,13 @@ final class ActivityFixtures extends Fixture
}
/**
- * {@inheritdoc}
+ * @param ObjectManager $manager
+ * @return Activity[]
*/
- public function load(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
+
$projects = $this->projects;
if (empty($projects)) {
$projects = $this->getAllProjects($manager);
@@ -126,16 +128,20 @@ final class ActivityFixtures extends Fixture
\call_user_func($this->callback, $activity);
}
$manager->persist($activity);
+
+ $created[] = $activity;
}
$manager->flush();
+
+ return $created;
}
/**
* @param ObjectManager $manager
* @return array
*/
- protected function getAllProjects(ObjectManager $manager): array
+ private function getAllProjects(ObjectManager $manager): array
{
$all = [];
/** @var Project[] $entries */
diff --git a/tests/DataFixtures/CustomerFixtures.php b/tests/DataFixtures/CustomerFixtures.php
index 467b60b9..2e4d7291 100644
--- a/tests/DataFixtures/CustomerFixtures.php
+++ b/tests/DataFixtures/CustomerFixtures.php
@@ -10,14 +10,13 @@
namespace App\Tests\DataFixtures;
use App\Entity\Customer;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in during controller tests.
*/
-final class CustomerFixtures extends Fixture
+final class CustomerFixtures implements TestFixture
{
/**
* @var int
@@ -65,10 +64,13 @@ final class CustomerFixtures extends Fixture
}
/**
- * {@inheritdoc}
+ * @param ObjectManager $manager
+ * @return Customer[]
*/
- public function load(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
+
$faker = Factory::create();
for ($i = 0; $i < $this->amount; $i++) {
@@ -92,8 +94,11 @@ final class CustomerFixtures extends Fixture
\call_user_func($this->callback, $customer);
}
$manager->persist($customer);
+ $created[] = $customer;
}
$manager->flush();
+
+ return $created;
}
}
diff --git a/tests/DataFixtures/InvoiceFixtures.php b/tests/DataFixtures/InvoiceTemplateFixtures.php
similarity index 83%
rename from tests/DataFixtures/InvoiceFixtures.php
rename to tests/DataFixtures/InvoiceTemplateFixtures.php
index 9abfe0f3..471a759b 100644
--- a/tests/DataFixtures/InvoiceFixtures.php
+++ b/tests/DataFixtures/InvoiceTemplateFixtures.php
@@ -10,28 +10,22 @@
namespace App\Tests\DataFixtures;
use App\Entity\InvoiceTemplate;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in during controller tests.
*/
-class InvoiceFixtures extends Fixture
+class InvoiceTemplateFixtures implements TestFixture
{
- /**
- * {@inheritdoc}
- */
- public function load(ObjectManager $manager)
- {
- $this->loadInvoiceTemplates($manager);
- }
-
/**
* @param ObjectManager $manager
+ * @return InvoiceTemplate[]
*/
- private function loadInvoiceTemplates(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
+
$faker = Factory::create();
$template = new InvoiceTemplate();
@@ -58,5 +52,9 @@ class InvoiceFixtures extends Fixture
$manager->persist($template);
$manager->flush();
+
+ $created[] = $template;
+
+ return $created;
}
}
diff --git a/tests/DataFixtures/ProjectFixtures.php b/tests/DataFixtures/ProjectFixtures.php
index 0acde063..abb0bdf6 100644
--- a/tests/DataFixtures/ProjectFixtures.php
+++ b/tests/DataFixtures/ProjectFixtures.php
@@ -11,14 +11,13 @@ namespace App\Tests\DataFixtures;
use App\Entity\Customer;
use App\Entity\Project;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in during controller tests.
*/
-final class ProjectFixtures extends Fixture
+final class ProjectFixtures implements TestFixture
{
/**
* @var int
@@ -81,10 +80,12 @@ final class ProjectFixtures extends Fixture
}
/**
- * {@inheritdoc}
+ * @param ObjectManager $manager
+ * @return Project[]
*/
- public function load(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
$customers = $this->customers;
if (empty($customers)) {
$customers = $this->getAllCustomers($manager);
@@ -109,16 +110,19 @@ final class ProjectFixtures extends Fixture
\call_user_func($this->callback, $project);
}
$manager->persist($project);
+ $created[] = $project;
}
$manager->flush();
+
+ return $created;
}
/**
* @param ObjectManager $manager
* @return array
*/
- protected function getAllCustomers(ObjectManager $manager): array
+ private function getAllCustomers(ObjectManager $manager): array
{
$all = [];
/** @var Customer[] $entries */
diff --git a/tests/DataFixtures/TagFixtures.php b/tests/DataFixtures/TagFixtures.php
index 4389dbf6..83e519ab 100644
--- a/tests/DataFixtures/TagFixtures.php
+++ b/tests/DataFixtures/TagFixtures.php
@@ -10,13 +10,12 @@
namespace App\Tests\DataFixtures;
use App\Entity\Tag;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
/**
* Defines the sample data to load in during controller tests.
*/
-final class TagFixtures extends Fixture
+final class TagFixtures implements TestFixture
{
/**
* @var string[]
@@ -60,10 +59,13 @@ final class TagFixtures extends Fixture
}
/**
- * {@inheritdoc}
+ * @param ObjectManager $manager
+ * @return Tag[]
*/
- public function load(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
+
foreach ($this->getTagArray() as $tagName) {
$tag = $this->createTagEntry($tagName);
@@ -71,8 +73,11 @@ final class TagFixtures extends Fixture
\call_user_func($this->callback, $tag);
}
$manager->persist($tag);
+ $created[] = $tag;
}
$manager->flush();
+
+ return $created;
}
private function createTagEntry(string $tagName): Tag
diff --git a/tests/DataFixtures/TeamFixtures.php b/tests/DataFixtures/TeamFixtures.php
index baa9aa4a..c7c665cd 100644
--- a/tests/DataFixtures/TeamFixtures.php
+++ b/tests/DataFixtures/TeamFixtures.php
@@ -12,14 +12,13 @@ namespace App\Tests\DataFixtures;
use App\Entity\Customer;
use App\Entity\Team;
use App\Entity\User;
-use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in during controller tests.
*/
-final class TeamFixtures extends Fixture
+final class TeamFixtures implements TestFixture
{
/**
* @var int
@@ -89,10 +88,13 @@ final class TeamFixtures extends Fixture
}
/**
- * {@inheritdoc}
+ * @param ObjectManager $manager
+ * @return Team[]
*/
- public function load(ObjectManager $manager)
+ public function load(ObjectManager $manager): array
{
+ $created = [];
+
$faker = Factory::create();
$user = $this->getAllUsers($manager);
$customer = $this->getAllCustomers($manager);
@@ -131,9 +133,12 @@ final class TeamFixtures extends Fixture
\call_user_func($this->callback, $team);
}
$manager->persist($team);
+ $created[] = $team;
}
$manager->flush();
+
+ return $created;
}
/**
diff --git a/tests/DataFixtures/TestFixture.php b/tests/DataFixtures/TestFixture.php
new file mode 100644
index 00000000..f61dd197
--- /dev/null
+++ b/tests/DataFixtures/TestFixture.php
@@ -0,0 +1,23 @@
+activities;
if (empty($activities)) {
$activities = $this->getAllActivities($manager);
@@ -222,6 +224,12 @@ final class TimesheetFixtures extends Fixture
$faker = Factory::create();
$user = $this->user;
+ $tags = $this->getTagObjectList();
+ foreach ($tags as $tag) {
+ $manager->persist($tag);
+ }
+ $manager->flush();
+
for ($i = 0; $i < $this->amount; $i++) {
$description = $faker->text;
if ($this->allowEmptyDescriptions) {
@@ -239,8 +247,6 @@ final class TimesheetFixtures extends Fixture
$project = $projects[array_rand($projects)];
}
- $tags = $this->getTagObjectList($i);
-
$timesheet = $this->createTimesheetEntry(
$user,
$activity,
@@ -254,6 +260,7 @@ final class TimesheetFixtures extends Fixture
\call_user_func($this->callback, $timesheet);
}
$manager->persist($timesheet);
+ $created[] = $timesheet;
}
for ($i = 0; $i < $this->running; $i++) {
@@ -264,8 +271,6 @@ final class TimesheetFixtures extends Fixture
$project = $projects[array_rand($projects)];
}
- $tags = $this->getTagObjectList($i);
-
$timesheet = $this->createTimesheetEntry(
$user,
$activity,
@@ -280,24 +285,32 @@ final class TimesheetFixtures extends Fixture
\call_user_func($this->callback, $timesheet);
}
$manager->persist($timesheet);
+ $created[] = $timesheet;
}
$manager->flush();
+
+ return $created;
}
- protected function getTagObjectList(int $cnt): array
+ private function getTagObjectList(): array
{
if (true === $this->useTags) {
- $tagObject = new Tag();
- $tagObject->setName($this->tags[($cnt % \count($this->tags))]);
+ $all = [];
+ foreach ($this->tags as $tagName) {
+ $tagObject = new Tag();
+ $tagObject->setName($tagName);
- return [$tagObject];
+ $all[] = $tagObject;
+ }
+
+ return $all;
}
return [];
}
- protected function getDateTime(int $i): \DateTime
+ private function getDateTime(int $i): \DateTime
{
$start = \DateTime::createFromFormat('Y-m-d', $this->startDate);
$start->modify("+ $i days");
@@ -310,7 +323,7 @@ final class TimesheetFixtures extends Fixture
* @param ObjectManager $manager
* @return array
*/
- protected function getAllActivities(ObjectManager $manager): array
+ private function getAllActivities(ObjectManager $manager): array
{
$all = [];
/** @var Activity[] $entries */
@@ -326,7 +339,7 @@ final class TimesheetFixtures extends Fixture
* @param ObjectManager $manager
* @return array
*/
- protected function getAllProjects(ObjectManager $manager): array
+ private function getAllProjects(ObjectManager $manager): array
{
$all = [];
/** @var Project[] $entries */
diff --git a/tests/Doctrine/SqliteSessionInitSubscriberTest.php b/tests/Doctrine/SqliteSessionInitSubscriberTest.php
deleted file mode 100644
index 6bbc01b5..00000000
--- a/tests/Doctrine/SqliteSessionInitSubscriberTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
-getSubscribedEvents();
- $this->assertTrue(\in_array(Events::postConnect, $events));
- }
-
- public function testPostConnectWithSqlite()
- {
- $sut = new SqliteSessionInitSubscriber();
-
- $platformMock = $this->getMockBuilder(SqlitePlatform::class)
- ->onlyMethods(['getName'])
- ->disableOriginalConstructor()
- ->getMock();
-
- $platformMock->expects($this->once())->method('getName')->willReturn('sqlite');
-
- $connectionMock = $this->createMock(Connection::class);
-
- $connectionMock->expects($this->once())->method('getDatabasePlatform')->willReturn($platformMock);
- $connectionMock->expects($this->once())->method('exec')->with('PRAGMA foreign_keys = ON;');
-
- $args = new ConnectionEventArgs($connectionMock);
- $sut->postConnect($args);
- }
-
- public function testPostConnectWithMysql()
- {
- $sut = new SqliteSessionInitSubscriber();
-
- $platformMock = $this->getMockBuilder(MySqlPlatform::class)
- ->onlyMethods(['getName'])
- ->disableOriginalConstructor()
- ->getMock();
-
- $platformMock->expects($this->once())->method('getName')->willReturn('mysql');
-
- $connectionMock = $this->createMock(Connection::class);
-
- $connectionMock->expects($this->once())->method('getDatabasePlatform')->willReturn($platformMock);
- $connectionMock->expects($this->never())->method('exec')->with('PRAGMA foreign_keys = ON;');
-
- $args = new ConnectionEventArgs($connectionMock);
- $sut->postConnect($args);
- }
-}
diff --git a/tests/Doctrine/UTCDateTimeTypeTest.php b/tests/Doctrine/UTCDateTimeTypeTest.php
index 9d96d234..a65210d7 100644
--- a/tests/Doctrine/UTCDateTimeTypeTest.php
+++ b/tests/Doctrine/UTCDateTimeTypeTest.php
@@ -12,9 +12,9 @@ namespace App\Tests\Doctrine;
use App\Doctrine\UTCDateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\Types\Types;
use PHPUnit\Framework\TestCase;
/**
@@ -24,9 +24,9 @@ class UTCDateTimeTypeTest extends TestCase
{
public function testGetUtc()
{
- Type::overrideType(Type::DATETIME, UTCDateTimeType::class);
+ Type::overrideType(Types::DATETIME_MUTABLE, UTCDateTimeType::class);
/** @var UTCDateTimeType $type */
- $type = Type::getType(Type::DATETIME);
+ $type = Type::getType(Types::DATETIME_MUTABLE);
$this->assertInstanceOf(UTCDateTimeType::class, $type);
$utc = $type::getUtc();
@@ -39,9 +39,9 @@ class UTCDateTimeTypeTest extends TestCase
*/
public function testConvertToDatabaseValue(AbstractPlatform $platform)
{
- Type::overrideType(Type::DATETIME, UTCDateTimeType::class);
+ Type::overrideType(Types::DATETIME_MUTABLE, UTCDateTimeType::class);
/** @var UTCDateTimeType $type */
- $type = Type::getType(Type::DATETIME);
+ $type = Type::getType(Types::DATETIME_MUTABLE);
$result = $type->convertToDatabaseValue(null, $platform);
$this->assertNull($result);
@@ -67,9 +67,9 @@ class UTCDateTimeTypeTest extends TestCase
*/
public function testConvertToPHPValue(AbstractPlatform $platform)
{
- Type::overrideType(Type::DATETIME, UTCDateTimeType::class);
+ Type::overrideType(Types::DATETIME_MUTABLE, UTCDateTimeType::class);
/** @var UTCDateTimeType $type */
- $type = Type::getType(Type::DATETIME);
+ $type = Type::getType(Types::DATETIME_MUTABLE);
$result = $type->convertToPHPValue(null, $platform);
$this->assertNull($result);
@@ -89,9 +89,9 @@ class UTCDateTimeTypeTest extends TestCase
{
$this->expectException(ConversionException::class);
- Type::overrideType(Type::DATETIME, UTCDateTimeType::class);
+ Type::overrideType(Types::DATETIME_MUTABLE, UTCDateTimeType::class);
/** @var UTCDateTimeType $type */
- $type = Type::getType(Type::DATETIME);
+ $type = Type::getType(Types::DATETIME_MUTABLE);
$type->convertToPHPValue('201xx01-17 13:30:00', $platform);
}
@@ -101,9 +101,9 @@ class UTCDateTimeTypeTest extends TestCase
*/
public function testRequiresSQLCommentHint(AbstractPlatform $platform)
{
- Type::overrideType(Type::DATETIME, UTCDateTimeType::class);
+ Type::overrideType(Types::DATETIME_MUTABLE, UTCDateTimeType::class);
/** @var UTCDateTimeType $type */
- $type = Type::getType(Type::DATETIME);
+ $type = Type::getType(Types::DATETIME_MUTABLE);
self::assertTrue($type->requiresSQLCommentHint($platform));
}
@@ -111,7 +111,6 @@ class UTCDateTimeTypeTest extends TestCase
{
return [
[new MySqlPlatform()],
- [new SqlitePlatform()],
];
}
}
diff --git a/tests/KernelTest.php b/tests/KernelTest.php
new file mode 100644
index 00000000..33f0f6b0
--- /dev/null
+++ b/tests/KernelTest.php
@@ -0,0 +1,26 @@
+assertEquals($sut->getCacheDir(), realpath(__DIR__ . '/../var/cache/test'));
+ $this->assertEquals($sut->getLogDir(), realpath(__DIR__ . '/../var/log'));
+ }
+}
diff --git a/tests/KernelTestTrait.php b/tests/KernelTestTrait.php
index 74ad05e2..064d164b 100644
--- a/tests/KernelTestTrait.php
+++ b/tests/KernelTestTrait.php
@@ -11,9 +11,7 @@ namespace App\Tests;
use App\DataFixtures\UserFixtures;
use App\Entity\User;
-use Doctrine\Bundle\FixturesBundle\Fixture;
-use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
-use Doctrine\Common\DataFixtures\Loader;
+use App\Tests\DataFixtures\TestFixture;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
@@ -31,15 +29,9 @@ trait KernelTestTrait
return $this::$container->get('doctrine.orm.entity_manager');
}
- protected function importFixture(Fixture $fixture)
+ protected function importFixture(TestFixture $fixture): array
{
- $em = $this::$container->get('doctrine.orm.entity_manager');
-
- $loader = new Loader();
- $loader->addFixture($fixture);
-
- $executor = new ORMExecutor($em, null);
- $executor->execute($loader->getFixtures(), true);
+ return $fixture->load($this->getEntityManager());
}
protected function getUserByName(string $username): ?User
diff --git a/tests/Repository/TagRepositoryTest.php b/tests/Repository/TagRepositoryTest.php
index 20a1cfd9..f8b67da4 100644
--- a/tests/Repository/TagRepositoryTest.php
+++ b/tests/Repository/TagRepositoryTest.php
@@ -38,13 +38,6 @@ class TagRepositoryTest extends AbstractRepositoryTest
$this->assertIsArray($result);
$this->assertNotEmpty($result);
$this->assertEquals(7, \count($result));
- $this->assertEquals(1, $result[0]);
- $this->assertEquals(3, $result[1]);
- $this->assertEquals(4, $result[2]);
- $this->assertEquals(5, $result[3]);
- $this->assertEquals(6, $result[4]);
- $this->assertEquals(7, $result[5]);
- $this->assertEquals(11, $result[6]);
}
public function testFindNoIds()
diff --git a/tests/Repository/TimesheetRepositoryTest.php b/tests/Repository/TimesheetRepositoryTest.php
index 5e96590f..685d238c 100644
--- a/tests/Repository/TimesheetRepositoryTest.php
+++ b/tests/Repository/TimesheetRepositoryTest.php
@@ -88,9 +88,9 @@ class TimesheetRepositoryTest extends AbstractRepositoryTest
$fixture = new TimesheetFixtures();
$fixture->setUser($user);
$fixture->setAmountRunning(1);
- $this->importFixture($fixture);
+ $timesheets = $this->importFixture($fixture);
- $timesheet = $repository->find(1);
+ $timesheet = $timesheets[0];
$this->assertInstanceOf(Timesheet::class, $timesheet);
$this->assertNull($timesheet->getEnd());
@@ -123,7 +123,7 @@ class TimesheetRepositoryTest extends AbstractRepositoryTest
$this->assertNull($timesheet->getId());
$repository->save($timesheet);
- $this->assertEquals(1, $timesheet->getId());
+ $this->assertNotNull($timesheet->getId());
}
public function testSaveWithTags()
@@ -156,11 +156,11 @@ class TimesheetRepositoryTest extends AbstractRepositoryTest
$this->assertNull($timesheet->getId());
$repository->save($timesheet);
- $this->assertEquals(1, $timesheet->getId());
+ $this->assertNotNull($timesheet->getId());
$this->assertEquals(2, $timesheet->getTags()->count());
$this->assertEquals('Travel', $timesheet->getTags()->get(0)->getName());
- $this->assertEquals(1, $timesheet->getTags()->get(0)->getId());
+ $this->assertNotNull($timesheet->getTags()->get(0)->getId());
$this->assertEquals('Picture', $timesheet->getTags()->get(1)->getName());
- $this->assertEquals(2, $timesheet->getTags()->get(1)->getId());
+ $this->assertNotNull($timesheet->getTags()->get(1)->getId());
}
}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 00000000..00f851d5
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,24 @@
+ |