├── .docker
├── nginx
│ └── nginx.conf
└── php
│ └── php.ini
├── .editorconfig
├── .github
├── CODEOWNERS
├── dependabot.yml
└── workflows
│ └── build.yml
├── .gitignore
├── CHANGELOG-1.0.md
├── Makefile
├── README.md
├── behat.yml.dist
├── bin
└── create_node_symlink.php
├── composer.json
├── config
├── admin_routing.yaml
├── config.yaml
├── doctrine
│ ├── AttachedFile.orm.xml
│ ├── Comment.orm.xml
│ └── Email.orm.xml
├── routing
│ ├── admin
│ │ └── order_comments.yaml
│ └── shop
│ │ └── order_comments.yaml
├── services.xml
└── shop_routing.yaml
├── docker-compose.yml
├── ecs.php
├── etc
└── build
│ └── .gitignore
├── features
├── attaching_file_to_comment.feature
├── commenting_an_order_by_a_customer.feature
├── commenting_an_order_by_an_administrator.feature
├── sorting_administrator_comments.feature
└── sorting_customer_comments.feature
├── node_modules
├── phpspec.yml.dist
├── phpstan.neon
├── phpunit.xml.dist
├── psalm.xml
├── src
├── Application
│ ├── Command
│ │ └── CommentOrder.php
│ ├── CommandHandler
│ │ └── CommentOrderHandler.php
│ └── Process
│ │ ├── SendUnreadCommentEmailNotification.php
│ │ ├── SendUnreadCommentEmailNotificationInterface.php
│ │ └── Sender
│ │ ├── ChanneledEmailSender.php
│ │ └── ChanneledEmailSenderInterface.php
├── Brille24SyliusOrderCommentsPlugin.php
├── DependencyInjection
│ ├── Brille24SyliusOrderCommentsExtension.php
│ └── Configuration.php
├── Domain
│ ├── Event
│ │ ├── FileAttached.php
│ │ └── OrderCommented.php
│ └── Model
│ │ ├── AttachedFile.php
│ │ ├── Comment.php
│ │ └── Email.php
└── Infrastructure
│ ├── Controller
│ └── Ui
│ │ ├── OrderCommentAction.php
│ │ └── RenderOrderCommentAction.php
│ ├── Form
│ ├── DTO
│ │ └── OrderComment.php
│ └── Type
│ │ └── OrderCommentType.php
│ └── Migrations
│ └── Version20230317140309.php
├── templates
├── Email
│ └── unread_comment.html.twig
├── _form.html.twig
├── index.html.twig
└── injected
│ ├── admin_order_comments.html.twig
│ └── shop_order_comments.html.twig
├── tests
├── Application
│ ├── .env
│ ├── .env.test
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── Kernel.php
│ ├── assets
│ │ ├── admin
│ │ │ └── entry.js
│ │ └── shop
│ │ │ └── entry.js
│ ├── bin
│ │ └── console
│ ├── composer.json
│ ├── config
│ │ ├── api_platform
│ │ │ └── .gitignore
│ │ ├── bootstrap.php
│ │ ├── bundles.php
│ │ ├── jwt
│ │ │ ├── private.pem
│ │ │ └── public.pem
│ │ ├── packages
│ │ │ ├── _sylius.yaml
│ │ │ ├── api_platform.yaml
│ │ │ ├── assets.yaml
│ │ │ ├── dev
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── jms_serializer.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── routing.yaml
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── doctrine.yaml
│ │ │ ├── doctrine_migrations.yaml
│ │ │ ├── fos_rest.yaml
│ │ │ ├── framework.yaml
│ │ │ ├── jms_serializer.yaml
│ │ │ ├── lexik_jwt_authentication.yaml
│ │ │ ├── liip_imagine.yaml
│ │ │ ├── mailer.yaml
│ │ │ ├── prod
│ │ │ │ ├── doctrine.yaml
│ │ │ │ ├── jms_serializer.yaml
│ │ │ │ └── monolog.yaml
│ │ │ ├── routing.yaml
│ │ │ ├── security.yaml
│ │ │ ├── staging
│ │ │ │ └── monolog.yaml
│ │ │ ├── stof_doctrine_extensions.yaml
│ │ │ ├── test
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── mailer.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── security.yaml
│ │ │ │ ├── sylius_theme.yaml
│ │ │ │ ├── sylius_uploader.yaml
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── test_cached
│ │ │ │ ├── doctrine.yaml
│ │ │ │ ├── fos_rest.yaml
│ │ │ │ ├── framework.yaml
│ │ │ │ ├── mailer.yaml
│ │ │ │ ├── monolog.yaml
│ │ │ │ ├── security.yaml
│ │ │ │ ├── sylius_channel.yaml
│ │ │ │ ├── sylius_theme.yaml
│ │ │ │ ├── sylius_uploader.yaml
│ │ │ │ └── twig.yaml
│ │ │ ├── translation.yaml
│ │ │ ├── twig.yaml
│ │ │ ├── validator.yaml
│ │ │ └── webpack_encore.yaml
│ │ ├── routes.yaml
│ │ ├── routes
│ │ │ ├── dev
│ │ │ │ └── web_profiler.yaml
│ │ │ ├── liip_imagine.yaml
│ │ │ ├── sylius_admin.yaml
│ │ │ ├── sylius_api.yaml
│ │ │ ├── sylius_shop.yaml
│ │ │ ├── test
│ │ │ │ ├── routing.yaml
│ │ │ │ └── sylius_test_plugin.yaml
│ │ │ └── test_cached
│ │ │ │ ├── routing.yaml
│ │ │ │ └── sylius_test_plugin.yaml
│ │ ├── secrets
│ │ │ ├── dev
│ │ │ │ └── .gitignore
│ │ │ ├── prod
│ │ │ │ └── .gitignore
│ │ │ ├── test
│ │ │ │ └── .gitignore
│ │ │ └── test_cached
│ │ │ │ └── .gitignore
│ │ ├── serialization
│ │ │ └── .gitignore
│ │ ├── services.yaml
│ │ ├── services_test.yaml
│ │ └── services_test_cached.yaml
│ ├── package.json
│ ├── public
│ │ ├── .htaccess
│ │ ├── favicon.ico
│ │ ├── index.php
│ │ └── robots.txt
│ ├── templates
│ │ └── .gitignore
│ ├── translations
│ │ └── .gitignore
│ └── webpack.config.js
├── Behat
│ ├── Context
│ │ ├── Application
│ │ │ ├── AdministratorOrderCommentsContext.php
│ │ │ └── CustomerOrderCommentsContext.php
│ │ ├── Common
│ │ │ └── ChannelContext.php
│ │ ├── Domain
│ │ │ ├── AdministratorOrderCommentsContext.php
│ │ │ └── CustomerOrderCommentsContext.php
│ │ └── UI
│ │ │ ├── AdministratorOrderCommentsContext.php
│ │ │ └── CustomerOrderCommentsContext.php
│ ├── Element
│ │ ├── Element.php
│ │ ├── OrderCommentFormElement.php
│ │ ├── OrderCommentFormElementInterface.php
│ │ ├── OrderCommentsElement.php
│ │ └── OrderCommentsElementInterface.php
│ └── Resources
│ │ ├── services.xml
│ │ ├── suites.yml
│ │ └── suites
│ │ ├── application
│ │ ├── administrator_order_comments.yml
│ │ └── customer_order_comments.yml
│ │ ├── domain
│ │ ├── administrator_order_comments.yml
│ │ └── customer_order_comments.yml
│ │ └── ui
│ │ ├── administrator_order_comments.yml
│ │ └── customer_order_comments.yml
└── Comments
│ ├── Application
│ ├── Command
│ │ └── CommentOrderTest.php
│ └── Process
│ │ └── ChanneledEmailSenderTest.php
│ ├── Domain
│ ├── Event
│ │ ├── FileAttachedTest.php
│ │ └── OrderCommentedTest.php
│ └── Model
│ │ ├── AttachedFileTest.php
│ │ ├── CommentTest.php
│ │ └── EmailTest.php
│ └── Infrastructure
│ └── Form
│ └── Type
│ ├── file.pdf
│ └── text.txt
└── translations
├── messages.de.yml
└── messages.en.yml
/.docker/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | user www-data;
2 | worker_processes auto;
3 | daemon off;
4 | pid /run/nginx.pid;
5 |
6 | include /etc/nginx/modules-enabled/*.conf;
7 |
8 | events {
9 | worker_connections 1024;
10 | }
11 |
12 | http {
13 | include /etc/nginx/mime.types;
14 | default_type application/octet-stream;
15 |
16 | server_tokens off;
17 |
18 | client_max_body_size 64m;
19 | sendfile on;
20 | tcp_nodelay on;
21 | tcp_nopush on;
22 |
23 | gzip_vary on;
24 |
25 | access_log /var/log/nginx/access.log;
26 | error_log /var/log/nginx/error.log;
27 |
28 | server {
29 | listen 80;
30 |
31 | root /app/tests/Application/public;
32 | index index.php;
33 |
34 | location / {
35 | try_files $uri /index.php$is_args$args;
36 | }
37 |
38 | location ~ \.php$ {
39 | include fastcgi_params;
40 |
41 | fastcgi_pass unix:/var/run/php8-fpm.sock;
42 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
43 |
44 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
45 | fastcgi_param DOCUMENT_ROOT $realpath_root;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/.docker/php/php.ini:
--------------------------------------------------------------------------------
1 | [PHP]
2 | memory_limit=512M
3 |
4 | [date]
5 | date.timezone=${PHP_DATE_TIMEZONE}
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 |
2 | # EditorConfig helps developers define and maintain consistent
3 | # coding styles between different editors and IDEs
4 | # editorconfig.org
5 |
6 | root = true
7 |
8 | [*]
9 | # Change these settings to your own preference
10 | indent_style = space
11 | indent_size = 4
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.feature]
20 | indent_style = space
21 | indent_size = 4
22 |
23 | [*.js]
24 | indent_style = space
25 | indent_size = 2
26 |
27 | [*.json]
28 | indent_style = space
29 | indent_size = 2
30 |
31 | [*.md]
32 | indent_style = space
33 | indent_size = 4
34 | trim_trailing_whitespace = false
35 |
36 | [*.neon]
37 | indent_style = space
38 | indent_size = 4
39 |
40 | [*.php]
41 | indent_style = space
42 | indent_size = 4
43 |
44 | [*.sh]
45 | indent_style = space
46 | indent_size = 4
47 |
48 | [*.{yaml,yml}]
49 | indent_style = space
50 | indent_size = 4
51 | trim_trailing_whitespace = false
52 |
53 | [.babelrc]
54 | indent_style = space
55 | indent_size = 2
56 |
57 | [.gitmodules]
58 | indent_style = tab
59 | indent_size = 4
60 |
61 | [.php_cs{,.dist}]
62 | indent_style = space
63 | indent_size = 4
64 |
65 | [composer.json]
66 | indent_style = space
67 | indent_size = 4
68 |
69 | [package.json]
70 | indent_style = space
71 | indent_size = 2
72 |
73 | [phpspec.yml{,.dist}]
74 | indent_style = space
75 | indent_size = 4
76 |
77 | [phpstan.neon]
78 | indent_style = space
79 | indent_size = 4
80 |
81 | [phpunit.xml{,.dist}]
82 | indent_style = space
83 | indent_size = 4
84 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @Sylius/core-team
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: composer
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "10:00"
8 | open-pull-requests-limit: 10
9 | ignore:
10 | - dependency-name: vimeo/psalm
11 | versions:
12 | - 4.5.0
13 | - 4.5.1
14 | - 4.5.2
15 | - 4.6.0
16 | - 4.6.1
17 | - 4.6.2
18 | - 4.6.3
19 | - 4.7.0
20 | - 4.7.1
21 | - dependency-name: phpstan/phpstan
22 | versions:
23 | - 0.12.70
24 | - 0.12.71
25 | - 0.12.73
26 | - 0.12.75
27 | - 0.12.76
28 | - 0.12.77
29 | - 0.12.78
30 | - 0.12.80
31 | - 0.12.81
32 | - 0.12.83
33 | - 0.12.84
34 | - dependency-name: sylius-labs/coding-standard
35 | versions:
36 | - 4.0.2
37 | - dependency-name: phpstan/phpstan-doctrine
38 | versions:
39 | - 0.12.32
40 | - dependency-name: phpstan/phpstan-webmozart-assert
41 | versions:
42 | - 0.12.10
43 | - 0.12.11
44 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches-ignore:
6 | - 'dependabot/**'
7 | pull_request:
8 | branches:
9 | - master
10 | release:
11 | types: [created]
12 | schedule:
13 | -
14 | cron: "0 1 * * 6" # Run at 1am every Saturday
15 | workflow_dispatch: ~
16 |
17 | jobs:
18 | tests:
19 | runs-on: ubuntu-latest
20 |
21 | name: "Sylius ${{ matrix.sylius }}, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}"
22 |
23 | strategy:
24 | fail-fast: false
25 | matrix:
26 | php: ["8.0", "8.1"]
27 | symfony: ["5.4.*", "^6.0"]
28 | sylius: ["^1.11"]
29 | node: ["14.x", "16.x", "18.x"]
30 | mysql: ["5.7", "8.0"]
31 |
32 | env:
33 | APP_ENV: test
34 | DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}"
35 |
36 | steps:
37 | -
38 | uses: actions/checkout@v2
39 |
40 | -
41 | name: Setup PHP
42 | uses: shivammathur/setup-php@v2
43 | with:
44 | php-version: "${{ matrix.php }}"
45 | extensions: intl
46 | tools: flex,symfony
47 | coverage: none
48 |
49 | -
50 | name: Setup Node
51 | uses: actions/setup-node@v1
52 | with:
53 | node-version: "${{ matrix.node }}"
54 |
55 | -
56 | name: Shutdown default MySQL
57 | run: sudo service mysql stop
58 |
59 | -
60 | name: Setup MySQL
61 | uses: mirromutth/mysql-action@v1.1
62 | with:
63 | mysql version: "${{ matrix.mysql }}"
64 | mysql root password: "root"
65 |
66 | -
67 | name: Output PHP version for Symfony CLI
68 | run: php -v | head -n 1 | awk '{ print $2 }' > .php-version
69 |
70 | -
71 | name: Install certificates
72 | run: symfony server:ca:install
73 |
74 | -
75 | name: Run Chrome Headless
76 | run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 &
77 |
78 | -
79 | name: Run webserver
80 | run: (cd tests/Application && symfony server:start --port=8080 --dir=public --daemon)
81 |
82 | -
83 | name: Get Composer cache directory
84 | id: composer-cache
85 | run: echo "::set-output name=dir::$(composer config cache-files-dir)"
86 |
87 | -
88 | name: Cache Composer
89 | uses: actions/cache@v2
90 | with:
91 | path: ${{ steps.composer-cache.outputs.dir }}
92 | key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }}
93 | restore-keys: |
94 | ${{ runner.os }}-php-${{ matrix.php }}-composer-
95 |
96 | -
97 | name: Configure global composer
98 | run: |
99 | composer global config --no-plugins allow-plugins.symfony/flex true
100 | composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^2.2.2"
101 |
102 | -
103 | name: Restrict Symfony version
104 | if: matrix.symfony != ''
105 | run: |
106 | composer config extra.symfony.require "${{ matrix.symfony }}"
107 |
108 | -
109 | name: Restrict Sylius version
110 | if: matrix.sylius != ''
111 | run: composer require "sylius/sylius:${{ matrix.sylius }}" --no-update --no-scripts --no-interaction
112 |
113 | -
114 | name: Install PHP dependencies
115 | run: composer install --no-interaction
116 | env:
117 | SYMFONY_REQUIRE: ${{ matrix.symfony }}
118 |
119 | -
120 | name: Get Yarn cache directory
121 | id: yarn-cache
122 | run: echo "::set-output name=dir::$(yarn cache dir)"
123 |
124 | -
125 | name: Cache Yarn
126 | uses: actions/cache@v2
127 | with:
128 | path: ${{ steps.yarn-cache.outputs.dir }}
129 | key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/package.json **/yarn.lock') }}
130 | restore-keys: |
131 | ${{ runner.os }}-node-${{ matrix.node }}-yarn-
132 |
133 | -
134 | name: Install JS dependencies
135 | run: (cd tests/Application && yarn install)
136 |
137 | -
138 | name: Prepare test application database
139 | run: |
140 | (cd tests/Application && bin/console doctrine:database:create -vvv)
141 | (cd tests/Application && bin/console doctrine:schema:create -vvv)
142 |
143 | -
144 | name: Prepare test application assets
145 | run: |
146 | (cd tests/Application && bin/console assets:install public -vvv)
147 | (cd tests/Application && yarn build:prod)
148 |
149 | -
150 | name: Prepare test application cache
151 | run: (cd tests/Application && bin/console cache:warmup -vvv)
152 |
153 | -
154 | name: Load fixtures in test application
155 | run: (cd tests/Application && bin/console sylius:fixtures:load -n)
156 |
157 | -
158 | name: Validate composer.json
159 | run: composer validate --ansi --strict
160 |
161 | -
162 | name: Validate database schema
163 | run: (cd tests/Application && bin/console doctrine:schema:validate)
164 |
165 | -
166 | name: Run PHPStan
167 | run: vendor/bin/phpstan analyse -c phpstan.neon -l max src/
168 |
169 | -
170 | name: Run Psalm
171 | run: vendor/bin/psalm
172 |
173 | -
174 | name: Run PHPSpec
175 | run: vendor/bin/phpspec run --ansi -f progress --no-interaction
176 |
177 | -
178 | name: Run PHPUnit
179 | run: vendor/bin/phpunit --colors=always
180 |
181 | -
182 | name: Run Behat
183 | run: vendor/bin/behat --colors --strict -vvv --no-interaction || vendor/bin/behat --colors --strict -vvv --no-interaction --rerun
184 |
185 | -
186 | name: Upload Behat logs
187 | uses: actions/upload-artifact@v2
188 | if: failure()
189 | with:
190 | name: Behat logs
191 | path: etc/build/
192 | if-no-files-found: ignore
193 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | /node_modules/
3 | /composer.lock
4 |
5 | /etc/build/*
6 | !/etc/build/.gitignore
7 |
8 | /tests/Application/yarn.lock
9 |
10 | /.phpunit.result.cache
11 | /behat.yml
12 | /phpspec.yml
13 | /phpunit.xml
14 |
15 | # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project
16 | /.php-version
17 | /php.ini
18 |
--------------------------------------------------------------------------------
/CHANGELOG-1.0.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG FOR `1.0.X`
2 |
3 | ## v1.0.0-alpha
4 |
5 | #### Details
6 |
7 | ### Changed
8 | - [#57](https://github.com/Sylius/SyliusOrderCommentsPlugin/issues/57) [Maintenance] Fix branch alias ([@lchrusciel](https://github.com/lchrusciel))
9 | - [#58](https://github.com/Sylius/SyliusOrderCommentsPlugin/issues/58) Sylius 1.3 support ([@JakobTolkemit](https://github.com/JakobTolkemit))
10 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | phpunit:
2 | vendor/bin/phpunit
3 |
4 | phpspec:
5 | vendor/bin/phpspec run --ansi --no-interaction -f dot
6 |
7 | phpstan:
8 | vendor/bin/phpstan analyse
9 |
10 | psalm:
11 | vendor/bin/psalm
12 |
13 | behat-js:
14 | APP_ENV=test vendor/bin/behat --colors --strict --no-interaction -vvv -f progress
15 |
16 | install:
17 | composer install --no-interaction --no-scripts
18 |
19 | backend:
20 | tests/Application/bin/console sylius:install --no-interaction
21 | tests/Application/bin/console sylius:fixtures:load default --no-interaction
22 |
23 | frontend:
24 | (cd tests/Application && yarn install --pure-lockfile)
25 | (cd tests/Application && GULP_ENV=prod yarn build)
26 |
27 | behat:
28 | APP_ENV=test vendor/bin/behat --colors --strict --no-interaction -vvv -f progress
29 |
30 | init: install backend frontend
31 |
32 | ci: init phpstan psalm phpunit phpspec behat
33 |
34 | integration: init phpunit behat
35 |
36 | static: install phpspec phpstan psalm
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Plugin Skeleton
2 |
3 | Adding comments to a Sylius order with customer notification.
4 |
5 | 
6 |
7 | 
8 |
9 |
10 | ## Installation
11 | 1. Run `composer require brille24/sylius-order-comments-plugin`
12 | 2. Updating the database with migrations
13 | ```bash
14 | bin/console doctrine:mig:diff
15 | bin/console doctrine:mig:mig
16 | ```
17 |
18 | ## Testing & Development
19 | For information on how to develop to test this plugin please refer to the official Sylius documentation under https://github.com/Sylius/PluginSkeleton/ .
20 |
--------------------------------------------------------------------------------
/behat.yml.dist:
--------------------------------------------------------------------------------
1 | imports:
2 | - vendor/sylius/sylius/src/Sylius/Behat/Resources/config/suites.yml
3 | - tests/Behat/Resources/suites.yml
4 |
5 | default:
6 | extensions:
7 | DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~
8 |
9 | FriendsOfBehat\MinkDebugExtension:
10 | directory: etc/build
11 | clean_start: false
12 | screenshot: true
13 |
14 | Behat\MinkExtension:
15 | files_path: "%paths.base%/vendor/sylius/sylius/src/Sylius/Behat/Resources/fixtures/"
16 | base_url: "https://127.0.0.1:8080/"
17 | default_session: symfony
18 | javascript_session: chrome_headless
19 | sessions:
20 | symfony:
21 | symfony: ~
22 | chrome_headless:
23 | chrome:
24 | api_url: http://127.0.0.1:9222
25 | validate_certificate: false
26 | chrome:
27 | selenium2:
28 | browser: chrome
29 | capabilities:
30 | browserName: chrome
31 | browser: chrome
32 | version: ""
33 | marionette: null # https://github.com/Behat/MinkExtension/pull/311
34 | chrome:
35 | switches:
36 | - "start-fullscreen"
37 | - "start-maximized"
38 | - "no-sandbox"
39 | extra_capabilities:
40 | unexpectedAlertBehaviour: accept
41 | firefox:
42 | selenium2:
43 | browser: firefox
44 | show_auto: false
45 |
46 | FriendsOfBehat\SymfonyExtension:
47 | bootstrap: tests/Application/config/bootstrap.php
48 | kernel:
49 | class: Tests\Brille24\SyliusOrderCommentsPlugin\Application\Kernel
50 |
51 | FriendsOfBehat\VariadicExtension: ~
52 |
53 | FriendsOfBehat\SuiteSettingsExtension:
54 | paths:
55 | - "features"
56 |
--------------------------------------------------------------------------------
/bin/create_node_symlink.php:
--------------------------------------------------------------------------------
1 | `' . NODE_MODULES_FOLDER_NAME . '` already exists as a link or folder, keeping existing as may be intentional.' . PHP_EOL;
11 | exit(0);
12 | } else {
13 | echo '> Invalid symlink `' . NODE_MODULES_FOLDER_NAME . '` detected, recreating...' . PHP_EOL;
14 | if (!@unlink(NODE_MODULES_FOLDER_NAME)) {
15 | echo '> Could not delete file `' . NODE_MODULES_FOLDER_NAME . '`.' . PHP_EOL;
16 | exit(1);
17 | }
18 | }
19 | }
20 |
21 | /* try to create the symlink using PHP internals... */
22 | $success = @symlink(PATH_TO_NODE_MODULES, NODE_MODULES_FOLDER_NAME);
23 |
24 | /* if case it has failed, but OS is Windows... */
25 | if (!$success && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
26 | /* ...then try a different approach which does not require elevated permissions and folder to exist */
27 | echo '> This system is running Windows, creation of links requires elevated privileges,' . PHP_EOL;
28 | echo '> and target path to exist. Fallback to NTFS Junction:' . PHP_EOL;
29 | exec(sprintf('mklink /J %s %s 2> NUL', NODE_MODULES_FOLDER_NAME, PATH_TO_NODE_MODULES), $output, $returnCode);
30 | $success = $returnCode === 0;
31 | if (!$success) {
32 | echo '> Failed o create the required symlink' . PHP_EOL;
33 | exit(2);
34 | }
35 | }
36 |
37 | $path = @readlink(NODE_MODULES_FOLDER_NAME);
38 | /* check if link points to the intended directory */
39 | if ($path && realpath($path) === realpath(PATH_TO_NODE_MODULES)) {
40 | echo '> Successfully created the symlink.' . PHP_EOL;
41 | exit(0);
42 | }
43 |
44 | echo '> Failed to create the symlink to `' . NODE_MODULES_FOLDER_NAME . '`.' . PHP_EOL;
45 | exit(3);
46 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "brille24/sylius-order-comments-plugin",
3 | "type": "sylius-plugin",
4 | "description": "Order comments plugin for Sylius.",
5 | "keywords": [
6 | "brille24",
7 | "sylius",
8 | "sylius-plugin"
9 | ],
10 | "license": "MIT",
11 | "require": {
12 | "php": "^8.0",
13 | "ramsey/uuid": "^3.9 || ^4.7",
14 | "ramsey/uuid-doctrine": "^1.4 || ^2.0.0",
15 | "sylius/mailer-bundle": "^1.8 || ^2.0@beta",
16 | "sylius/sylius": "^1.11",
17 | "symfony/webpack-encore-bundle": "^1.15"
18 | },
19 | "require-dev": {
20 | "behat/behat": "^3.6.1",
21 | "behat/mink-selenium2-driver": "^1.4",
22 | "dmore/behat-chrome-extension": "^1.3",
23 | "dmore/chrome-mink-driver": "^2.7",
24 | "friends-of-behat/mink": "^1.8",
25 | "friends-of-behat/mink-browserkit-driver": "^1.4",
26 | "friends-of-behat/mink-debug-extension": "^2.0.0",
27 | "friends-of-behat/mink-extension": "^2.4",
28 | "friends-of-behat/page-object-extension": "^0.3",
29 | "friends-of-behat/suite-settings-extension": "^1.0",
30 | "friends-of-behat/symfony-extension": "^2.1",
31 | "friends-of-behat/variadic-extension": "^1.3",
32 | "phpspec/phpspec": "^7.2",
33 | "phpstan/extension-installer": "^1.0",
34 | "phpstan/phpstan": "^1.8.1",
35 | "phpstan/phpstan-doctrine": "1.3.37",
36 | "phpstan/phpstan-strict-rules": "^1.3.0",
37 | "phpstan/phpstan-webmozart-assert": "^1.2.0",
38 | "phpunit/phpunit": "^9.5",
39 | "polishsymfonycommunity/symfony-mocker-container": "^1.0",
40 | "sylius-labs/coding-standard": "^4.2",
41 | "symfony/browser-kit": "^5.4 || ^6.0",
42 | "symfony/debug-bundle": "^5.4 || ^6.0",
43 | "symfony/dotenv": "^5.4 || ^6.0",
44 | "symfony/flex": "^2.2.2",
45 | "symfony/intl": "^5.4 || ^6.0",
46 | "symfony/web-profiler-bundle": "^5.4 || ^6.0",
47 | "vimeo/psalm": "5.9.0"
48 | },
49 | "config": {
50 | "sort-packages": true,
51 | "allow-plugins": {
52 | "dealerdirect/phpcodesniffer-composer-installer": false,
53 | "phpstan/extension-installer": true,
54 | "symfony/flex": true
55 | }
56 | },
57 | "extra": {
58 | "branch-alias": {
59 | "dev-master": "1.12-dev"
60 | }
61 | },
62 | "autoload": {
63 | "psr-4": {
64 | "Brille24\\OrderCommentsPlugin\\": "src/",
65 | "Tests\\Brille24\\OrderCommentsPlugin\\": "tests/"
66 | }
67 | },
68 | "autoload-dev": {
69 | "classmap": [
70 | "tests/Application/Kernel.php"
71 | ]
72 | },
73 | "scripts": {
74 | "post-install-cmd": [
75 | "php bin/create_node_symlink.php"
76 | ],
77 | "post-update-cmd": [
78 | "php bin/create_node_symlink.php"
79 | ],
80 | "post-create-project-cmd": [
81 | "php bin/create_node_symlink.php"
82 | ],
83 | "auto-scripts": {
84 | "cache:clear": "symfony-cmd",
85 | "assets:install %PUBLIC_DIR%": "symfony-cmd",
86 | "security-checker security:check": "script"
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/config/admin_routing.yaml:
--------------------------------------------------------------------------------
1 | sylius_order_comments_plugin_admin_partial:
2 | resource: "@Brille24SyliusOrderCommentsPlugin/config/routing/admin/order_comments.yaml"
3 | prefix: "/admin/orders"
4 |
--------------------------------------------------------------------------------
/config/config.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | dbal:
3 | types:
4 | uuid: 'Ramsey\Uuid\Doctrine\UuidType'
5 |
6 | sylius_mailer:
7 | emails:
8 | unread_comment:
9 | subject: 'sylius.emails.unread_comment.subject'
10 | template: '@Brille24SyliusOrderCommentsPlugin/Email/unread_comment.html.twig'
11 |
12 | knp_gaufrette:
13 | adapters:
14 | sylius_comments_attachment:
15 | local:
16 | directory: '%sylius_core.public_dir%/media/comment_attachments'
17 | create: true
18 | filesystems:
19 | sylius_comments_attachment:
20 | adapter: 'sylius_comments_attachment'
21 |
22 | sylius_ui:
23 | events:
24 | sylius.admin.order.show.summary:
25 | blocks:
26 | order_comments: '@Brille24SyliusOrderCommentsPlugin/injected/admin_order_comments.html.twig'
27 | sylius.shop.account.order.show.subcontent:
28 | blocks:
29 | order_comments: '@Brille24SyliusOrderCommentsPlugin/injected/shop_order_comments.html.twig'
30 |
--------------------------------------------------------------------------------
/config/doctrine/AttachedFile.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/config/doctrine/Comment.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/config/doctrine/Email.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/config/routing/admin/order_comments.yaml:
--------------------------------------------------------------------------------
1 | sylius_admin_order_comments_partial_comment_create:
2 | path: "/{orderId}/comments"
3 | methods: ["POST"]
4 | defaults:
5 | _controller: "brille24.order_comments_plugin.infrastructure.controller.ui.comment_form_action"
6 |
7 | sylius_admin_order_comments_partial_comment_index:
8 | path: "/{orderId}/comments"
9 | methods: ["GET"]
10 | defaults:
11 | _controller: "sylius.controller.order_comment::indexAction"
12 | _sylius:
13 | paginate: false
14 | limit: false
15 | repository:
16 | method: findBy
17 | arguments:
18 | - order: "expr:notFoundOnNull(service('sylius.repository.order').find($orderId))"
19 | - createdAt: asc
20 | template: "@Brille24SyliusOrderCommentsPlugin/index.html.twig"
21 | isAdmin: true
22 |
--------------------------------------------------------------------------------
/config/routing/shop/order_comments.yaml:
--------------------------------------------------------------------------------
1 | sylius_shop_order_comments_partial_comment_create:
2 | path: "/{orderId}/comments"
3 | methods: ["POST"]
4 | defaults:
5 | _controller: "brille24.order_comments_plugin.infrastructure.controller.ui.comment_form_action"
6 |
7 | sylius_shop_order_comments_partial_comment_index:
8 | path: "/{number}/comments"
9 | methods: ["GET"]
10 | defaults:
11 | _controller: "sylius.controller.order_comment::indexAction"
12 | _sylius:
13 | paginate: false
14 | limit: false
15 | repository:
16 | method: findBy
17 | arguments:
18 | - order: "expr:notFoundOnNull(service('sylius.repository.order').findOneByNumber($number))"
19 | - createdAt: asc
20 | template: "@Brille24SyliusOrderCommentsPlugin/index.html.twig"
21 | isAdmin: false
22 |
--------------------------------------------------------------------------------
/config/services.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 | media/comment_attachments
17 |
18 |
19 |
20 |
27 |
28 |
37 |
38 |
45 |
46 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/config/shop_routing.yaml:
--------------------------------------------------------------------------------
1 | sylius_order_comments_plugin_shop_partial:
2 | resource: "@Brille24SyliusOrderCommentsPlugin/config/routing/shop/order_comments.yaml"
3 | prefix: "/shop/orders"
4 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | app:
3 | image: sylius/standard:1.11-traditional-alpine
4 | environment:
5 | APP_ENV: "dev"
6 | DATABASE_URL: "mysql://root:mysql@mysql/sylius_%kernel.environment%?charset=utf8mb4"
7 | # DATABASE_URL: "pgsql://root:postgres@postgres/sylius_%kernel.environment%?charset=utf8" # When using postgres
8 | PHP_DATE_TIMEZONE: "Europe/Warsaw"
9 | volumes:
10 | - ./:/app:delegated
11 | - ./.docker/php/php.ini:/etc/php8/php.ini:delegated
12 | - ./.docker/nginx/nginx.conf:/etc/nginx/nginx.conf:delegated
13 | ports:
14 | - 80:80
15 | depends_on:
16 | - mysql
17 | networks:
18 | - sylius
19 |
20 | mysql:
21 | image: mysql:8.0
22 | platform: linux/amd64
23 | environment:
24 | MYSQL_ROOT_PASSWORD: mysql
25 | ports:
26 | - ${MYSQL_PORT:-3306}:3306
27 | networks:
28 | - sylius
29 |
30 | # postgres:
31 | # image: postgres:14-alpine
32 | # environment:
33 | # POSTGRES_USER: root
34 | # POSTGRES_PASSWORD: postgres
35 | # ports:
36 | # - ${POSTGRES_PORT:-5432}:5432
37 | # networks:
38 | # - sylius
39 |
40 | networks:
41 | sylius:
42 | driver: bridge
43 |
--------------------------------------------------------------------------------
/ecs.php:
--------------------------------------------------------------------------------
1 | paths([
10 | __DIR__ . '/src',
11 | __DIR__ . '/tests/Behat',
12 | __DIR__ . '/ecs.php',
13 | ]);
14 |
15 | $ecsConfig->import('vendor/sylius-labs/coding-standard/ecs.php');
16 |
17 | $ecsConfig->skip([
18 | VisibilityRequiredFixer::class => ['*Spec.php'],
19 | ]);
20 | };
21 |
--------------------------------------------------------------------------------
/etc/build/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/etc/build/.gitignore
--------------------------------------------------------------------------------
/features/attaching_file_to_comment.feature:
--------------------------------------------------------------------------------
1 | @customer_order_comments
2 | Feature: Attaching file to comment
3 | In order to provide ability to attach file to comment
4 | As a Customer
5 | I want to be able to communicate with the store owner via order comments with more details
6 |
7 | Background:
8 | Given the store operates on a single channel in "United States"
9 | And this channel has "customer.service@test.com" as a contact email
10 | And the store has a product "PHP T-Shirt"
11 | And the store ships everywhere for free
12 | And the store allows paying with "Cash on Delivery"
13 | And there was account of "john.doe@gmail.com" with password "sylius"
14 | And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
15 | And the customer bought a single "PHP T-Shirt"
16 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
17 | And I am logged in as "john.doe@gmail.com"
18 |
19 | @domain @application @ui
20 | Scenario: Attaching file to comment
21 | When I comment the order "#00000022" with "Hello" and "file.pdf" file
22 | Then this order should have a comment with "Hello" and file "file.pdf" from this customer
23 |
--------------------------------------------------------------------------------
/features/commenting_an_order_by_a_customer.feature:
--------------------------------------------------------------------------------
1 | @customer_order_comments
2 | Feature: Commenting an order by a customer
3 | In order to provide ability to comment an order
4 | As a Customer
5 | I want to be able to communicate with the store owner via order comments
6 |
7 | Background:
8 | Given the store operates on a single channel in "United States"
9 | And this channel has "customer.service@test.com" as a contact email
10 | And the store has a product "PHP T-Shirt"
11 | And the store ships everywhere for free
12 | And the store allows paying with "Cash on Delivery"
13 | And there was account of "john.doe@gmail.com" with password "sylius"
14 | And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
15 | And the customer bought a single "PHP T-Shirt"
16 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
17 | And I am logged in as "john.doe@gmail.com"
18 |
19 | @domain @application @ui
20 | Scenario: Customer commented an order
21 | When I comment the order "#00000022" with "Hello"
22 | Then this order should have a comment with "Hello" from this customer
23 |
24 | @application @ui
25 | Scenario: Customer commented an order
26 | Given a customer "john.doe@gmail.com" placed an order "#00000023"
27 | And the customer bought a single "PHP T-Shirt"
28 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
29 | When I comment the order "#00000023" with "Hello"
30 | Then this order should have a comment with "Hello" from this customer
31 | But the order "#00000022" should not have any comments
32 |
33 | @domain @application @ui
34 | Scenario: Customer cannot comment an order with an empty message
35 | When I try to comment the order "#00000022" with an empty message
36 | Then I should be notified that comment is invalid
37 | And this order should not have any comments
38 |
39 | @domain @application
40 | Scenario: Customer with invalid email cannot comment an order
41 | When a customer with email "notEmail" try to comment an order "#00000022"
42 | Then I should be notified that comment is invalid
43 | And this order should not have any comments
44 |
45 | @application
46 | Scenario: Customer cannot comment an order which does not exist
47 | When I try to comment a not existing order with "Hello"
48 | Then I should be notified that comment is invalid
49 | And this order should not have any comments
50 |
51 | @application
52 | Scenario: Sending the email notification to the administrator about unread customer's comments
53 | Given I have commented the order "#00000022" with "Hello"
54 | Then the notification email should be sent to the administrator about "Hello" comment
55 |
--------------------------------------------------------------------------------
/features/commenting_an_order_by_an_administrator.feature:
--------------------------------------------------------------------------------
1 | @administrator_order_comments
2 | Feature: Commenting an order by an administrator
3 | In order to communicate with the customer that made an order
4 | As an Administrator
5 | I want to be able to add a comment to the order
6 |
7 | Background:
8 | Given the store operates on a single channel in "United States"
9 | And the store has a product "PHP T-Shirt"
10 | And the store ships everywhere for free
11 | And the store allows paying with "Cash on Delivery"
12 | And there was account of "john.doe@test.com" with password "sylius"
13 | And there is a customer "john.doe@test.com" that placed an order "#00000022"
14 | And the customer bought a single "PHP T-Shirt"
15 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
16 | And I am logged in as an administrator
17 |
18 | @domain @application @ui
19 | Scenario: Administrator commented an order
20 | When I comment the order "#00000022" with "How can I help you?" with the notify customer checkbox enabled
21 | Then this order should have a comment with "How can I help you?" from this administrator
22 |
23 | @application @ui
24 | Scenario: Administrator see only related comments
25 | Given a customer "john.doe@test.com" placed an order "#00000023"
26 | And the customer bought a single "PHP T-Shirt"
27 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
28 | When I comment the order "#00000023" with "How can I help you?" with the notify customer checkbox enabled
29 | Then this order should have a comment with "How can I help you?" from this administrator
30 | But the order "#00000022" should not have any comments
31 |
32 | @domain @application @ui
33 | Scenario: Administrator cannot comment the order with an empty message
34 | When I try to comment the order "#00000022" with an empty message
35 | Then I should be notified that comment is invalid
36 | And this order should not have any comments
37 |
38 | @application
39 | Scenario: Sending an email notification to the customer about unread comments
40 | When I have commented the order "#00000022" with "How can I help you?" with the notify customer checkbox enabled
41 | Then the notification email should be sent to the customer about "How can I help you?" comment
42 |
43 | @application
44 | Scenario: Sending no email notification to the customer about unread comments
45 | When I have commented the order "#00000022" with "How can I not help you?" with the notify customer checkbox disabled
46 | Then the notification email should not be sent to the customer about "How can I not help you?" comment
47 |
--------------------------------------------------------------------------------
/features/sorting_administrator_comments.feature:
--------------------------------------------------------------------------------
1 | @administrator_order_comments
2 | Feature: Sorting administrator comments
3 | In order to track the conversation properly
4 | As an Administrator
5 | I want to be see comments from the oldest to the newest
6 |
7 | Background:
8 | Given the store operates on a single channel in "United States"
9 | And the store has a product "PHP T-Shirt"
10 | And the store ships everywhere for free
11 | And the store allows paying with "Cash on Delivery"
12 | And there was account of "john.doe@gmail.com" with password "sylius"
13 | And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
14 | And the customer bought a single "PHP T-Shirt"
15 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
16 | And I am logged in as an administrator
17 |
18 | @ui
19 | Scenario: Administrator commented an order
20 | When I have commented the order "#00000022" with "Hello" with the notify customer checkbox enabled
21 | And I have commented the order "#00000022" with "How can I help you?" with the notify customer checkbox enabled
22 | Then the first comment from the top should have the "Hello" message
23 |
--------------------------------------------------------------------------------
/features/sorting_customer_comments.feature:
--------------------------------------------------------------------------------
1 | @customer_order_comments
2 | Feature: Sorting customer comments
3 | In order to track the conversation properly
4 | As a Customer
5 | I want to be see comments from the oldest to the newest
6 |
7 | Background:
8 | Given the store operates on a single channel in "United States"
9 | And this channel has "customer.service@test.com" as a contact email
10 | And the store has a product "PHP T-Shirt"
11 | And the store ships everywhere for free
12 | And the store allows paying with "Cash on Delivery"
13 | And there was account of "john.doe@gmail.com" with password "sylius"
14 | And there is a customer "john.doe@gmail.com" that placed an order "#00000022"
15 | And the customer bought a single "PHP T-Shirt"
16 | And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment
17 | And I am logged in as "john.doe@gmail.com"
18 |
19 | @ui
20 | Scenario: Sorting customer comments
21 | Given I have commented the order "#00000022" with "Hello"
22 | And I wait 1 seconds
23 | And I have commented the order "#00000022" with "Is it me you are looking for?"
24 | Then the first comment from the top should have the "Hello" message
25 |
--------------------------------------------------------------------------------
/node_modules:
--------------------------------------------------------------------------------
1 | tests/Application/node_modules
--------------------------------------------------------------------------------
/phpspec.yml.dist:
--------------------------------------------------------------------------------
1 | suites:
2 | main:
3 | namespace: Brille24\SyliusOrderCommentsPlugin
4 | psr4_prefix: Brille24\SyliusOrderCommentsPlugin
5 |
--------------------------------------------------------------------------------
/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: max
3 | reportUnmatchedIgnoredErrors: false
4 | checkMissingIterableValueType: false
5 | paths:
6 | - src
7 | - tests/Behat
8 |
9 | excludes_analyse:
10 | # Makes PHPStan crash
11 | - 'src/DependencyInjection/Configuration.php'
12 |
13 | # Test dependencies
14 | - 'tests/Application/app/**.php'
15 | - 'tests/Application/src/**.php'
16 |
17 | ignoreErrors:
18 | - '/Parameter #1 \$configuration of method Symfony\\Component\\DependencyInjection\\Extension\\Extension::processConfiguration\(\) expects Symfony\\Component\\Config\\Definition\\ConfigurationInterface, Symfony\\Component\\Config\\Definition\\ConfigurationInterface\|null given\./'
19 | - '/Method Sylius\\Component\\Mailer\\Sender\\SenderInterface\:\:send\(\) invoked with 7 parameters\, 2\-5 required\./'
20 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | tests
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Application/Command/CommentOrder.php:
--------------------------------------------------------------------------------
1 | orderNumber;
28 | }
29 |
30 | public function authorEmail(): string
31 | {
32 | return $this->authorEmail;
33 | }
34 |
35 | public function message(): string
36 | {
37 | return $this->message;
38 | }
39 |
40 | public function file(): ?UploadedFile
41 | {
42 | return $this->file;
43 | }
44 |
45 | public function notifyCustomer(): bool
46 | {
47 | return $this->notifyCustomer;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Application/CommandHandler/CommentOrderHandler.php:
--------------------------------------------------------------------------------
1 | orderRepository->findOneBy(['number' => $command->orderNumber()]);
34 |
35 | if (null === $order) {
36 | throw new \DomainException(sprintf('Cannot comment an order "%s" because it does not exist', $command->orderNumber()));
37 | }
38 |
39 | $comment = new Comment($order, $command->authorEmail(), $command->message(), $command->notifyCustomer());
40 |
41 | $file = $command->file();
42 | if (null !== $file) {
43 | $extension = $file->guessExtension() ?? 'pdf';
44 | $newFileName = Uuid::uuid4()->toString().'.'.$extension;
45 | $file->move($this->fileDir, $newFileName);
46 |
47 | $filePath = $comment->attachFile($this->fileDir.'/'.$newFileName);
48 | $this->eventDispatcher->dispatch(FileAttached::occur($filePath));
49 | }
50 |
51 | $this->eventDispatcher->dispatch(OrderCommented::occur(
52 | $comment->getId(),
53 | $comment->order(),
54 | $comment->authorEmail(),
55 | $comment->message(),
56 | $comment->notifyCustomer(),
57 | $comment->createdAt(),
58 | $comment->attachedFile()
59 | ));
60 |
61 | $this->entityManager->persist($comment);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Application/Process/SendUnreadCommentEmailNotification.php:
--------------------------------------------------------------------------------
1 | 'handleOrderCommented',
25 | ];
26 | }
27 |
28 | public function handleOrderCommented(OrderCommented $event): void
29 | {
30 | if (!$event->notifyCustomer()) {
31 | return;
32 | }
33 |
34 | $order = $event->order();
35 | $customer = $order->getCustomer();
36 |
37 | if (null === $customer) {
38 | return;
39 | }
40 |
41 | /** @var ChannelInterface $channel */
42 | $channel = $order->getChannel();
43 |
44 | $recipients = [$channel->getContactEmail(), $customer->getEmail()];
45 |
46 | $this->sendUnreadCommentNotification(
47 | array_diff(array_filter($recipients), [$event->authorEmail()]),
48 | $order,
49 | $event->message(),
50 | (string) $event->authorEmail(),
51 | $event->attachedFile()
52 | );
53 | }
54 |
55 | /**
56 | * @param array $recipients
57 | */
58 | private function sendUnreadCommentNotification(
59 | array $recipients,
60 | OrderInterface $order,
61 | string $message,
62 | string $authorEmail,
63 | ?AttachedFile $attachedFile
64 | ): void {
65 | $attachments = ($attachedFile === null) ? [] : [$attachedFile->path() ?? ''];
66 |
67 | $orderChannel = $order->getChannel();
68 | Assert::isInstanceOf($orderChannel, ChannelInterface::class);
69 |
70 | $orderChannelCode = $orderChannel->getCode();
71 | Assert::notNull($orderChannelCode);
72 |
73 | $this->emailSender->sendWithChannelTemplate(
74 | 'unread_comment',
75 | $orderChannelCode,
76 | $recipients,
77 | [
78 | 'order' => $order,
79 | 'message' => $message,
80 | 'authorEmail' => $authorEmail,
81 | ],
82 | $attachments
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Application/Process/SendUnreadCommentEmailNotificationInterface.php:
--------------------------------------------------------------------------------
1 | $this->channelRepository->findOneByCode($channelCode)]);
37 |
38 | try {
39 | /**
40 | * @psalm-suppress DeprecatedMethod
41 | * @psalm-suppress TooManyArguments
42 | */
43 | $this->baseSender->send("{$code}_{$channelCode}", $recipients, $enrichedData, $attachments, $replyTo, $ccRecipients, $bccRecipients);
44 | } catch (InvalidArgumentException) {
45 | /**
46 | * @psalm-suppress DeprecatedMethod
47 | * @psalm-suppress TooManyArguments
48 | */
49 | $this->baseSender->send($code, $recipients, $enrichedData, $attachments, $replyTo, $ccRecipients, $bccRecipients);
50 | }
51 | }
52 |
53 | /**
54 | * {@inheritdoc}
55 | */
56 | public function send(
57 | string $code,
58 | array $recipients,
59 | array $data = [],
60 | array $attachments = [],
61 | array $replyTo = []
62 | ): void {
63 | $channelCode = $this->channelContext->getChannel()->getCode();
64 | Assert::notNull($channelCode);
65 |
66 | $this->sendWithChannelTemplate($code, $channelCode, $recipients, $data, $attachments, $replyTo);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Application/Process/Sender/ChanneledEmailSenderInterface.php:
--------------------------------------------------------------------------------
1 | processConfiguration($this->getConfiguration([], $container), $configs);
23 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../../config'));
24 | $loader->load('services.xml');
25 |
26 | /** @var string $projectDir */
27 | $projectDir = $container->getParameter('kernel.project_dir');
28 | $container->setParameter(
29 | 'sylius_order_comment_plugin.comment_file_dir',
30 | $projectDir.'/public/media/comment_attachments'
31 | );
32 | }
33 |
34 | public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface
35 | {
36 | return new Configuration();
37 | }
38 |
39 | protected function getMigrationsNamespace(): string
40 | {
41 | return 'Brille24\SyliusOrderCommentsPlugin\Migrations';
42 | }
43 |
44 | protected function getMigrationsDirectory(): string
45 | {
46 | return '@Brille24SyliusOrderCommentsPlugin/src/Infrastructure/Migrations';
47 | }
48 |
49 | protected function getNamespacesOfMigrationsExecutedBefore(): array
50 | {
51 | return ['Sylius\Bundle\CoreBundle\Migrations'];
52 | }
53 |
54 | public function prepend(ContainerBuilder $container): void
55 | {
56 | $config = $this->getCurrentConfiguration($container);
57 |
58 | $this->registerResources('sylius', 'doctrine/orm', $config['resources'], $container);
59 |
60 | $this->prependDoctrineMigrations($container);
61 | $this->prependDoctrineMapping($container);
62 | }
63 |
64 | private function prependDoctrineMapping(ContainerBuilder $container): void
65 | {
66 | $config = array_merge(...$container->getExtensionConfig('doctrine'));
67 |
68 | // do not register mappings if dbal not configured.
69 | if (!isset($config['dbal']) || !isset($config['orm'])) {
70 | return;
71 | }
72 |
73 | $container->prependExtensionConfig('doctrine', [
74 | 'orm' => [
75 | 'mappings' => [
76 | 'Brille24SyliusOrderCommentsPlugin' => [
77 | 'type' => 'xml',
78 | 'dir' => $this->getPath($container, '/config/doctrine/'),
79 | 'is_bundle' => false,
80 | 'prefix' => 'Brille24\OrderCommentsPlugin\Domain\Model',
81 | 'alias' => 'Brille24SyliusOrderCommentsPlugin',
82 | ],
83 | ],
84 | ],
85 | ]);
86 | }
87 |
88 | private function getCurrentConfiguration(ContainerBuilder $container): array
89 | {
90 | /** @var ConfigurationInterface $configuration */
91 | $configuration = $this->getConfiguration([], $container);
92 |
93 | $configs = $container->getExtensionConfig($this->getAlias());
94 |
95 | return $this->processConfiguration($configuration, $configs);
96 | }
97 |
98 | private function getPath(ContainerBuilder $container, string $path): string
99 | {
100 | /** @var array> $metadata */
101 | $metadata = $container->getParameter('kernel.bundles_metadata');
102 |
103 | return $metadata['Brille24SyliusOrderCommentsPlugin']['path'] . $path;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 | getRootNode();
20 |
21 | $this->addResourcesSection($rootNode);
22 |
23 | return $treeBuilder;
24 | }
25 |
26 | private function addResourcesSection(ArrayNodeDefinition $node): void
27 | {
28 | $node
29 | ->children()
30 | ->arrayNode('resources')
31 | ->addDefaultsIfNotSet()
32 | ->children()
33 | ->arrayNode('order_comment')
34 | ->addDefaultsIfNotSet()
35 | ->children()
36 | ->variableNode('options')->end()
37 | ->arrayNode('classes')
38 | ->addDefaultsIfNotSet()
39 | ->children()
40 | ->scalarNode('model')->defaultValue(Comment::class)->cannotBeEmpty()->end()
41 | ->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
42 | ->scalarNode('repository')->defaultValue(EntityRepository::class)->cannotBeEmpty()->end()
43 | ->scalarNode('factory')->defaultValue(Factory::class)->end()
44 | ->scalarNode('form')->defaultValue(DefaultResourceType::class)->cannotBeEmpty()->end()
45 | ->end()
46 | ->end()
47 | ->end()
48 | ->end()
49 | ->end()
50 | ->end()
51 | ->end()
52 | ;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Domain/Event/FileAttached.php:
--------------------------------------------------------------------------------
1 | filePath;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Domain/Event/OrderCommented.php:
--------------------------------------------------------------------------------
1 | orderCommentId;
40 | }
41 |
42 | public function order(): OrderInterface
43 | {
44 | return $this->order;
45 | }
46 |
47 | public function authorEmail(): Email
48 | {
49 | return $this->authorEmail;
50 | }
51 |
52 | public function message(): string
53 | {
54 | return $this->message;
55 | }
56 |
57 | public function notifyCustomer(): bool
58 | {
59 | return $this->notifyCustomer;
60 | }
61 |
62 | public function createdAt(): \DateTimeInterface
63 | {
64 | return $this->createdAt;
65 | }
66 |
67 | public function attachedFile(): ?AttachedFile
68 | {
69 | return $this->attachedFile;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/Domain/Model/AttachedFile.php:
--------------------------------------------------------------------------------
1 | path;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Domain/Model/Comment.php:
--------------------------------------------------------------------------------
1 | message) {
30 | throw new \DomainException('OrderComment cannot be created with empty message');
31 | }
32 |
33 | $this->id = Uuid::uuid4();
34 | $this->authorEmail = Email::fromString($authorEmail);
35 | $this->createdAt = new \DateTimeImmutable();
36 | }
37 |
38 | public function attachFile(string $path): string
39 | {
40 | $this->attachedFile = AttachedFile::create($path);
41 |
42 | $path = $this->attachedFile->path();
43 | Assert::string($path);
44 |
45 | return $path;
46 | }
47 |
48 | public function getId(): UuidInterface
49 | {
50 | return $this->id;
51 | }
52 |
53 | public function order(): OrderInterface
54 | {
55 | return $this->order;
56 | }
57 |
58 | public function authorEmail(): Email
59 | {
60 | return $this->authorEmail;
61 | }
62 |
63 | public function message(): string
64 | {
65 | return $this->message;
66 | }
67 |
68 | public function createdAt(): \DateTimeInterface
69 | {
70 | return $this->createdAt;
71 | }
72 |
73 | public function attachedFile(): ?AttachedFile
74 | {
75 | return $this->attachedFile;
76 | }
77 |
78 | public function notifyCustomer(): bool
79 | {
80 | return $this->notifyCustomer;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Domain/Model/Email.php:
--------------------------------------------------------------------------------
1 | email;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Infrastructure/Controller/Ui/OrderCommentAction.php:
--------------------------------------------------------------------------------
1 | formFactory->create(OrderCommentType::class);
34 | $form->handleRequest($request);
35 | $token = $this->securityTokenStorage->getToken();
36 |
37 | /** @var string $referer */
38 | $referer = $request->headers->get('referer');
39 | if (null === $token || !$form->isValid()) {
40 | return new RedirectResponse($referer);
41 | }
42 |
43 | /** @var OrderComment $comment */
44 | $comment = $form->getData();
45 |
46 | /** @var UserInterface|string|null $user */
47 | $user = $token->getUser();
48 | /** @var OrderInterface $order */
49 | $order = $this->orderRepository->find($request->attributes->get('orderId'));
50 |
51 | Assert::isInstanceOf($user, UserInterface::class);
52 |
53 | $orderNumber = $order->getNumber();
54 | $email = $user->getEmail();
55 | Assert::string($orderNumber);
56 | Assert::string($email);
57 |
58 | $this->commandBus->dispatch(CommentOrder::create(
59 | $orderNumber,
60 | $email,
61 | $comment->message,
62 | $comment->notifyCustomer,
63 | $comment->file
64 | ));
65 |
66 | return new RedirectResponse($referer);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Infrastructure/Controller/Ui/RenderOrderCommentAction.php:
--------------------------------------------------------------------------------
1 | formFactory->create(OrderCommentType::class);
21 |
22 | return new Response($this->twig->render(
23 | '@Brille24SyliusOrderCommentsPlugin/_form.html.twig',
24 | ['form' => $form->createView(), 'orderId' => $orderId, 'submitPath' => $submitPath, 'isAdmin' => $isAdmin]
25 | ));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Infrastructure/Form/DTO/OrderComment.php:
--------------------------------------------------------------------------------
1 | add(
22 | 'message',
23 | TextareaType::class,
24 | [
25 | 'constraints' => [new NotBlank()],
26 | 'required' => true,
27 | 'empty_data' => '',
28 | ]
29 | )
30 | ->add(
31 | 'notifyCustomer',
32 | CheckboxType::class,
33 | ['label' => 'sylius_order_comments.notify_customer']
34 | )
35 | ->add('file', FileType::class)
36 | ;
37 | }
38 |
39 | public function configureOptions(OptionsResolver $resolver): void
40 | {
41 | $resolver->setDefaults(['data_class' => OrderComment::class]);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Infrastructure/Migrations/Version20230317140309.php:
--------------------------------------------------------------------------------
1 | addSql('CREATE TABLE sylius_order_comment (id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', order_id INT DEFAULT NULL, message TEXT NOT NULL, createdAt DATETIME NOT NULL, notifyCustomer TINYINT(1) NOT NULL, authorEmail_email VARCHAR(255) NOT NULL, attachedFile_path VARCHAR(255) DEFAULT NULL, INDEX IDX_8EA9CF098D9F6D38 (order_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
24 | $this->addSql('ALTER TABLE sylius_order_comment ADD CONSTRAINT FK_8EA9CF098D9F6D38 FOREIGN KEY (order_id) REFERENCES sylius_order (id)');
25 | }
26 |
27 | public function down(Schema $schema): void
28 | {
29 | // this down() migration is auto-generated, please modify it to your needs
30 | $this->addSql('ALTER TABLE sylius_order_comment DROP FOREIGN KEY FK_8EA9CF098D9F6D38');
31 | $this->addSql('DROP TABLE sylius_order_comment');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/templates/Email/unread_comment.html.twig:
--------------------------------------------------------------------------------
1 | {% block subject %}
2 | You have unread comment from {{ authorEmail }}
3 | {% endblock %}
4 |
5 | {% block body %}
6 | {% autoescape %}
7 | Message from: {{ authorEmail }}
8 |
9 | Content:
10 |
11 | "{{ message }}"
12 | {% endautoescape %}
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/templates/_form.html.twig:
--------------------------------------------------------------------------------
1 |
2 | {{ form_start(form, {'action': path(submitPath, { 'orderId': orderId}), 'attr': {'class': 'ui reply form', 'novalidate': 'novalidate'}}) }}
3 |
4 | {{ form_row(form.message) }}
5 |
6 |
7 | {{ form_row(form.file) }}
8 |
9 | {% if isAdmin %}
10 |
11 | {{ form_label(form.notifyCustomer) }}
12 | {{ form_widget(form.notifyCustomer) }}
13 |
14 | {% endif %}
15 |
16 | {{ form_row(form._token) }}
17 | {{ form_end(form, {'render_rest': false}) }}
18 |
19 |
--------------------------------------------------------------------------------
/templates/index.html.twig:
--------------------------------------------------------------------------------
1 |
2 | {% for order_comment in order_comments %}
3 |
26 | {% endfor %}
27 |
--------------------------------------------------------------------------------
/templates/injected/admin_order_comments.html.twig:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/templates/injected/shop_order_comments.html.twig:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/tests/Application/.env:
--------------------------------------------------------------------------------
1 | # This file is a "template" of which env vars needs to be defined in your configuration or in an .env file
2 | # Set variables here that may be different on each deployment target of the app, e.g. development, staging, production.
3 | # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
4 |
5 | ###> symfony/framework-bundle ###
6 | APP_ENV=dev
7 | APP_DEBUG=1
8 | APP_SECRET=EDITME
9 | ###< symfony/framework-bundle ###
10 |
11 | ###> doctrine/doctrine-bundle ###
12 | # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
13 | # For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
14 | # Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls
15 | DATABASE_URL=mysql://root@127.0.0.1/acme_sylius_example_plugin_%kernel.environment%?serverVersion=5.7
16 | ###< doctrine/doctrine-bundle ###
17 |
18 | ###> lexik/jwt-authentication-bundle ###
19 | JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
20 | JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
21 | JWT_PASSPHRASE=order_comments_plugin_development
22 | ###< lexik/jwt-authentication-bundle ###
23 |
24 | ###> symfony/mailer ###
25 | MAILER_DSN=null://null
26 | ###< symfony/mailer ###
27 |
28 | ###> symfony/messenger ###
29 | SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=doctrine://default
30 | SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=doctrine://default?queue_name=main_failed
31 | SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=doctrine://default?queue_name=catalog_promotion_removal
32 | SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=doctrine://default?queue_name=catalog_promotion_removal_failed
33 | ###< symfony/messenger ###
34 |
--------------------------------------------------------------------------------
/tests/Application/.env.test:
--------------------------------------------------------------------------------
1 | APP_SECRET='ch4mb3r0f5ecr3ts'
2 |
3 | KERNEL_CLASS='Tests\Brille24\SyliusOrderCommentsPlugin\Application\Kernel'
4 |
5 | ###> symfony/messenger ###
6 | # Sync transport turned for testing env for the ease of testing
7 | SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=sync://
8 | SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=sync://
9 | SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=sync://
10 | SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=sync://
11 | ###< symfony/messenger ###
12 |
--------------------------------------------------------------------------------
/tests/Application/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'airbnb-base',
3 | env: {
4 | node: true,
5 | },
6 | rules: {
7 | 'object-shorthand': ['error', 'always', {
8 | avoidQuotes: true,
9 | avoidExplicitReturnArrows: true,
10 | }],
11 | 'function-paren-newline': ['error', 'consistent'],
12 | 'max-len': ['warn', 120, 2, {
13 | ignoreUrls: true,
14 | ignoreComments: false,
15 | ignoreRegExpLiterals: true,
16 | ignoreStrings: true,
17 | ignoreTemplateLiterals: true,
18 | }],
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/tests/Application/.gitignore:
--------------------------------------------------------------------------------
1 | /public/assets
2 | /public/build
3 | /public/css
4 | /public/js
5 | /public/media/*
6 | !/public/media/image/
7 | /public/media/image/*
8 | !/public/media/image/.gitignore
9 |
10 | /node_modules
11 |
12 | ###> symfony/framework-bundle ###
13 | /.env.*.local
14 | /.env.local
15 | /.env.local.php
16 | /public/bundles
17 | /var/
18 | /vendor/
19 | ###< symfony/framework-bundle ###
20 |
21 | ###> symfony/web-server-bundle ###
22 | /.web-server-pid
23 | ###< symfony/web-server-bundle ###
24 |
--------------------------------------------------------------------------------
/tests/Application/Kernel.php:
--------------------------------------------------------------------------------
1 | getProjectDir() . '/var/cache/' . $this->environment;
23 | }
24 |
25 | public function getLogDir(): string
26 | {
27 | return $this->getProjectDir() . '/var/log';
28 | }
29 |
30 | public function registerBundles(): iterable
31 | {
32 | foreach ($this->getConfigurationDirectories() as $confDir) {
33 | $bundlesFile = $confDir . '/bundles.php';
34 | if (false === is_file($bundlesFile)) {
35 | continue;
36 | }
37 | yield from $this->registerBundlesFromFile($bundlesFile);
38 | }
39 | }
40 |
41 | protected function configureRoutes(RoutingConfigurator $routes): void
42 | {
43 | foreach ($this->getConfigurationDirectories() as $confDir) {
44 | $this->loadRoutesConfiguration($routes, $confDir);
45 | }
46 | }
47 |
48 | protected function getContainerBaseClass(): string
49 | {
50 | if ($this->isTestEnvironment() && class_exists(MockerContainer::class)) {
51 | return MockerContainer::class;
52 | }
53 |
54 | return parent::getContainerBaseClass();
55 | }
56 |
57 | private function isTestEnvironment(): bool
58 | {
59 | return 0 === strpos($this->getEnvironment(), 'test');
60 | }
61 |
62 | private function loadRoutesConfiguration(RoutingConfigurator $routes, string $confDir): void
63 | {
64 | $routes->import($confDir . '/{routes}/*' . self::CONFIG_EXTS);
65 | $routes->import($confDir . '/{routes}/' . $this->environment . '/**/*' . self::CONFIG_EXTS);
66 | $routes->import($confDir . '/{routes}' . self::CONFIG_EXTS);
67 | }
68 |
69 | /**
70 | * @return BundleInterface[]
71 | */
72 | private function registerBundlesFromFile(string $bundlesFile): iterable
73 | {
74 | $contents = require $bundlesFile;
75 | foreach ($contents as $class => $envs) {
76 | if (isset($envs['all']) || isset($envs[$this->environment])) {
77 | yield new $class();
78 | }
79 | }
80 | }
81 |
82 | /**
83 | * @return string[]
84 | */
85 | private function getConfigurationDirectories(): iterable
86 | {
87 | yield $this->getProjectDir() . '/config';
88 | $syliusConfigDir = $this->getProjectDir() . '/config/sylius/' . SyliusKernel::MAJOR_VERSION . '.' . SyliusKernel::MINOR_VERSION;
89 | if (is_dir($syliusConfigDir)) {
90 | yield $syliusConfigDir;
91 | }
92 | $symfonyConfigDir = $this->getProjectDir() . '/config/symfony/' . BaseKernel::MAJOR_VERSION . '.' . BaseKernel::MINOR_VERSION;
93 | if (is_dir($symfonyConfigDir)) {
94 | yield $symfonyConfigDir;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/tests/Application/assets/admin/entry.js:
--------------------------------------------------------------------------------
1 | import 'sylius/bundle/AdminBundle/Resources/private/entry';
2 |
--------------------------------------------------------------------------------
/tests/Application/assets/shop/entry.js:
--------------------------------------------------------------------------------
1 | import 'sylius/bundle/ShopBundle/Resources/private/entry';
2 |
--------------------------------------------------------------------------------
/tests/Application/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getParameterOption(['--env', '-e'], null, true)) {
19 | putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
20 | }
21 |
22 | if ($input->hasParameterOption('--no-debug', true)) {
23 | putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
24 | }
25 |
26 | require dirname(__DIR__).'/config/bootstrap.php';
27 |
28 | if ($_SERVER['APP_DEBUG']) {
29 | umask(0000);
30 |
31 | if (class_exists(Debug::class)) {
32 | Debug::enable();
33 | }
34 | }
35 |
36 | $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
37 | $application = new Application($kernel);
38 | $application->run($input);
39 |
--------------------------------------------------------------------------------
/tests/Application/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sylius/plugin-skeleton-test-application",
3 | "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)",
4 | "license": "MIT"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Application/config/api_platform/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/api_platform/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | =1.2)
11 | if (is_array($env = @include dirname(__DIR__) . '/.env.local.php')) {
12 | $_SERVER += $env;
13 | $_ENV += $env;
14 | } elseif (!class_exists(Dotenv::class)) {
15 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
16 | } elseif (method_exists(Dotenv::class, 'bootEnv')) {
17 | (new Dotenv())->bootEnv(dirname(__DIR__) . '/.env');
18 |
19 | return;
20 | } else {
21 | // load all the .env files
22 | (new Dotenv(true))->loadEnv(dirname(__DIR__) . '/.env');
23 | }
24 |
25 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
26 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
27 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
28 |
--------------------------------------------------------------------------------
/tests/Application/config/bundles.php:
--------------------------------------------------------------------------------
1 | ['all' => true],
5 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
6 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
7 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
8 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
9 | Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true],
10 | Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true],
11 | Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true],
12 | Sylius\Bundle\LocaleBundle\SyliusLocaleBundle::class => ['all' => true],
13 | Sylius\Bundle\ProductBundle\SyliusProductBundle::class => ['all' => true],
14 | Sylius\Bundle\ChannelBundle\SyliusChannelBundle::class => ['all' => true],
15 | Sylius\Bundle\AttributeBundle\SyliusAttributeBundle::class => ['all' => true],
16 | Sylius\Bundle\TaxationBundle\SyliusTaxationBundle::class => ['all' => true],
17 | Sylius\Bundle\ShippingBundle\SyliusShippingBundle::class => ['all' => true],
18 | Sylius\Bundle\PaymentBundle\SyliusPaymentBundle::class => ['all' => true],
19 | Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true],
20 | Sylius\Bundle\PromotionBundle\SyliusPromotionBundle::class => ['all' => true],
21 | Sylius\Bundle\AddressingBundle\SyliusAddressingBundle::class => ['all' => true],
22 | Sylius\Bundle\InventoryBundle\SyliusInventoryBundle::class => ['all' => true],
23 | Sylius\Bundle\TaxonomyBundle\SyliusTaxonomyBundle::class => ['all' => true],
24 | Sylius\Bundle\UserBundle\SyliusUserBundle::class => ['all' => true],
25 | Sylius\Bundle\CustomerBundle\SyliusCustomerBundle::class => ['all' => true],
26 | Sylius\Bundle\UiBundle\SyliusUiBundle::class => ['all' => true],
27 | Sylius\Bundle\ReviewBundle\SyliusReviewBundle::class => ['all' => true],
28 | Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true],
29 | Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true],
30 | Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true],
31 | winzou\Bundle\StateMachineBundle\winzouStateMachineBundle::class => ['all' => true],
32 | Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true],
33 | Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle::class => ['all' => true],
34 | JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
35 | FOS\RestBundle\FOSRestBundle::class => ['all' => true],
36 | Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true],
37 | Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true],
38 | Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true],
39 | Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true],
40 | Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
41 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
42 | Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true],
43 | Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true],
44 | Sylius\Bundle\ThemeBundle\SyliusThemeBundle::class => ['all' => true],
45 | Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true],
46 | Sylius\Bundle\ShopBundle\SyliusShopBundle::class => ['all' => true],
47 | Brille24\OrderCommentsPlugin\Brille24SyliusOrderCommentsPlugin::class => ['all' => true],
48 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true],
49 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true],
50 | FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true, 'test_cached' => true],
51 | Sylius\Behat\Application\SyliusTestPlugin\SyliusTestPlugin::class => ['test' => true, 'test_cached' => true],
52 | ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
53 | Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
54 | Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true],
55 | SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true],
56 | BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true],
57 | SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true],
58 | Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true],
59 | Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
60 | League\FlysystemBundle\FlysystemBundle::class => ['all' => true],
61 | ];
62 |
--------------------------------------------------------------------------------
/tests/Application/config/jwt/private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN ENCRYPTED PRIVATE KEY-----
2 | MIIJrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIDbthk+aF5EACAggA
3 | MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBA3DYfh2mXByUxFNke/Wf5SBIIJ
4 | UBckIgXeXBWPLQAAq07pN8uNFMUcUirFuEvbmxVe1PupCCAqriNxi1DqeSu/M7c1
5 | h66y0BqKZu/0G9SVTg63iCKDEiRAM3hLyD2CsjYg8h2LAaqQ9dFYGV0cHRhCXagZ
6 | Sdt9YTfn2rarRbxauMSt0z9zwCaiUrBU4JwSM3g+tD7W0lxAm9TeaqBZek5DIX+j
7 | 3Gom5tPYQe8jvfGMGdMPuanoEwH4WbWzGcqypWriy4JwaggwKCQ4ituWfa9kqMMC
8 | 8HRmBBDg0gtafmQP910RZh18JL2ewF5Pl7GDsLtOj5gNLNuAiQxDCcYRnD4/Cdsl
9 | bH91btmGX1nUVIFViUTW93eBsjBgdgqOMRVxUKkSSX6CmIZWlE3AazgwSbvOvNrN
10 | JGa8X21UwfuS/JHLmfRmgdti0YxRjJkBYLPpcd3ILsi+MMhSHy0uycAM/dB80Q1B
11 | vkW1UXGbCw/PzA5yHrzULzAl69E3Tt5nTVMIIcBGxw2rf+ej+AVjsuOl7etwecdC
12 | gnA90ViNlGOACLVnhsjd4WVF9Oircosf0UYoblwcT6gw1GSVF9pWuu7k5hy/7Pt/
13 | o1BvonUgz/4VHG+K58qvtnlto+JE0XWzPvukNUyggtekTLyoQCI3ZKge6ui3qLax
14 | N6whHpzFnFVF3GJAisTk5naHFawHNvH7t85pmc+UnjNUUmyl9RStl9LMYDSBKNlR
15 | LzPlJK27E5SLhhyJCni4+UYjH6PdlJuKXJ0365fufJ+5ajHRatwt039xLnK0W+oa
16 | L35NxCuXrn8YxOgJIomt7IrkV3AuxoWxcx4lRFoM0WCdn9SWZVtfFFiyX/Xr1qDg
17 | dUysw3/bePEkOKr5JWx09hT0OKDpkwLFo2Ljtvjln4EMXYEvvVqFciKw0kqF73Dw
18 | NyoSubwR4qs6FQclKW1TAP6UW4B6ffq1iagKOCTZ5bBtsPBZk8UGCJb57q4fUj4P
19 | nJy0hnSdlOH4Am+US4HF4ayOGuaV1Be1taurdJnt5cNnUYRah0wg4nG+wVdG5HJk
20 | f4dJ4nih9d6WA/8LfxdpB7NCwdR+KK6lky+GgLSdhmIT9lzjj2GDsU4lBf29TkBn
21 | lyt98/LWGrgCQgZAQ/obxLT8CZtY+tNejGoMppY+ub8DIaLBFID+fcz13kgA9x7a
22 | TeVB8RPok+S3yHXP9a4WSFe9DGjjN+m7EnRtte7MEjyMoekXVnT04gNbTMoGAjNb
23 | lrR4g3ICygZtsoGSB2VEu7o3azAspXNBMOuJfRCuC0LDXcjH3TbvjX0da5wHBoK9
24 | clRxu+CDo9A849HMkmSje8wED7ysZnkvSX0OdPjXahVd4t1tDRI6jSlzFo9fGcjp
25 | S8Ikm9iMrHXaWcDdtcq4C63CjSynIBr4mNIxe/f2e9nynm3AIv+aOan891RWHqrd
26 | DdpSSPShtzATI9PbB+b+S0Gw58Y8fpO7yoZ87VW1BMpadmFZ87YY78jdB7BwInNI
27 | JqtnivinM6qCsvbdMoGinUyL6PUcfQGiEAibouKr3zNRDC4aesBZZmj7w0dnf+HK
28 | YC905aR0cddlc6DBo/ed3o9krMcZ6oY/vruemPTc5G7Cg3t4H3mInRgURw22X1wo
29 | FsioU1yOdkK+MYxvmGsQvQuSJhp7h1Uz37t/olkPRafZgy2nEtw6DQO0Dm4UfSsD
30 | nysq6dn1WeZPkOipGBRgQmY1FTRzwPoCxi7+/EuHhD8hr962rHOglSuNqPG89J8r
31 | wdbTDr8kgXj2A9p+jI3TVKEX+h6FEhrCHW9SHUqATOZ7RiNL6hKld9j0U4D9gQwZ
32 | dflA0TxpVsHXm7pd1idkr46jIFgw7HA89Erm0Ty7RolfHkqlRca805AVmsKkviIz
33 | sbF5uv4WzIE3ViO8P1KMUhCyElm72mpyNTXBhkxkup9hJ4fQieaN6pET6dQ2xyjs
34 | SBIvQoXI0JQKpespcyAdoh88ULQjRUXEOaNFfN7q+itTcocwmPZfzW2nXORJT2p8
35 | SXLqSE73nYZdqzSYFq1hLcnlubJ7yPBYYG1fI0IydjSGKfnjtB0DReR32OToRZ7m
36 | laduZ8O+IaBUY4Sp6QdYcVbGGpG/wsPmTQyScc/O2bfSI7AiPnL9EnwebI9sPSWQ
37 | R0t0QMXZOSSqNY6jkYjsOCxeekRIdY6havo2Y52Ywti0QNrkT4BQ+175VVTmRMdy
38 | LNaMFeEq6ehSEdaHaozvjHvP50HQT43tCK+RJiL+Gf9FqawoQRt693yO5LFbQsuw
39 | QsUSMi41txpINMa+HEc2K5FvGoPr7FmajLK7X2fr+3c/yZ4fahoMKEAVFWl5kRYx
40 | Fe1smlw1Vxl/qNQ32LFWsBIK+XnYBteYmlpVyYrTgXyjnp1rK2zz0118DPFuYiAP
41 | O0r6nnBz0NbwnSKb7S4CjxBKDvDbWTzP35Q5L/vySnO2zRbM64Gw7sjeLiJittWS
42 | gQfbFpEk9k8KVndKM4H50Jp0WznmYpm1Tman8hUOiCvmq0qdI3bJ5Bnj0K+q2zFV
43 | +noGpMFdq1+8WaUFLQFGCPM+yJgCqDgT1RAgfsGcomckGcmenDtHaTbcSFabEdpM
44 | Tsa2qLdg/Kju+7JyGrkmobXl/azuyjYTHfRvSZrvO5WUDFzhChrJpIL4nA3ZGRlS
45 | gvy+OzyyBh4sRyHwLItwUwE81aya3W4llAkhQ7OycmqniJgjtJzLwnxv2RQsB8bF
46 | pyoqQdKVxkqHdbUFeh9igI4ffRAK+8xDER5J+RUoZ4mO8qJebxar54XTb6I/Lepc
47 | g8ITX8bJ/GH+M6JdP7tLCikDTSGS+i1ReMQXE5XuEajYOVbzQdyWU5jleZIx0f6X
48 | mTa4WvMEGNyNxKZZXsy9FAaBkZqrNzEv8k0uFgFMNWQcMMtiqbei86yACdqe+jiW
49 | HqHv8wfoBHR+eIARub2itOJ/cI+oKv96d4it4FqQ9Lml8RUFFZj7Hrd6EjDb6Nq4
50 | P9ti7eku/xZvS0saBNChvv44GhP6FZJS0i/gidVffLna7Wua98tPZEAXp57k+XUL
51 | PzsRJ4a+hFuQjkyXFoz/v8YuUdyCFUSVVr9ArVu0v4+4euFWpQLav5sXv0Gh9X58
52 | Ek1KIf7Z/tZAJnSjTjFuSbDX/AoTMTxpRBKKnFW6zY0Nw2pjTVMtTVDkv9xkBpBK
53 | wod7FPD5f0T7y9YOARVZnBxVRSkkcYpEJFy5pLNeadg9
54 | -----END ENCRYPTED PRIVATE KEY-----
55 |
--------------------------------------------------------------------------------
/tests/Application/config/jwt/public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6QkmF/Xi5nAYb8Kzr7qC
3 | d63V2K+d/nCXbpDUKKDPJAqOtTlMoQSuJRLNnhhp7z1i/Cp4Bhifr20Pu2dq8JYg
4 | 6pRT4ctqvYb/MXxAaPZc3EcBC0S6AhgKO/fDvR3LcqYqGJmQQOXZvxTsgqongdvV
5 | 4XbqFBMMgngyayoBk0VKTaI/s+LQhIce+1QaxbAI0+/zbR0hZ1hWT73orJi3do+1
6 | TBzQol+V7WGa8LlJfmgM56qO3BmVkeTDMBc27pGp6g3+Oufk/l29jEGJlUT9yu7Q
7 | BRhaQTWNVASa2aD+AKjVBzJh53O2zD8slAbjF1M9U7bbWN28Sv+xC/dUz0q9HnPu
8 | RsY2tnwryqTyYn/Hf2xyP3/KvjJ6oslAwemu5JirdJkO7KVQAthWG42gLuhZg3ks
9 | cSZhCLZH7nO2UDsf+2ZZgdbhpYZwR4gDRfNt7GKWXnWZOz9Uw1yVCPgylyZRZwg8
10 | l0y9aABdj3379I22icrwpMZbAgkyxNSV6UNJuxZksLUoP3i9OvXYgPYU9E4tU/Ul
11 | Dm/T1rGSReGoPkU1YQnI50bq7p1byIoUu2scTflvpTVI5a7zULkS1tg60xk7vBRC
12 | aBc7nr4UEtA235N6uLtcGxH11WBMwsKX69sSU0sQdC4Sk25zXM2gc8R1XV9K3qz2
13 | wQorQRlCwrkG44VRDgbFH+8CAwEAAQ==
14 | -----END PUBLIC KEY-----
15 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/_sylius.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" }
3 | - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" }
4 | - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" }
5 | - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" }
6 |
7 | - { resource: "@Brille24SyliusOrderCommentsPlugin/config/config.yaml" }
8 |
9 | parameters:
10 | sylius_core.public_dir: '%kernel.project_dir%/public'
11 |
12 | sylius_api:
13 | enabled: true
14 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/api_platform.yaml:
--------------------------------------------------------------------------------
1 | api_platform:
2 | mapping:
3 | paths:
4 | - '%kernel.project_dir%/../../vendor/sylius/sylius/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources'
5 | - '%kernel.project_dir%/config/api_platform'
6 | patch_formats:
7 | json: ['application/merge-patch+json']
8 | swagger:
9 | versions: [3]
10 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/assets.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | assets:
3 | packages:
4 | shop:
5 | json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json'
6 | admin:
7 | json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json'
8 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | profiler: { only_exceptions: false }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/jms_serializer.yaml:
--------------------------------------------------------------------------------
1 | jms_serializer:
2 | visitors:
3 | json_serialization:
4 | options:
5 | - JSON_PRETTY_PRINT
6 | - JSON_UNESCAPED_SLASHES
7 | - JSON_PRESERVE_ZERO_FRACTION
8 | json_deserialization:
9 | options:
10 | - JSON_PRETTY_PRINT
11 | - JSON_UNESCAPED_SLASHES
12 | - JSON_PRESERVE_ZERO_FRACTION
13 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: debug
7 | firephp:
8 | type: firephp
9 | level: info
10 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: true
3 | intercept_redirects: false
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Adds a fallback DATABASE_URL if the env var is not set.
3 | # This allows you to run cache:warmup even if your
4 | # environment variables are not available yet.
5 | # You should not need to change this value.
6 | env(DATABASE_URL): ''
7 |
8 | doctrine:
9 | dbal:
10 | url: '%env(resolve:DATABASE_URL)%'
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | storage:
3 | table_storage:
4 | table_name: sylius_migrations
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/fos_rest.yaml:
--------------------------------------------------------------------------------
1 | fos_rest:
2 | exception: true
3 | view:
4 | formats:
5 | json: true
6 | xml: true
7 | empty_content: 204
8 | format_listener:
9 | rules:
10 | - { path: '^/api/v1/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true }
11 | - { path: '^/', stop: true }
12 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | secret: '%env(APP_SECRET)%'
3 | form: true
4 | csrf_protection: true
5 | session:
6 | handler_id: ~
7 | serializer:
8 | mapping:
9 | paths: [ '%kernel.project_dir%/config/serialization' ]
10 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/jms_serializer.yaml:
--------------------------------------------------------------------------------
1 | jms_serializer:
2 | visitors:
3 | xml_serialization:
4 | format_output: '%kernel.debug%'
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/lexik_jwt_authentication.yaml:
--------------------------------------------------------------------------------
1 | lexik_jwt_authentication:
2 | secret_key: '%env(resolve:JWT_SECRET_KEY)%'
3 | public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
4 | pass_phrase: '%env(JWT_PASSPHRASE)%'
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/liip_imagine.yaml:
--------------------------------------------------------------------------------
1 | liip_imagine:
2 | resolvers:
3 | default:
4 | web_path:
5 | web_root: "%kernel.project_dir%/public"
6 | cache_prefix: "media/cache"
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/mailer.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | mailer:
3 | dsn: '%env(MAILER_DSN)%'
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | metadata_cache_driver:
4 | type: service
5 | id: doctrine.system_cache_provider
6 | query_cache_driver:
7 | type: service
8 | id: doctrine.system_cache_provider
9 | result_cache_driver:
10 | type: service
11 | id: doctrine.result_cache_provider
12 |
13 | services:
14 | doctrine.result_cache_provider:
15 | class: Symfony\Component\Cache\DoctrineProvider
16 | public: false
17 | arguments:
18 | - '@doctrine.result_cache_pool'
19 | doctrine.system_cache_provider:
20 | class: Symfony\Component\Cache\DoctrineProvider
21 | public: false
22 | arguments:
23 | - '@doctrine.system_cache_pool'
24 |
25 | framework:
26 | cache:
27 | pools:
28 | doctrine.result_cache_pool:
29 | adapter: cache.app
30 | doctrine.system_cache_pool:
31 | adapter: cache.system
32 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/prod/jms_serializer.yaml:
--------------------------------------------------------------------------------
1 | jms_serializer:
2 | visitors:
3 | json_serialization:
4 | options:
5 | - JSON_UNESCAPED_SLASHES
6 | - JSON_PRESERVE_ZERO_FRACTION
7 | json_deserialization:
8 | options:
9 | - JSON_UNESCAPED_SLASHES
10 | - JSON_PRESERVE_ZERO_FRACTION
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/prod/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | nested:
8 | type: stream
9 | path: "%kernel.logs_dir%/%kernel.environment%.log"
10 | level: debug
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/security.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | enable_authenticator_manager: true
3 | providers:
4 | sylius_admin_user_provider:
5 | id: sylius.admin_user_provider.email_or_name_based
6 | sylius_api_admin_user_provider:
7 | id: sylius.admin_user_provider.email_or_name_based
8 | sylius_shop_user_provider:
9 | id: sylius.shop_user_provider.email_or_name_based
10 | sylius_api_shop_user_provider:
11 | id: sylius.shop_user_provider.email_or_name_based
12 |
13 | password_hashers:
14 | Sylius\Component\User\Model\UserInterface: argon2i
15 | firewalls:
16 | admin:
17 | switch_user: true
18 | context: admin
19 | pattern: "%sylius.security.admin_regex%"
20 | provider: sylius_admin_user_provider
21 | form_login:
22 | provider: sylius_admin_user_provider
23 | login_path: sylius_admin_login
24 | check_path: sylius_admin_login_check
25 | failure_path: sylius_admin_login
26 | default_target_path: sylius_admin_dashboard
27 | use_forward: false
28 | use_referer: true
29 | enable_csrf: true
30 | csrf_parameter: _csrf_admin_security_token
31 | csrf_token_id: admin_authenticate
32 | remember_me:
33 | secret: "%env(APP_SECRET)%"
34 | path: "/%sylius_admin.path_name%"
35 | name: APP_ADMIN_REMEMBER_ME
36 | lifetime: 31536000
37 | remember_me_parameter: _remember_me
38 | logout:
39 | path: sylius_admin_logout
40 | target: sylius_admin_login
41 |
42 | new_api_admin_user:
43 | pattern: "%sylius.security.new_api_admin_regex%/.*"
44 | provider: sylius_api_admin_user_provider
45 | stateless: true
46 | entry_point: jwt
47 | json_login:
48 | check_path: "%sylius.security.new_api_admin_route%/authentication-token"
49 | username_path: email
50 | password_path: password
51 | success_handler: lexik_jwt_authentication.handler.authentication_success
52 | failure_handler: lexik_jwt_authentication.handler.authentication_failure
53 | jwt: true
54 |
55 | new_api_shop_user:
56 | pattern: "%sylius.security.new_api_shop_regex%/.*"
57 | provider: sylius_api_shop_user_provider
58 | stateless: true
59 | entry_point: jwt
60 | json_login:
61 | check_path: "%sylius.security.new_api_shop_route%/authentication-token"
62 | username_path: email
63 | password_path: password
64 | success_handler: lexik_jwt_authentication.handler.authentication_success
65 | failure_handler: lexik_jwt_authentication.handler.authentication_failure
66 | jwt: true
67 |
68 | shop:
69 | switch_user: { role: ROLE_ALLOWED_TO_SWITCH }
70 | context: shop
71 | pattern: "%sylius.security.shop_regex%"
72 | provider: sylius_shop_user_provider
73 | form_login:
74 | success_handler: sylius.authentication.success_handler
75 | failure_handler: sylius.authentication.failure_handler
76 | provider: sylius_shop_user_provider
77 | login_path: sylius_shop_login
78 | check_path: sylius_shop_login_check
79 | failure_path: sylius_shop_login
80 | default_target_path: sylius_shop_homepage
81 | use_forward: false
82 | use_referer: true
83 | enable_csrf: true
84 | csrf_parameter: _csrf_shop_security_token
85 | csrf_token_id: shop_authenticate
86 | remember_me:
87 | secret: "%env(APP_SECRET)%"
88 | name: APP_SHOP_REMEMBER_ME
89 | lifetime: 31536000
90 | remember_me_parameter: _remember_me
91 | logout:
92 | path: sylius_shop_logout
93 | target: sylius_shop_homepage
94 | invalidate_session: false
95 |
96 | dev:
97 | pattern: ^/(_(profiler|wdt)|css|images|js)/
98 | security: false
99 |
100 | image_resolver:
101 | pattern: ^/media/cache/resolve
102 | security: false
103 |
104 | access_control:
105 | - { path: "%sylius.security.admin_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] }
106 | - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS }
107 | - { path: "%sylius.security.shop_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] }
108 | - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS }
109 |
110 | - { path: "%sylius.security.admin_regex%/login", role: PUBLIC_ACCESS }
111 | - { path: "%sylius.security.shop_regex%/login", role: PUBLIC_ACCESS }
112 |
113 | - { path: "%sylius.security.shop_regex%/register", role: PUBLIC_ACCESS }
114 | - { path: "%sylius.security.shop_regex%/verify", role: PUBLIC_ACCESS }
115 |
116 | - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS }
117 | - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER }
118 |
119 | - { path: "%sylius.security.new_api_admin_route%/reset-password-requests", role: PUBLIC_ACCESS }
120 | - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS }
121 | - { path: "%sylius.security.new_api_admin_route%/authentication-token", role: PUBLIC_ACCESS }
122 | - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER }
123 | - { path: "%sylius.security.new_api_shop_route%/authentication-token", role: PUBLIC_ACCESS }
124 | - { path: "%sylius.security.new_api_shop_regex%/.*", role: PUBLIC_ACCESS }
125 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/staging/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | nested:
8 | type: stream
9 | path: "%kernel.logs_dir%/%kernel.environment%.log"
10 | level: debug
11 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/stof_doctrine_extensions.yaml:
--------------------------------------------------------------------------------
1 | # Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
2 | # See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/
3 | stof_doctrine_extensions:
4 | default_locale: '%locale%'
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: ~
3 | session:
4 | storage_factory_id: session.storage.factory.mock_file
5 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/mailer.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | pools:
4 | test.mailer_pool:
5 | adapter: cache.adapter.filesystem
6 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: error
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/security.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | password_hashers:
3 | Sylius\Component\User\Model\UserInterface:
4 | algorithm: argon2i
5 | time_cost: 3
6 | memory_cost: 10
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/sylius_theme.yaml:
--------------------------------------------------------------------------------
1 | sylius_theme:
2 | sources:
3 | test: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/sylius_uploader.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | Sylius\Component\Core\Generator\ImagePathGeneratorInterface:
3 | class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: false
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { collect: false }
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | entity_managers:
4 | default:
5 | result_cache_driver:
6 | type: memcached
7 | host: localhost
8 | port: 11211
9 | query_cache_driver:
10 | type: memcached
11 | host: localhost
12 | port: 11211
13 | metadata_cache_driver:
14 | type: memcached
15 | host: localhost
16 | port: 11211
17 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/fos_rest.yaml:
--------------------------------------------------------------------------------
1 | fos_rest:
2 | exception:
3 | debug: true
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/framework.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: ../test/framework.yaml }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/mailer.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "../test/mailer.yaml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: error
7 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/security.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: ../test/security.yaml }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_channel.yaml:
--------------------------------------------------------------------------------
1 | sylius_channel:
2 | debug: true
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_theme.yaml:
--------------------------------------------------------------------------------
1 | sylius_theme:
2 | sources:
3 | test: ~
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/sylius_uploader.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "../test/sylius_uploader.yaml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/test_cached/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | strict_variables: true
3 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/translation.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | default_locale: '%locale%'
3 | translator:
4 | paths:
5 | - '%kernel.project_dir%/translations'
6 | fallbacks:
7 | - '%locale%'
8 | - 'en'
9 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | paths: ['%kernel.project_dir%/templates']
3 | debug: '%kernel.debug%'
4 | strict_variables: '%kernel.debug%'
5 |
6 | services:
7 | _defaults:
8 | public: false
9 | autowire: true
10 | autoconfigure: true
11 |
12 | Twig\Extra\Intl\IntlExtension: ~
13 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | enable_annotations: true
4 |
--------------------------------------------------------------------------------
/tests/Application/config/packages/webpack_encore.yaml:
--------------------------------------------------------------------------------
1 | webpack_encore:
2 | output_path: '%kernel.project_dir%/public/build/default'
3 | builds:
4 | shop: '%kernel.project_dir%/public/build/shop'
5 | admin: '%kernel.project_dir%/public/build/admin'
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes.yaml:
--------------------------------------------------------------------------------
1 | brille24_sylius_order_comments_plugin_admin:
2 | resource: "@Brille24SyliusOrderCommentsPlugin/config/admin_routing.yaml"
3 |
4 | brille24_sylius_order_comments_plugin_shop:
5 | resource: "@Brille24SyliusOrderCommentsPlugin/config/shop_routing.yaml"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | _wdt:
2 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
3 | prefix: /_wdt
4 |
5 | _profiler:
6 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
7 | prefix: /_profiler
8 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/liip_imagine.yaml:
--------------------------------------------------------------------------------
1 | _liip_imagine:
2 | resource: "@LiipImagineBundle/Resources/config/routing.yaml"
3 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_admin.yaml:
--------------------------------------------------------------------------------
1 | sylius_admin:
2 | resource: "@SyliusAdminBundle/Resources/config/routing.yml"
3 | prefix: /admin
4 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_api.yaml:
--------------------------------------------------------------------------------
1 | sylius_api:
2 | resource: "@SyliusApiBundle/Resources/config/routing.yml"
3 | prefix: "%sylius.security.new_api_route%"
4 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/sylius_shop.yaml:
--------------------------------------------------------------------------------
1 | sylius_shop:
2 | resource: "@SyliusShopBundle/Resources/config/routing.yml"
3 | prefix: /{_locale}
4 | requirements:
5 | _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$
6 |
7 | sylius_shop_payum:
8 | resource: "@SyliusShopBundle/Resources/config/routing/payum.yml"
9 |
10 | sylius_shop_default_locale:
11 | path: /
12 | methods: [GET]
13 | defaults:
14 | _controller: sylius.controller.shop.locale_switch:switchAction
15 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test/routing.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test/sylius_test_plugin.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test_cached/routing.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/routes/test_cached/sylius_test_plugin.yaml:
--------------------------------------------------------------------------------
1 | sylius_test_plugin_main:
2 | path: /test/main
3 | controller: FrameworkBundle:Template:template
4 | defaults:
5 | template: "@SyliusTestPlugin/main.html.twig"
6 |
--------------------------------------------------------------------------------
/tests/Application/config/secrets/dev/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/secrets/dev/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/prod/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/secrets/prod/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/test/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/secrets/test/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/secrets/test_cached/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/secrets/test_cached/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/serialization/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/config/serialization/.gitignore
--------------------------------------------------------------------------------
/tests/Application/config/services.yaml:
--------------------------------------------------------------------------------
1 | # Put parameters here that don't need to change on each machine where the app is deployed
2 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
3 | parameters:
4 | locale: en_US
5 |
--------------------------------------------------------------------------------
/tests/Application/config/services_test.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "../../Behat/Resources/services.xml" }
3 | - { resource: "../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" }
4 |
5 | # workaround needed for strange "test.client.history" problem
6 | # see https://github.com/FriendsOfBehat/SymfonyExtension/issues/88
7 | services:
8 | Symfony\Component\BrowserKit\AbstractBrowser: '@test.client'
9 |
--------------------------------------------------------------------------------
/tests/Application/config/services_test_cached.yaml:
--------------------------------------------------------------------------------
1 | imports:
2 | - { resource: "services_test.yaml" }
3 |
--------------------------------------------------------------------------------
/tests/Application/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@babel/polyfill": "^7.0.0",
4 | "chart.js": "^3.7.1",
5 | "jquery": "^3.5.0",
6 | "jquery.dirtyforms": "^2.0.0",
7 | "lightbox2": "^2.9.0",
8 | "semantic-ui-css": "^2.2.0",
9 | "slick-carousel": "^1.8.1"
10 | },
11 | "devDependencies": {
12 | "@babel/core": "^7.0.0",
13 | "@babel/plugin-external-helpers": "^7.0.0",
14 | "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
15 | "@babel/preset-env": "^7.18.10",
16 | "@babel/register": "^7.0.0",
17 | "@rollup/plugin-babel": "^5.3.1",
18 | "@rollup/plugin-commonjs": "^22.0.2",
19 | "@rollup/plugin-inject": "^4.0.4",
20 | "@rollup/plugin-node-resolve": "^13.3.0",
21 | "@semantic-ui-react/css-patch": "^1.1.2",
22 | "@symfony/webpack-encore": "^3.1.0",
23 | "babel-plugin-fast-async": "^6.1.2",
24 | "babel-plugin-module-resolver": "^4.1.0",
25 | "dedent": "^0.7.0",
26 | "eslint": "^8.23.0",
27 | "eslint-config-airbnb-base": "^15.0.0",
28 | "eslint-import-resolver-babel-module": "^5.3.1",
29 | "eslint-plugin-import": "^2.26.0",
30 | "fast-async": "^6.3.8",
31 | "gulp": "^4.0.2",
32 | "gulp-chug": "^0.5.1",
33 | "gulp-concat": "^2.6.1",
34 | "gulp-debug": "^4.0.0",
35 | "gulp-if": "^3.0.0",
36 | "gulp-livereload": "^4.0.2",
37 | "gulp-order": "^1.2.0",
38 | "gulp-sass": "^5.1.0",
39 | "gulp-sourcemaps": "^3.0.0",
40 | "gulp-uglifycss": "^1.1.0",
41 | "merge-stream": "^2.0.0",
42 | "rollup": "^2.79.0",
43 | "rollup-plugin-terser": "^7.0.2",
44 | "sass": "^1.54.8",
45 | "sass-loader": "^13.0.0",
46 | "upath": "^2.0.1",
47 | "yargs": "^17.5.1"
48 | },
49 | "engines": {
50 | "node": "^14 || ^16 || ^18"
51 | },
52 | "engineStrict": true,
53 | "scripts": {
54 | "watch": "encore dev --watch",
55 | "build": "encore dev",
56 | "build:prod": "encore production",
57 | "gulp": "gulp build",
58 | "lint": "yarn lint:js",
59 | "lint:js": "eslint gulpfile.babel.js src/Sylius/Bundle/AdminBundle/gulpfile.babel.js src/Sylius/Bundle/ShopBundle/gulpfile.babel.js src/Sylius/Bundle/UiBundle/Resources/private/js src/Sylius/Bundle/AdminBundle/Resources/private/js src/Sylius/Bundle/ShopBundle/Resources/private/js",
60 | "postinstall": "semantic-ui-css-patch"
61 | },
62 | "repository": {
63 | "type": "git",
64 | "url": "git+https://github.com/Sylius/Sylius.git"
65 | },
66 | "author": "Paweł Jędrzejewski",
67 | "license": "MIT"
68 | }
69 |
--------------------------------------------------------------------------------
/tests/Application/public/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex app.php
2 |
3 |
4 | RewriteEngine On
5 |
6 | RewriteCond %{HTTP:Authorization} ^(.*)
7 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
8 |
9 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
10 | RewriteRule ^(.*) - [E=BASE:%1]
11 |
12 | RewriteCond %{ENV:REDIRECT_STATUS} ^$
13 | RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
14 |
15 | RewriteCond %{REQUEST_FILENAME} -f
16 | RewriteRule .? - [L]
17 |
18 | RewriteRule .? %{ENV:BASE}/index.php [L]
19 |
20 |
21 |
22 |
23 | RedirectMatch 302 ^/$ /index.php/
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/Application/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/public/favicon.ico
--------------------------------------------------------------------------------
/tests/Application/public/index.php:
--------------------------------------------------------------------------------
1 | handle($request);
28 | $response->send();
29 | $kernel->terminate($request, $response);
30 |
--------------------------------------------------------------------------------
/tests/Application/public/robots.txt:
--------------------------------------------------------------------------------
1 | # www.robotstxt.org/
2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
3 |
4 | User-agent: *
5 |
--------------------------------------------------------------------------------
/tests/Application/templates/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/templates/.gitignore
--------------------------------------------------------------------------------
/tests/Application/translations/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Application/translations/.gitignore
--------------------------------------------------------------------------------
/tests/Application/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const Encore = require('@symfony/webpack-encore');
3 |
4 | const syliusBundles = path.resolve(__dirname, '../../vendor/sylius/sylius/src/Sylius/Bundle/');
5 | const uiBundleScripts = path.resolve(syliusBundles, 'UiBundle/Resources/private/js/');
6 | const uiBundleResources = path.resolve(syliusBundles, 'UiBundle/Resources/private/');
7 |
8 | // Shop config
9 | Encore
10 | .setOutputPath('public/build/shop/')
11 | .setPublicPath('/build/shop')
12 | .addEntry('shop-entry', './assets/shop/entry.js')
13 | .disableSingleRuntimeChunk()
14 | .cleanupOutputBeforeBuild()
15 | .enableSourceMaps(!Encore.isProduction())
16 | .enableVersioning(Encore.isProduction())
17 | .enableSassLoader();
18 |
19 | const shopConfig = Encore.getWebpackConfig();
20 |
21 | shopConfig.resolve.alias['sylius/ui'] = uiBundleScripts;
22 | shopConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources;
23 | shopConfig.resolve.alias['sylius/bundle'] = syliusBundles;
24 | shopConfig.resolve.alias['chart.js/dist/Chart.min'] = path.resolve(__dirname, 'node_modules/chart.js/dist/chart.min.js');
25 | shopConfig.name = 'shop';
26 |
27 | Encore.reset();
28 |
29 | // Admin config
30 | Encore
31 | .setOutputPath('public/build/admin/')
32 | .setPublicPath('/build/admin')
33 | .addEntry('admin-entry', './assets/admin/entry.js')
34 | .disableSingleRuntimeChunk()
35 | .cleanupOutputBeforeBuild()
36 | .enableSourceMaps(!Encore.isProduction())
37 | .enableVersioning(Encore.isProduction())
38 | .enableSassLoader();
39 |
40 | const adminConfig = Encore.getWebpackConfig();
41 |
42 | adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts;
43 | adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources;
44 | adminConfig.resolve.alias['sylius/bundle'] = syliusBundles;
45 | adminConfig.resolve.alias['chart.js/dist/Chart.min'] = path.resolve(__dirname, 'node_modules/chart.js/dist/chart.min.js');
46 | adminConfig.externals = Object.assign({}, adminConfig.externals, { window: 'window', document: 'document' });
47 | adminConfig.name = 'admin';
48 |
49 | module.exports = [shopConfig, adminConfig];
50 |
--------------------------------------------------------------------------------
/tests/Behat/Context/Application/AdministratorOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | sharedStorage->get('administrator');
38 |
39 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $user->getEmail(), $message, true));
40 | }
41 |
42 | /**
43 | * @Given I have commented the order :order with :message with the notify customer checkbox disabled
44 | * @When I comment the order :order with :message with the notify customer checkbox disabled
45 | */
46 | public function iCommentTheOrderWithMessageAndCheckboxDisabled(OrderInterface $order, string $message): void
47 | {
48 | /** @var AdminUserInterface $user */
49 | $user = $this->sharedStorage->get('administrator');
50 |
51 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $user->getEmail(), $message, false));
52 | }
53 |
54 | /**
55 | * @Then /^(this order) should have a comment with "([^"]+)" from this administrator$/
56 | */
57 | public function thisOrderShouldHaveACommentWithFromThisAdministrator(OrderInterface $order, string $message): void
58 | {
59 | /** @var Comment $comment */
60 | $comment = $this->orderCommentRepository->findOneBy(['order' => $order]);
61 |
62 | /** @var AdminUserInterface $user */
63 | $user = $this->sharedStorage->get('administrator');
64 |
65 | Assert::notNull($comment, 'This order does not have any comments.');
66 | if (
67 | $comment->message() !== $message ||
68 | $comment->order() !== $order ||
69 | $comment->authorEmail() != $user->getEmail() ||
70 | !$comment->createdAt() instanceof \DateTimeInterface
71 | ) {
72 | throw new \RuntimeException(
73 | sprintf(
74 | 'There are no order comment with the "%s" message for the "%s" order from the "%s" administrator',
75 | $message, $order->getNumber(), $user->getEmail()
76 | ));
77 | }
78 | }
79 |
80 | /**
81 | * @When I try to comment the order :order with an empty message
82 | */
83 | public function iTryToCommentTheOrderWithAnEmptyMessage(OrderInterface $order): void
84 | {
85 | try {
86 | $this->iCommentTheOrderWithMessageAndCheckboxEnabled($order, '');
87 | } catch (HandlerFailedException $exception) {
88 | $innerException = $exception->getPrevious();
89 | if (!($innerException instanceof \DomainException)) {
90 | throw $exception;
91 | }
92 |
93 | $this->sharedStorage->set('exception', $innerException);
94 | }
95 | }
96 |
97 | /**
98 | * @Then I should be notified that comment is invalid
99 | */
100 | public function iShouldBeNotifiedThatCommentIsInvalid(): void
101 | {
102 | Assert::isInstanceOf($this->sharedStorage->get('exception'), \DomainException::class);
103 | }
104 |
105 | /**
106 | * @Then /^(this order) should not have any comments$/
107 | * @Then the order :order should not have any comments
108 | */
109 | public function thisOrderShouldNotHaveAnyComments(OrderInterface $order): void
110 | {
111 | $comments = $this->orderCommentRepository->findBy(['order' => $order]);
112 |
113 | Assert::isEmpty($comments, sprintf('This order should not have any comment, but %d found', count($comments)));
114 | }
115 |
116 | /**
117 | * @Then the notification email should be sent to the customer about :message comment
118 | */
119 | public function theNotificationEmailShouldBeSentToTheCustomerAboutComment(string $message): void
120 | {
121 | /** @var ShopUserInterface $user */
122 | $user = $this->sharedStorage->get('user');
123 | Assert::true($this->emailChecker->hasMessageTo($message, $user->getEmail()));
124 | }
125 |
126 | /**
127 | * @Then the notification email should not be sent to the customer about :message comment
128 | */
129 | public function theNotificationEmailShouldNotBeSentToTheCustomerAboutComment(string $message): void
130 | {
131 | /** @var ShopUserInterface $user */
132 | $user = $this->sharedStorage->get('user');
133 | Assert::false($this->emailChecker->hasMessageTo($message, $user->getEmail()));
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/tests/Behat/Context/Application/CustomerOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | sharedStorage->get('user');
39 |
40 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $user->getEmail(), $message, true));
41 | }
42 |
43 | /**
44 | * @When I comment the order :order with :message and :fileName file
45 | */
46 | public function iCommentTheOrderWithMessageAndFile(Orderinterface $order, string $message, string $fileName): void
47 | {
48 | /** @var ShopUserInterface $user */
49 | $user = $this->sharedStorage->get('user');
50 | $originalFilePath = __DIR__ . '/../../../Comments/Infrastructure/Form/Type/' . $fileName;
51 |
52 | // Copy the file, because the handler will move it.
53 | $filePath = $originalFilePath.'.bkp';
54 | copy($originalFilePath, $filePath);
55 |
56 | $file = new UploadedFile($filePath, $filePath, null, null, true);
57 |
58 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $user->getEmail(), $message, true, $file));
59 | }
60 |
61 | /**
62 | * @When I try to comment the order :order with an empty message
63 | */
64 | public function aCustomerTryToCommentsTheOrderWithEmptyMessage(OrderInterface $order): void
65 | {
66 | /** @var ShopUserInterface $user */
67 | $user = $this->sharedStorage->get('user');
68 | try {
69 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $user->getEmail(), '', true));
70 | } catch (HandlerFailedException $exception) {
71 | $innerException = $exception->getPrevious();
72 | if (!($innerException instanceof \DomainException)) {
73 | throw $exception;
74 | }
75 |
76 | $this->sharedStorage->set('exception', $innerException);
77 | }
78 | }
79 |
80 | /**
81 | * @When a customer with email :email try to comment an order :order
82 | */
83 | public function aCustomerWithEmailTryToCommentAnOrder(string $email, OrderInterface $order): void
84 | {
85 | try {
86 | $this->commandBus->dispatch(CommentOrder::create($order->getNumber(), $email, 'Hello', true));
87 | } catch (HandlerFailedException $exception) {
88 | $innerException = $exception->getPrevious();
89 | if (!($innerException instanceof \DomainException)) {
90 | throw $exception;
91 | }
92 |
93 | $this->sharedStorage->set('exception', $innerException);
94 | }
95 | }
96 |
97 | /**
98 | * @When I try to comment a not existing order with :message
99 | */
100 | public function iTryToCommentAnNotExistingOrderWith(string $message): void
101 | {
102 | /** @var ShopUserInterface $user */
103 | $user = $this->sharedStorage->get('user');
104 | try {
105 | $this->commandBus->dispatch(CommentOrder::create('#0003', $user->getEmail(), $message, true));
106 | } catch (HandlerFailedException $exception) {
107 | $innerException = $exception->getPrevious();
108 | if (!($innerException instanceof \DomainException)) {
109 | throw $exception;
110 | }
111 |
112 | $this->sharedStorage->set('exception', $innerException);
113 | }
114 | }
115 |
116 | /**
117 | * @Then /^(this order) should have a comment with "([^"]+)" from this customer$/
118 | */
119 | public function thisOrderShouldHaveCommentWithFromThisCustomer(OrderInterface $order, string $message): void
120 | {
121 | /** @var Comment $comment */
122 | $comment = $this->orderCommentRepository->findOneBy(['order' => $order]);
123 |
124 | /** @var ShopUserInterface $user */
125 | $user = $this->sharedStorage->get('user');
126 |
127 | Assert::notNull($comment, 'This order does not have any comments.');
128 | if (
129 | $comment->message() !== $message ||
130 | $comment->order() !== $order ||
131 | $comment->authorEmail() != $user->getEmail() ||
132 | !$comment->createdAt() instanceof \DateTimeInterface
133 | ) {
134 | throw new \RuntimeException(
135 | sprintf(
136 | 'There are no order comment with this message "%s" for this order "%s" from this customer "%s"',
137 | $message,
138 | $order->getNumber(),
139 | $user->getEmail()
140 | )
141 | );
142 | }
143 | }
144 |
145 | /**
146 | * @Then I should be notified that comment is invalid
147 | */
148 | public function thisOrderShouldNotHaveEmptyCommentFromThisCustomer(): void
149 | {
150 | Assert::isInstanceOf($this->sharedStorage->get('exception'), \DomainException::class);
151 | }
152 |
153 | /**
154 | * @Then /^(this order) should not have any comments$/
155 | * @Then the order :order should not have any comments
156 | */
157 | public function thisOrderShouldNotHaveAnyComments(OrderInterface $order): void
158 | {
159 | $comments = $this->orderCommentRepository->findBy(['order' => $order]);
160 |
161 | Assert::isEmpty($comments, sprintf('This order should not have any comment, but %d found', count($comments)));
162 | }
163 |
164 | /**
165 | * @Then the notification email should be sent to the administrator about :message comment
166 | */
167 | public function theNotificationEmailShouldBeSentToTheAdministratorAboutComment(string $message): void
168 | {
169 | /** @var ChannelInterface $channel */
170 | $channel = $this->sharedStorage->get('channel');
171 | Assert::true($this->emailChecker->hasMessageTo($message, $channel->getContactEmail()));
172 | }
173 |
174 | /**
175 | * @Then /^(this order) should have a comment with "([^"]+)" and file "([^"]+)" from this customer$/
176 | */
177 | public function thisOrderShouldHaveACommentWithAndFileFromThisCustomer(Orderinterface $order, string $message, string $fileName): void
178 | {
179 | /** @var Comment $comment */
180 | $comment = $this->orderCommentRepository->findOneBy(['order' => $order]);
181 |
182 | /** @var ShopUserInterface $user */
183 | $user = $this->sharedStorage->get('user');
184 |
185 | Assert::notNull($comment, 'This order does not have any comments.');
186 | if (
187 | $comment->message() !== $message ||
188 | $comment->order() !== $order ||
189 | $comment->authorEmail() != $user->getEmail() ||
190 | !$comment->createdAt() instanceof \DateTimeInterface
191 | ) {
192 | throw new \RuntimeException(
193 | sprintf(
194 | 'There are no order comment with this message "%s" for this order "%s" from this customer "%s"',
195 | $message,
196 | $order->getNumber(),
197 | $user->getEmail()
198 | )
199 | );
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/tests/Behat/Context/Common/ChannelContext.php:
--------------------------------------------------------------------------------
1 | entityManager = $entityManager;
19 | }
20 |
21 | /**
22 | * @Given /^(this channel) has "([^"]+)" as a contact email$/
23 | */
24 | public function thisChannelHasAsAContactEmail(ChannelInterface $channel, string $contactEmail): void
25 | {
26 | $channel->setContactEmail($contactEmail);
27 |
28 | $this->entityManager->persist($channel);
29 | $this->entityManager->flush();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Behat/Context/Domain/AdministratorOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | commentOrder($order, $message, true);
31 | }
32 |
33 | /**
34 | * @When I comment the order :order with :message with the notify customer checkbox disabled
35 | */
36 | public function iCommentTheOrderWithMessageAndCheckboxDisabled(OrderInterface $order, string $message): void
37 | {
38 | $this->commentOrder($order, $message, false);
39 | }
40 |
41 | /**
42 | * @When I try to comment the order :order with an empty message
43 | */
44 | public function iTryToCommentTheOrderWith(OrderInterface $order): void
45 | {
46 | try {
47 | $this->iCommentTheOrderWithMessageAndCheckboxEnabled($order, '');
48 | } catch (\DomainException $exception) {
49 | $this->sharedStorage->set('exception', $exception);
50 | }
51 | }
52 |
53 | /**
54 | * @Then /^(this order) should have a comment with "([^"]+)" from this administrator$/
55 | */
56 | public function thisOrderShouldHaveCommentWithFromThisAdministrator(OrderInterface $order, string $message): void
57 | {
58 | /** @var AdminUserInterface $user */
59 | $user = $this->sharedStorage->get('administrator');
60 | /** @var Comment $comment */
61 | $comment = $this->sharedStorage->get('comment');
62 |
63 | if (
64 | $comment->message() !== $message ||
65 | $comment->order() !== $order ||
66 | $comment->authorEmail() != $user->getEmail() ||
67 | !$comment->createdAt() instanceof \DateTimeInterface
68 | ) {
69 | throw new \InvalidArgumentException(
70 | sprintf(
71 | 'There are no order comment with the "%s" message for the "%s" order from the "%s" customer',
72 | $message, $order->getNumber(), $user->getEmail()
73 | ));
74 | }
75 | }
76 |
77 | /**
78 | * Creates a new comment and sets it into the shared storage.
79 | * @param OrderInterface $order
80 | * @param string $message
81 | * @param bool $notifyCustomer
82 | */
83 | private function commentOrder(OrderInterface $order, string $message, bool $notifyCustomer): void
84 | {
85 | /** @var AdminUserInterface $user */
86 | $user = $this->sharedStorage->get('administrator');
87 | $comment = new Comment($order, $user->getEmail(), $message, $notifyCustomer);
88 |
89 | $this->eventDispatcher->dispatch(OrderCommented::occur(
90 | $comment->getId(),
91 | $comment->order(),
92 | $comment->authorEmail(),
93 | $comment->message(),
94 | $comment->notifyCustomer(),
95 | $comment->createdAt(),
96 | $comment->attachedFile()
97 | ));
98 |
99 | $this->sharedStorage->set('comment', $comment);
100 | }
101 |
102 | /**
103 | * @Then I should be notified that comment is invalid
104 | */
105 | public function iShouldBeNotifiedThatCommentIsInvalid(): void
106 | {
107 | Assert::isInstanceOf($this->sharedStorage->get('exception'), \DomainException::class);
108 | }
109 |
110 | /**
111 | * @Then this order should not have any comments
112 | */
113 | public function thisOrderShouldNotHaveAnyComments()
114 | {
115 | Assert::false($this->sharedStorage->has('comment'), 'At least one comment has been saved in shared storage, but none should');
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/tests/Behat/Context/Domain/CustomerOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | commentOrder($order, $message, true);
32 | }
33 |
34 | /**
35 | * @When I comment the order :order with :message and :fileName file
36 | */
37 | public function iCommentTheOrderWithMessageAndFile(Orderinterface $order, string $message, string $fileName): void
38 | {
39 | $this->commentOrder($order, $message, true, $fileName);
40 | }
41 |
42 | /**
43 | * @When I try to comment the order :order with an empty message
44 | */
45 | public function aCustomerTryToCommentsTheOrderWithEmptyMessage(OrderInterface $order): void
46 | {
47 | try {
48 | $this->commentOrder($order, '', true);
49 | } catch (\DomainException $exception) {
50 | $this->sharedStorage->set('exception', $exception);
51 | }
52 | }
53 |
54 | /**
55 | * @When a customer with email :email try to comment an order :order
56 | */
57 | public function aCustomerWithEmailTryToCommentAnOrder(string $email, OrderInterface $order): void
58 | {
59 | try {
60 | $this->commentOrder($order, 'Hello', true, null, $email);
61 | } catch (\DomainException $exception) {
62 | $this->sharedStorage->set('exception', $exception);
63 | }
64 | }
65 |
66 | /**
67 | * @Then /^(this order) should have a comment with "([^"]+)" from this customer$/
68 | */
69 | public function thisOrderShouldHaveCommentWithFromThisCustomer(OrderInterface $order, string $message): void
70 | {
71 | /** @var ShopUserInterface $user */
72 | $user = $this->sharedStorage->get('user');
73 | /** @var Comment $comment */
74 | $comment = $this->sharedStorage->get('comment');
75 |
76 | if (
77 | $comment->message() !== $message ||
78 | $comment->order() !== $order ||
79 | $comment->authorEmail() != $user->getEmail() ||
80 | !$comment->createdAt() instanceof \DateTimeInterface
81 | ) {
82 | throw new \RuntimeException(
83 | sprintf(
84 | 'There are no order comment with this message "%s" for this order "%s" from this customer "%s"',
85 | $message,
86 | $order->getNumber(),
87 | $user->getEmail()
88 | )
89 | );
90 | }
91 | }
92 |
93 | /**
94 | * Creates a new comment and sets it into the shared storage.
95 | * @param OrderInterface $order
96 | * @param string $message
97 | * @param bool $notifyCustomer
98 | * @param string|null $fileName
99 | * @param string|null $email
100 | */
101 | private function commentOrder(OrderInterface $order, string $message, bool $notifyCustomer, string $fileName = null, string $email = null): void
102 | {
103 | if (null === $email) {
104 | /** @var ShopUserInterface $user */
105 | $user = $this->sharedStorage->get('user');
106 | $email = $user->getEmail();
107 | }
108 |
109 | $comment = new Comment($order, $email, $message, $notifyCustomer);
110 |
111 | $this->eventDispatcher->dispatch(OrderCommented::occur(
112 | $comment->getId(),
113 | $comment->order(),
114 | $comment->authorEmail(),
115 | $comment->message(),
116 | $comment->notifyCustomer(),
117 | $comment->createdAt(),
118 | $comment->attachedFile()
119 | ));
120 |
121 | if (null !== $fileName) {
122 | $filePath = $comment->attachFile($fileName);
123 | $this->eventDispatcher->dispatch(FileAttached::occur($filePath));
124 | }
125 |
126 | $this->sharedStorage->set('comment', $comment);
127 | }
128 |
129 | /**
130 | * @Then I should be notified that comment is invalid
131 | */
132 | public function thisOrderShouldNotHaveEmptyCommentFromThisCustomer(): void
133 | {
134 | Assert::isInstanceOf($this->sharedStorage->get('exception'), \DomainException::class);
135 | }
136 |
137 | /**
138 | * @Then this order should not have any comments
139 | */
140 | public function thisOrderShouldNotHaveAnyComments()
141 | {
142 | Assert::false($this->sharedStorage->has('comment'), 'At least one comment has been saved in shared storage, but none should');
143 | }
144 |
145 | /**
146 | * @Then /^(this order) should have a comment with "([^"]+)" and file "([^"]+)" from this customer$/
147 | */
148 | public function thisOrderShouldHaveACommentWithAndFileFromThisCustomer(Orderinterface $order, string $message, string $fileName): void
149 | {
150 | /** @var ShopUserInterface $user */
151 | $user = $this->sharedStorage->get('user');
152 | /** @var Comment $comment */
153 | $comment = $this->sharedStorage->get('comment');
154 |
155 | if (
156 | $comment->message() !== $message ||
157 | $comment->order() !== $order ||
158 | $comment->authorEmail() != $user->getEmail() ||
159 | !$comment->createdAt() instanceof \DateTimeInterface ||
160 | $comment->attachedFile()->path() != $fileName
161 | ) {
162 | throw new \RuntimeException(
163 | sprintf(
164 | 'There are no order comment with this message "%s" for this order "%s" from this customer "%s"',
165 | $message,
166 | $order->getNumber(),
167 | $user->getEmail()
168 | )
169 | );
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/tests/Behat/Context/UI/AdministratorOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | sharedStorage = $sharedStorage;
37 | $this->orderPage = $orderPage;
38 | $this->orderCommentsElement = $orderCommentsElement;
39 | $this->orderCommentFormElement = $orderCommentFormElement;
40 | }
41 |
42 | /**
43 | * @When I comment the order :order with :message with the notify customer checkbox enabled
44 | * @Given I have commented the order :order with :message with the notify customer checkbox enabled
45 | */
46 | public function iCommentTheOrderWithMessageAndCheckboxEnabled(OrderInterface $order, string $message): void
47 | {
48 | $this->orderPage->open(['id' => $order->getId()]);
49 |
50 | $this->orderCommentFormElement->enableCustomerNotified();
51 | $this->orderCommentFormElement->specifyMessage($message);
52 | $this->orderCommentFormElement->comment();
53 |
54 | sleep(1);
55 | }
56 |
57 | /**
58 | * @When I comment the order :order with :message with the notify customer checkbox disabled
59 | * @Given I have commented the order :order with :message with the notify customer checkbox disabled
60 | */
61 | public function iCommentTheOrderWithMessageAndCheckboxDisabled(OrderInterface $order, string $message): void
62 | {
63 | $this->orderPage->open(['id' => $order->getId()]);
64 |
65 | $this->orderCommentFormElement->disableCustomerNotified();
66 | $this->orderCommentFormElement->specifyMessage($message);
67 | $this->orderCommentFormElement->comment();
68 | }
69 |
70 | /**
71 | * @When I try to comment the order :order with an empty message
72 | */
73 | public function aCustomerTryToCommentsTheOrderWithEmptyMessage(OrderInterface $order): void
74 | {
75 | $this->orderPage->open(['id' => $order->getId()]);
76 | $this->orderCommentFormElement->enableCustomerNotified();
77 | $this->orderCommentFormElement->specifyMessage('');
78 | $this->orderCommentFormElement->comment();
79 | }
80 |
81 | /**
82 | * @Then this order should have a comment with :message from this administrator
83 | * @Then the first comment from the top should have the :message message
84 | */
85 | public function thisOrderShouldHaveACommentWithFromThisAdministrator(string $message): void
86 | {
87 | /** @var AdminUserInterface $user */
88 | $user = $this->sharedStorage->get('administrator');
89 |
90 | $comment = $this->orderCommentsElement->getFirstComment();
91 |
92 | Assert::notNull($comment);
93 | Assert::same($comment->find('css', '.text')->getText(), $message);
94 | Assert::same($comment->find('css', '.author')->getText(), $user->getEmail());
95 | }
96 |
97 | /**
98 | * @Then I should be notified that comment is invalid
99 | */
100 | public function thisOrderShouldNotHaveEmptyCommentFromThisCustomer(): void
101 | {
102 | $order = $this->sharedStorage->get('order');
103 |
104 | Assert::true($this->orderPage->isOpen(['id' => $order->getId()]));
105 | }
106 |
107 | /**
108 | * @Then the order :order should not have any comments
109 | * @Then /^(this order) should not have any comments$/
110 | */
111 | public function theOrderShouldNotHaveAnyComments(OrderInterface $order): void
112 | {
113 | $this->orderPage->open(['id' => $order->getId()]);
114 |
115 | Assert::same($this->orderCommentsElement->countComments(), 0, 'This order should not have any comment, but %s found.');
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/tests/Behat/Context/UI/CustomerOrderCommentsContext.php:
--------------------------------------------------------------------------------
1 | sharedStorage = $sharedStorage;
37 | $this->orderPage = $orderPage;
38 | $this->orderCommentsElement = $orderCommentsElement;
39 | $this->orderCommentFormElement = $orderCommentFormElement;
40 | }
41 |
42 | /**
43 | * @When I comment the order :order with :message
44 | * @Given I have commented the order :order with :message
45 | */
46 | public function iCommentTheOrderWith(OrderInterface $order, string $message): void
47 | {
48 | $this->orderPage->open(['number' => $order->getNumber()]);
49 |
50 | $this->orderCommentFormElement->specifyMessage($message);
51 | $this->orderCommentFormElement->comment();
52 |
53 | $this->sharedStorage->set('order', $order);
54 | }
55 |
56 |
57 | /**
58 | * @Given I wait :seconds seconds
59 | */
60 | public function andIWaitSeconds(int $seconds): void
61 | {
62 | sleep($seconds);
63 | }
64 |
65 | /**
66 | * @When I try to comment the order :order with an empty message
67 | */
68 | public function aCustomerTryToCommentsTheOrderWithEmptyMessage(OrderInterface $order): void
69 | {
70 | $this->orderPage->open(['number' => $order->getNumber()]);
71 | $this->orderCommentFormElement->specifyMessage('');
72 | $this->orderCommentFormElement->comment();
73 |
74 | $this->sharedStorage->set('order', $order);
75 | }
76 |
77 | /**
78 | * @When I comment the order :order with :message and :fileName file
79 | */
80 | public function iCommentTheOrderWithMessageAndFile(Orderinterface $order, string $message, string $fileName): void
81 | {
82 | $filePath = __DIR__ . '/../../../Comments/Infrastructure/Form/Type/' . $fileName;
83 |
84 | $this->orderPage->open(['number' => $order->getNumber()]);
85 |
86 | $this->orderCommentFormElement->specifyMessage($message);
87 | $this->orderCommentFormElement->attachFile($filePath);
88 | $this->orderCommentFormElement->comment();
89 |
90 | $this->sharedStorage->set('order', $order);
91 | }
92 |
93 | /**
94 | * @Then this order should have a comment with :message from this customer
95 | * @Then the first comment from the top should have the :message message
96 | */
97 | public function thisOrderShouldHaveACommentWithFromThisAdministrator(string $message): void
98 | {
99 | $order = $this->sharedStorage->get('order');
100 | $this->orderPage->open(['number' => $order->getNumber()]);
101 |
102 | /** @var AdminUserInterface $user */
103 | $user = $this->sharedStorage->get('user');
104 |
105 | $comment = $this->orderCommentsElement->getFirstComment();
106 |
107 | Assert::notNull($comment);
108 | Assert::same($comment->find('css', '.text')->getText(), $message);
109 | Assert::same($comment->find('css', '.author')->getText(), $user->getEmail());
110 | }
111 |
112 | /**
113 | * @Then the order :order should not have any comments
114 | * @Then /^(this order) should not have any comments$/
115 | */
116 | public function theOrderShouldNotHaveAnyComments(OrderInterface $order): void
117 | {
118 | $this->orderPage->open(['number' => $order->getNumber()]);
119 |
120 | Assert::same($this->orderCommentsElement->countComments(), 0, 'This order should not have any comment, but %s found.');
121 |
122 | $this->sharedStorage->set('order', $order);
123 | }
124 |
125 | /**
126 | * @Then I should be notified that comment is invalid
127 | */
128 | public function thisOrderShouldNotHaveEmptyCommentFromThisCustomer(): void
129 | {
130 | }
131 |
132 | /**
133 | * @Then this order should have a comment with :message and file :fileName from this customer
134 | */
135 | public function thisOrderShouldHaveACommentWithAndFileFromThisCustomer(string $message, string $fileName): void
136 | {
137 | $order = $this->sharedStorage->get('order');
138 | $this->orderPage->open(['number' => $order->getNumber()]);
139 |
140 | /** @var AdminUserInterface $user */
141 | $user = $this->sharedStorage->get('user');
142 |
143 | $comment = $this->orderCommentsElement->getFirstComment();
144 |
145 | Assert::notNull($comment);
146 | Assert::same($comment->find('css', '.text')->getText(), $message);
147 | Assert::same($comment->find('css', '.author')->getText(), $user->getEmail());
148 | Assert::true($comment->find('css', '.file')->isValid());
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/tests/Behat/Element/Element.php:
--------------------------------------------------------------------------------
1 | session = $session;
35 | $this->parameters = $parameters;
36 | }
37 |
38 | protected function getParameter(string $name): NodeElement
39 | {
40 | return $this->parameters[$name] ?? null;
41 | }
42 |
43 | /**
44 | * Defines elements by returning an array with items being:
45 | * - :elementName => :cssLocator
46 | * - :elementName => [:selectorType => :locator]
47 | */
48 | protected function getDefinedElements(): array
49 | {
50 | return [];
51 | }
52 |
53 | /**
54 | * @param string $name
55 | * @param array $parameters
56 | *
57 | * @return NodeElement
58 | *
59 | * @throws ElementNotFoundException
60 | */
61 | protected function getElement(string $name, array $parameters = []): NodeElement
62 | {
63 | $element = $this->createElement($name, $parameters);
64 |
65 | if (!$this->getDocument()->has('xpath', $element->getXpath())) {
66 | throw new ElementNotFoundException(
67 | $this->getSession(),
68 | sprintf('Element named "%s" with parameters %s', $name, implode(', ', $parameters)),
69 | 'xpath',
70 | $element->getXpath()
71 | );
72 | }
73 |
74 | return $element;
75 | }
76 |
77 | protected function hasElement(string $name, array $parameters = []): bool
78 | {
79 | return $this->getDocument()->has('xpath', $this->createElement($name, $parameters)->getXpath());
80 | }
81 |
82 | protected function getSession(): Session
83 | {
84 | return $this->session;
85 | }
86 |
87 | protected function getDriver(): DriverInterface
88 | {
89 | return $this->session->getDriver();
90 | }
91 |
92 | protected function getDocument(): DocumentElement
93 | {
94 | if (null === $this->document) {
95 | $this->document = new DocumentElement($this->session);
96 | }
97 |
98 | return $this->document;
99 | }
100 |
101 | private function createElement(string $name, array $parameters = []): NodeElement
102 | {
103 | $definedElements = $this->getDefinedElements();
104 |
105 | if (!isset($definedElements[$name])) {
106 | throw new \InvalidArgumentException(sprintf(
107 | 'Could not find a defined element with name "%s". The defined ones are: %s.',
108 | $name,
109 | implode(', ', array_keys($definedElements))
110 | ));
111 | }
112 |
113 | $elementSelector = $this->resolveParameters($name, $parameters, $definedElements);
114 |
115 | return new NodeElement(
116 | $this->getSelectorAsXpath($elementSelector, $this->session->getSelectorsHandler()),
117 | $this->session
118 | );
119 | }
120 |
121 | /**
122 | * @param string|array $selector
123 | * @param SelectorsHandler $selectorsHandler
124 | *
125 | * @return string
126 | */
127 | private function getSelectorAsXpath($selector, SelectorsHandler $selectorsHandler): string
128 | {
129 | $selectorType = is_array($selector) ? key($selector) : 'css';
130 | $locator = is_array($selector) ? $selector[$selectorType] : $selector;
131 |
132 | return $selectorsHandler->selectorToXpath($selectorType, $locator);
133 | }
134 |
135 | private function resolveParameters(string $name, array $parameters, array $definedElements): string
136 | {
137 | if (!is_array($definedElements[$name])) {
138 | return strtr($definedElements[$name], $parameters);
139 | }
140 |
141 | array_map(
142 | function ($definedElement) use ($parameters) {
143 | return strtr($definedElement, $parameters);
144 | }, $definedElements[$name]
145 | );
146 |
147 | return $definedElements[$name];
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/tests/Behat/Element/OrderCommentFormElement.php:
--------------------------------------------------------------------------------
1 | getDocument()->fillField('Message', $message);
12 | }
13 |
14 | public function attachFile($path): void
15 | {
16 | $this->getDocument()->find('css', 'input[type="file"]')->attachFile($path);
17 | }
18 |
19 | public function enableCustomerNotified(): void
20 | {
21 | $this->getDocument()->find('css', '#order_comment_notifyCustomer')->check();
22 | }
23 |
24 | public function disableCustomerNotified(): void
25 | {
26 | $this->getDocument()->find('css', '#order_comment_notifyCustomer')->uncheck();
27 | }
28 |
29 | public function comment(): void
30 | {
31 | $this->getDocument()->pressButton('Comment');
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Behat/Element/OrderCommentFormElementInterface.php:
--------------------------------------------------------------------------------
1 | getDocument()->find('css', '#comments .comment');
14 | }
15 |
16 | public function countComments(): int
17 | {
18 | return count($this->getDocument()->findAll('css', '#comments .comment'));
19 | }
20 |
21 | protected function getDefinedElements(): array
22 | {
23 | return array_merge(parent::getDefinedElements(), [
24 | 'comments' => '#comments',
25 | ]);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Behat/Element/OrderCommentsElementInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
31 |
32 |
38 |
39 |
45 |
46 |
49 |
50 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites.yml:
--------------------------------------------------------------------------------
1 | imports:
2 | - suites/domain/customer_order_comments.yml
3 | - suites/application/customer_order_comments.yml
4 | - suites/ui/customer_order_comments.yml
5 |
6 | - suites/domain/administrator_order_comments.yml
7 | - suites/application/administrator_order_comments.yml
8 | - suites/ui/administrator_order_comments.yml
9 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/application/administrator_order_comments.yml:
--------------------------------------------------------------------------------
1 | # Put your Behat suites definitions here
2 |
3 | default:
4 | suites:
5 | application_admistrator_order_comments:
6 | contexts:
7 | - sylius.behat.context.hook.doctrine_orm
8 | - sylius.behat.context.hook.mailer
9 |
10 | - sylius.behat.context.setup.channel
11 | - sylius.behat.context.setup.order
12 | - sylius.behat.context.setup.payment
13 | - sylius.behat.context.setup.product
14 | - sylius.behat.context.setup.shipping
15 | - sylius.behat.context.setup.user
16 | - sylius.behat.context.setup.admin_security
17 |
18 | - sylius.behat.context.transform.address
19 | - sylius.behat.context.transform.customer
20 | - sylius.behat.context.transform.order
21 | - sylius.behat.context.transform.payment
22 | - sylius.behat.context.transform.product
23 | - sylius.behat.context.transform.shared_storage
24 | - sylius.behat.context.transform.shipping_method
25 |
26 | - brille24.order_comments_plugin.behat.application.administrator_order_comments
27 | filters:
28 | tags: "@administrator_order_comments && @application"
29 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/application/customer_order_comments.yml:
--------------------------------------------------------------------------------
1 | # Put your Behat suites definitions here
2 |
3 | default:
4 | suites:
5 | application_customer_order_comments:
6 | contexts:
7 | - sylius.behat.context.hook.doctrine_orm
8 | - sylius.behat.context.hook.mailer
9 |
10 | - sylius.behat.context.setup.channel
11 | - sylius.behat.context.setup.order
12 | - sylius.behat.context.setup.payment
13 | - sylius.behat.context.setup.product
14 | - sylius.behat.context.setup.shop_security
15 | - sylius.behat.context.setup.shipping
16 | - sylius.behat.context.setup.user
17 |
18 | - sylius.behat.context.transform.address
19 | - sylius.behat.context.transform.customer
20 | - sylius.behat.context.transform.order
21 | - sylius.behat.context.transform.payment
22 | - sylius.behat.context.transform.product
23 | - sylius.behat.context.transform.shared_storage
24 | - sylius.behat.context.transform.shipping_method
25 |
26 | - brille24.order_comments_plugin.behat.common.channel
27 |
28 | - brille24.order_comments_plugin.behat.application.customer_order_comments
29 | filters:
30 | tags: "@customer_order_comments && @application"
31 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/domain/administrator_order_comments.yml:
--------------------------------------------------------------------------------
1 | # Put your Behat suites definitions here
2 |
3 | default:
4 | suites:
5 | domain_administrator_order_comments:
6 | contexts:
7 | - sylius.behat.context.hook.doctrine_orm
8 | - sylius.behat.context.hook.mailer
9 |
10 | - sylius.behat.context.setup.channel
11 | - sylius.behat.context.setup.order
12 | - sylius.behat.context.setup.payment
13 | - sylius.behat.context.setup.product
14 | - sylius.behat.context.setup.shipping
15 | - sylius.behat.context.setup.user
16 | - sylius.behat.context.setup.admin_security
17 |
18 | - sylius.behat.context.transform.address
19 | - sylius.behat.context.transform.customer
20 | - sylius.behat.context.transform.order
21 | - sylius.behat.context.transform.payment
22 | - sylius.behat.context.transform.product
23 | - sylius.behat.context.transform.shared_storage
24 | - sylius.behat.context.transform.shipping_method
25 |
26 | - brille24.order_comments_plugin.behat.domain.administrator_order_comments
27 | filters:
28 | tags: "@administrator_order_comments && @domain"
29 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/domain/customer_order_comments.yml:
--------------------------------------------------------------------------------
1 | # Put your Behat suites definitions here
2 |
3 | default:
4 | suites:
5 | domain_customer_order_comments:
6 | contexts:
7 | - sylius.behat.context.hook.doctrine_orm
8 | - sylius.behat.context.hook.mailer
9 |
10 | - sylius.behat.context.setup.channel
11 | - sylius.behat.context.setup.order
12 | - sylius.behat.context.setup.payment
13 | - sylius.behat.context.setup.product
14 | - sylius.behat.context.setup.shop_security
15 | - sylius.behat.context.setup.shipping
16 | - sylius.behat.context.setup.user
17 |
18 | - sylius.behat.context.transform.address
19 | - sylius.behat.context.transform.customer
20 | - sylius.behat.context.transform.order
21 | - sylius.behat.context.transform.payment
22 | - sylius.behat.context.transform.product
23 | - sylius.behat.context.transform.shared_storage
24 | - sylius.behat.context.transform.shipping_method
25 |
26 | - brille24.order_comments_plugin.behat.common.channel
27 |
28 | - brille24.order_comments_plugin.behat.domain.customer_order_comments
29 | filters:
30 | tags: "@customer_order_comments && @domain"
31 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/ui/administrator_order_comments.yml:
--------------------------------------------------------------------------------
1 | default:
2 | suites:
3 | ui_admistrator_order_comments:
4 | contexts:
5 | - sylius.behat.context.hook.doctrine_orm
6 | - sylius.behat.context.hook.mailer
7 |
8 | - sylius.behat.context.setup.channel
9 | - sylius.behat.context.setup.order
10 | - sylius.behat.context.setup.payment
11 | - sylius.behat.context.setup.product
12 | - sylius.behat.context.setup.shipping
13 | - sylius.behat.context.setup.user
14 | - sylius.behat.context.setup.admin_security
15 |
16 | - sylius.behat.context.transform.address
17 | - sylius.behat.context.transform.customer
18 | - sylius.behat.context.transform.order
19 | - sylius.behat.context.transform.payment
20 | - sylius.behat.context.transform.product
21 | - sylius.behat.context.transform.shared_storage
22 | - sylius.behat.context.transform.shipping_method
23 |
24 | - brille24.order_comments_plugin.behat.ui.administrator_order_comments
25 | filters:
26 | tags: "@administrator_order_comments && @ui"
27 |
--------------------------------------------------------------------------------
/tests/Behat/Resources/suites/ui/customer_order_comments.yml:
--------------------------------------------------------------------------------
1 | # Put your Behat suites definitions here
2 |
3 | default:
4 | suites:
5 | ui_customer_order_comments:
6 | contexts:
7 | - sylius.behat.context.hook.doctrine_orm
8 | - sylius.behat.context.hook.mailer
9 |
10 | - sylius.behat.context.setup.channel
11 | - sylius.behat.context.setup.order
12 | - sylius.behat.context.setup.payment
13 | - sylius.behat.context.setup.product
14 | - sylius.behat.context.setup.shop_security
15 | - sylius.behat.context.setup.shipping
16 | - sylius.behat.context.setup.user
17 |
18 | - sylius.behat.context.transform.address
19 | - sylius.behat.context.transform.customer
20 | - sylius.behat.context.transform.order
21 | - sylius.behat.context.transform.payment
22 | - sylius.behat.context.transform.product
23 | - sylius.behat.context.transform.shared_storage
24 | - sylius.behat.context.transform.shipping_method
25 |
26 | - brille24.order_comments_plugin.behat.common.channel
27 |
28 | - brille24.order_comments_plugin.behat.ui.customer_order_comments
29 | filters:
30 | tags: "@customer_order_comments && @ui"
31 |
--------------------------------------------------------------------------------
/tests/Comments/Application/Command/CommentOrderTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('#00002', $command->orderNumber());
21 | $this->assertEquals('test@test.com', $command->authorEmail());
22 | $this->assertEquals('Hello', $command->message());
23 | $this->assertEquals(true, $command->notifyCustomer());
24 | }
25 |
26 | /**
27 | * @test
28 | */
29 | public function it_has_option_file_path_and_file_type(): void
30 | {
31 | $filePath = __DIR__.'/../../Infrastructure/Form/Type/text.txt';
32 |
33 | $file = new UploadedFile($filePath, $filePath, null, null, true);
34 | $command = CommentOrder::create('#00002', 'test@test.com', 'Hello', true, $file);
35 |
36 | $this->assertEquals($file, $command->file());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Comments/Application/Process/ChanneledEmailSenderTest.php:
--------------------------------------------------------------------------------
1 | sender = $this->createMock(SenderInterface::class);
33 |
34 | $this->channel = $this->createMock(ChannelInterface::class);
35 | $this->channelContext = $this->createMock(ChannelContextInterface::class);
36 |
37 | /** @var ChannelRepositoryInterface|MockObject $channelRepository */
38 | $channelRepository = $this->createMock(ChannelRepositoryInterface::class);
39 | $channelRepository
40 | ->method('findOneByCode')
41 | ->with('glasses24')
42 | ->willReturn($this->channel)
43 | ;
44 |
45 | $this->channeledEmailSender =
46 | new ChanneledEmailSender($this->sender, $channelRepository, $this->channelContext);
47 | }
48 |
49 | public function testSendsTheEmailWithChanneledTemplate(): void
50 | {
51 | $this->sender->expects($this->once())->method('send')->with($this->equalTo('welcome_glasses24'));
52 |
53 | $this->channeledEmailSender
54 | ->sendWithChannelTemplate('welcome', 'glasses24', ['test@localhost.com'], ['message' => 'Hello']);
55 | }
56 |
57 | public function testGetsChannelFromChannelContext(): void
58 | {
59 | $this->channelContext->method('getChannel')->willReturn($this->channel);
60 | $this->channel->method('getCode')->willReturn('glasses24');
61 | $this->sender->expects($this->once())->method('send')->with($this->equalTo('welcome_glasses24'));
62 |
63 | $this->channeledEmailSender
64 | ->send('welcome', ['test@localhost.com'], ['message' => 'Hello']);
65 | }
66 |
67 | public function testSendsAnUnchanneledEmailIfTheChannelHasNoConfig(): void
68 | {
69 | $this->channelContext->method('getChannel')->willReturn($this->channel);
70 | $this->channel->method('getCode')->willReturn('glasses24');
71 | $this->sender
72 | ->expects($this->atLeastOnce())
73 | ->method('send')
74 | ->withConsecutive(
75 | [
76 | 'welcome_glasses24',
77 | ['test@localhost.com'],
78 | ['message' => 'Hello', 'channel' => $this->channel],
79 | [],
80 | [],
81 | ],
82 | ['welcome'],
83 | )
84 | ->will(
85 | new ConsecutiveCalls([
86 | $this->throwException(new InvalidArgumentException()),
87 | $this->returnValue(null),
88 | ])
89 | )
90 | ;
91 | $this->channeledEmailSender
92 | ->send('welcome', ['test@localhost.com'], ['message' => 'Hello']);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/tests/Comments/Domain/Event/FileAttachedTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('test/test/file.pdf', $event->filePath());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Comments/Domain/Event/OrderCommentedTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($commentId, $event->orderCommentId());
32 | $this->assertEquals($order, $event->order());
33 | $this->assertEquals('test@test.com', $event->authorEmail());
34 | $this->assertEquals('Hello', $event->message());
35 | $this->assertEquals(true, $event->notifyCustomer());
36 | $this->assertInstanceOf(\DateTimeImmutable::class, $event->createdAt());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Comments/Domain/Model/AttachedFileTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('test/test/file.pdf', $uploadedFile->path());
20 | }
21 |
22 | /**
23 | * @test
24 | */
25 | public function it_cannot_be_created_with_empty_path(): void
26 | {
27 | $this->expectException(\DomainException::class);
28 |
29 | AttachedFile::create('');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Comments/Domain/Model/CommentTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($order, $comment->order());
23 | $this->assertEquals('test@test.com', $comment->authorEmail());
24 | $this->assertEquals('Hello', $comment->message());
25 | $this->assertEquals(true, $comment->notifyCustomer());
26 | $this->assertInstanceOf(\DateTimeImmutable::class, $comment->createdAt());
27 | }
28 |
29 | /**
30 | * @test
31 | */
32 | public function order_cannot_be_commented_with_empty_message(): void
33 | {
34 | $this->expectException(\DomainException::class);
35 |
36 | $order = new Order();
37 |
38 | new Comment($order, 'test@test.com', '', true);
39 | }
40 |
41 | /**
42 | * @test
43 | */
44 | public function order_cannot_be_commented_with_invalid_email(): void
45 | {
46 | $this->expectException(\DomainException::class);
47 |
48 | $order = new Order();
49 |
50 | new Comment($order, 'abcd.com', 'Hello', true);
51 | }
52 |
53 | /**
54 | * @test
55 | */
56 | public function it_can_have_file_attached(): void
57 | {
58 | $order = new Order();
59 |
60 | $comment = new Comment($order, 'test@test.com', 'Hello', true);
61 | $comment->attachFile('test/test.pdf');
62 |
63 | $this->assertNotNull($comment->attachedFile());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/Comments/Domain/Model/EmailTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('test@test.com', $email->__toString());
20 | }
21 |
22 | /**
23 | * @test
24 | */
25 | public function it_cannot_be_created_from_invalid_string(): void
26 | {
27 | $this->expectException(\DomainException::class);
28 |
29 | Email::fromString('abcd.com');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Comments/Infrastructure/Form/Type/file.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Comments/Infrastructure/Form/Type/file.pdf
--------------------------------------------------------------------------------
/tests/Comments/Infrastructure/Form/Type/text.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Brille24/SyliusOrderCommentsPlugin/1c59f1a13aead1387a3f5a44d2a945c9cd996aad/tests/Comments/Infrastructure/Form/Type/text.txt
--------------------------------------------------------------------------------
/translations/messages.de.yml:
--------------------------------------------------------------------------------
1 | sylius_order_comments:
2 | notify_customer: "Kunden über den Kommentar benachrichtigen"
3 | customer_notified: "Kunde benachrichtig!"
4 | customer_not_notified: "Kunde wurde nicht benachrichtigt!"
5 |
--------------------------------------------------------------------------------
/translations/messages.en.yml:
--------------------------------------------------------------------------------
1 | sylius_order_comments:
2 | notify_customer: "Notify customer about this comment!"
3 | customer_notified: "Customer notified!"
4 | customer_not_notified: "Customer not notified!"
5 |
--------------------------------------------------------------------------------