58 changed files with 9281 additions and 2 deletions
-
10.editorconfig
-
7.gitlab-ci.yml
-
19LICENSE
-
18Makefile
-
3README.md
-
6app/.env.test
-
3app/.gitignore
-
13app/.php-cs-fixer.php
-
17app/bin/console
-
19app/bin/phpunit
-
127app/composer.json
-
7816app/composer.lock
-
9app/config/bundles.php
-
4app/config/packages/cache.yaml
-
8app/config/packages/dev/web_profiler.yaml
-
20app/config/packages/framework.yaml
-
17app/config/packages/nelmio_api_doc.yaml
-
10app/config/packages/routing.yaml
-
8app/config/packages/test/web_profiler.yaml
-
8app/config/packages/twig.yaml
-
5app/config/preload.php
-
6app/config/routes.yaml
-
9app/config/routes/annotations.yaml
-
9app/config/routes/dev/web_profiler.yaml
-
6app/config/routes/framework.yaml
-
11app/config/routes/nelmio_api_doc.yaml
-
29app/config/services.yaml
-
35app/phpunit.xml.dist
-
1app/public/bundles/.gitignore
-
9app/public/index.php
-
56app/src/Controller/Api/v1/MattermostController.php
-
38app/src/Kernel.php
-
15app/src/Service/BaseService.php
-
55app/src/Service/Mattermost/MattermostService.php
-
12app/src/Service/Mattermost/MattermostServiceInterface.php
-
433app/symfony.lock
-
19app/templates/base.html.twig
-
19app/tests/Unit/Controller/Api/v1/MattermostControllerTest.php
-
19app/tests/Unit/KernelTest.php
-
102app/tests/Unit/Service/Mattermost/MattermostServiceTest.php
-
27app/tests/Unit/UnitTester.php
-
2app/tests/_coverage/.gitignore
-
11app/tests/bootstrap.php
-
2app/var/cache/.gitignore
-
2app/var/log/.gitignore
-
2app/var/php-cs-fixer/.gitignore
-
2app/var/sessions/.gitignore
-
2app/vendor/.gitignore
-
27devops/docker/nginx/etc/nginx/conf.d/default.conf
-
36devops/docker/php/Dockerfile
-
9devops/docker/php/xdebug.ini
-
22devops/gitlab/merge_requests/build/1_build.yml
-
19devops/gitlab/release/1_release-tag.yml
-
19devops/gitlab/release/2_deploy.yml
-
35docker-compose-local.yml
-
27docker-compose.yml
-
1env/.gitignore
-
8env/app/app.env-dist
@ -0,0 +1,10 @@ |
|||
root = true |
|||
|
|||
[*] |
|||
charset = utf-8 |
|||
end_of_line = lf |
|||
indent_style = space |
|||
indent_size = 4 |
|||
trim_trailing_whitespace = true |
|||
insert_final_newline = true |
|||
max_line_length = 100 |
@ -0,0 +1,7 @@ |
|||
--- |
|||
include: |
|||
- project: infra/kernel/ci-templates |
|||
ref: master |
|||
file: /${CI_PROJECT_PATH}.yml |
|||
- local: /devops/gitlab/merge_requests/build/1_build.yml |
|||
... |
@ -0,0 +1,19 @@ |
|||
MIT License Copyright (c) 2021 fedy95 |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is furnished |
|||
to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice (including the next |
|||
paragraph) shall be included in all copies or substantial portions of the |
|||
Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
|||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS |
|||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
|||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,18 @@ |
|||
MAKEFLAGS += --silent |
|||
.PHONY: * |
|||
|
|||
restart-local: |
|||
docker-compose -f docker-compose-local.yml pull |
|||
docker-compose -f docker-compose-local.yml down |
|||
docker-compose -f docker-compose-local.yml up -d |
|||
|
|||
restart: |
|||
docker-compose -f docker-compose.yml pull |
|||
docker-compose -f docker-compose.yml down |
|||
docker-compose -f docker-compose.yml up -d |
|||
|
|||
cleanup: |
|||
docker system prune --all --force |
|||
docker system prune --volumes --force |
|||
|
|||
.DEFAULT_GOAL := lint |
@ -1,2 +1 @@ |
|||
# notification-provider |
|||
|
|||
### notification-provider |
@ -0,0 +1,6 @@ |
|||
# define your env variables for the test env here |
|||
KERNEL_CLASS='App\Kernel' |
|||
APP_SECRET='$ecretf0rt3st' |
|||
SYMFONY_DEPRECATIONS_HELPER=999999 |
|||
PANTHER_APP_ENV=panther |
|||
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots |
@ -0,0 +1,3 @@ |
|||
/.env |
|||
/.phpunit.result.cache |
|||
/phpunit.xml |
@ -0,0 +1,13 @@ |
|||
<?php |
|||
|
|||
$finder = PhpCsFixer\Finder::create() |
|||
->in(__DIR__) |
|||
->exclude('var') |
|||
; |
|||
|
|||
return (new PhpCsFixer\Config())->setRules([ |
|||
'@Symfony' => true, |
|||
'array_syntax' => ['syntax' => 'short'], |
|||
]) |
|||
->setFinder($finder) |
|||
; |
@ -0,0 +1,17 @@ |
|||
#!/usr/bin/env php |
|||
<?php |
|||
|
|||
use App\Kernel; |
|||
use Symfony\Bundle\FrameworkBundle\Console\Application; |
|||
|
|||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) { |
|||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".'); |
|||
} |
|||
|
|||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; |
|||
|
|||
return function (array $context) { |
|||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); |
|||
|
|||
return new Application($kernel); |
|||
}; |
@ -0,0 +1,19 @@ |
|||
#!/usr/bin/env php |
|||
<?php |
|||
|
|||
if (!ini_get('date.timezone')) { |
|||
ini_set('date.timezone', 'UTC'); |
|||
} |
|||
|
|||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) { |
|||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php'); |
|||
require PHPUNIT_COMPOSER_INSTALL; |
|||
PHPUnit\TextUI\Command::main(); |
|||
} else { |
|||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) { |
|||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; |
|||
exit(1); |
|||
} |
|||
|
|||
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php'; |
|||
} |
@ -0,0 +1,127 @@ |
|||
{ |
|||
"name": "dev/notification-provider", |
|||
"type": "project", |
|||
"description": "notification-provider", |
|||
"license": "MIT", |
|||
"require": { |
|||
"php": "8.0.*", |
|||
"ext-ctype": "8.0.*", |
|||
"ext-iconv": "8.0.*", |
|||
"doctrine/annotations": "^1.13", |
|||
"guzzlehttp/guzzle": "^7.3", |
|||
"nelmio/api-doc-bundle": "^4.6", |
|||
"symfony/asset": "5.3.*", |
|||
"symfony/console": "5.3.*", |
|||
"symfony/dotenv": "5.3.*", |
|||
"symfony/flex": "^1.16", |
|||
"symfony/framework-bundle": "5.3.*", |
|||
"symfony/runtime": "5.3.*", |
|||
"symfony/twig-bundle": "5.3.*", |
|||
"symfony/yaml": "5.3.*", |
|||
"twig/extra-bundle": "^2.12 || ^3.0", |
|||
"twig/twig": "^2.12 || ^3.0" |
|||
}, |
|||
"replace": { |
|||
"symfony/polyfill-ctype": "*", |
|||
"symfony/polyfill-iconv": "*", |
|||
"symfony/polyfill-php72": "*" |
|||
}, |
|||
"conflict": { |
|||
"symfony/symfony": "*" |
|||
}, |
|||
"require-dev": { |
|||
"ext-xdebug": "3.*", |
|||
"ergebnis/composer-normalize": "^2.13", |
|||
"fakerphp/faker": "^1.0", |
|||
"friendsofphp/php-cs-fixer": "^3.1", |
|||
"php-parallel-lint/php-parallel-lint": "1.3.*", |
|||
"phpunit/phpunit": "^9.5", |
|||
"roave/security-advisories": "dev-latest", |
|||
"symfony/browser-kit": "5.3.*", |
|||
"symfony/css-selector": "5.3.*", |
|||
"symfony/phpunit-bridge": "^5.3", |
|||
"symfony/stopwatch": "5.3.*", |
|||
"symfony/web-profiler-bundle": "5.3.*" |
|||
}, |
|||
"config": { |
|||
"optimize-autoloader": true, |
|||
"preferred-install": { |
|||
"*": "dist" |
|||
}, |
|||
"sort-packages": true |
|||
}, |
|||
"extra": { |
|||
"symfony": { |
|||
"allow-contrib": false, |
|||
"require": "5.3.*" |
|||
} |
|||
}, |
|||
"autoload": { |
|||
"psr-4": { |
|||
"App\\": "src/" |
|||
} |
|||
}, |
|||
"autoload-dev": { |
|||
"psr-4": { |
|||
"App\\Tests\\": "tests/" |
|||
} |
|||
}, |
|||
"minimum-stability": "stable", |
|||
"prefer-stable": true, |
|||
"scripts": { |
|||
"post-install-cmd": [ |
|||
"@auto-scripts" |
|||
], |
|||
"post-update-cmd": [ |
|||
"@auto-scripts" |
|||
], |
|||
"auto-scripts": { |
|||
"cache:clear": "symfony-cmd", |
|||
"assets:install %PUBLIC_DIR%": "symfony-cmd" |
|||
}, |
|||
"json-cs-fix": "composer normalize", |
|||
"lint:php": [ |
|||
"parallel-lint --no-progress --no-colors --blame ./bin/console", |
|||
"parallel-lint --no-progress --no-colors --blame ./config/bundles.php", |
|||
"parallel-lint --no-progress --no-colors --blame ./config/preload.php", |
|||
"parallel-lint --no-progress --no-colors --blame ./public/index.php", |
|||
"parallel-lint --no-progress --no-colors --blame ./src", |
|||
"parallel-lint --no-progress --no-colors --blame ./tests/bootstrap.php", |
|||
"parallel-lint --no-progress --no-colors --blame .php-cs-fixer.php" |
|||
], |
|||
"lint:yaml": [ |
|||
"bin/console --quiet --no-debug l:yaml ./config/packages", |
|||
"bin/console --quiet --no-debug l:yaml ./config/routes", |
|||
"bin/console --quiet --no-debug l:yaml ./config/routes.yaml", |
|||
"bin/console --quiet --no-debug l:yaml ./config/services.yaml" |
|||
], |
|||
"php-cs-check": [ |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache bin/console", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache config/bundles.php", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache config/preload.php", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache public/index.php", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache src", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache tests/bootstrap.php", |
|||
"php vendor/bin/php-cs-fixer fix --dry-run --cache-file=var/php-cs-fixer/.php-cs.cache .php-cs-fixer.php" |
|||
], |
|||
"php-cs-fix": [ |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache bin/console", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache config/bundles.php", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache config/preload.php", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache public/index.php", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache src", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/bootstrap.php", |
|||
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache .php-cs-fixer.php" |
|||
], |
|||
"test": [ |
|||
"@php ./vendor/bin/phpunit --coverage-html tests/_coverage --coverage-text" |
|||
], |
|||
"test:unit": [ |
|||
"@php ./vendor/bin/phpunit --coverage-html tests/_coverage --coverage-text --colors=never" |
|||
], |
|||
"validate:composer": { |
|||
"check:platform": "@composer check-platform-reqs", |
|||
"validate": "@composer validate --strict" |
|||
} |
|||
} |
|||
} |
7816
app/composer.lock
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,9 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], |
|||
Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true], |
|||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], |
|||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], |
|||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], |
|||
]; |
@ -0,0 +1,4 @@ |
|||
--- |
|||
framework: |
|||
cache: |
|||
... |
@ -0,0 +1,8 @@ |
|||
--- |
|||
web_profiler: |
|||
toolbar: true |
|||
intercept_redirects: false |
|||
|
|||
framework: |
|||
profiler: { only_exceptions: false } |
|||
... |
@ -0,0 +1,20 @@ |
|||
--- |
|||
framework: |
|||
secret: '%env(APP_SECRET)%' |
|||
http_method_override: false |
|||
|
|||
session: |
|||
handler_id: null |
|||
cookie_secure: auto |
|||
cookie_samesite: lax |
|||
storage_factory_id: session.storage.factory.native |
|||
|
|||
php_errors: |
|||
log: true |
|||
|
|||
when@test: |
|||
framework: |
|||
test: true |
|||
session: |
|||
storage_factory_id: session.storage.factory.mock_file |
|||
... |
@ -0,0 +1,17 @@ |
|||
--- |
|||
nelmio_api_doc: |
|||
documentation: |
|||
servers: |
|||
- url: http://127.0.0.1:8054 |
|||
description: localhost API over HTTP |
|||
- url: https://notification-provider.fedy95.com |
|||
description: server API over HTTPS |
|||
info: |
|||
title: notification-provider |
|||
description: notification-provider api doc |
|||
version: 0.0.1 |
|||
areas: |
|||
default: |
|||
path_patterns: |
|||
- ^/api/v1 |
|||
... |
@ -0,0 +1,10 @@ |
|||
--- |
|||
framework: |
|||
router: |
|||
utf8: true |
|||
|
|||
when@prod: |
|||
framework: |
|||
router: |
|||
strict_requirements: null |
|||
... |
@ -0,0 +1,8 @@ |
|||
--- |
|||
web_profiler: |
|||
toolbar: false |
|||
intercept_redirects: false |
|||
|
|||
framework: |
|||
profiler: { collect: false } |
|||
... |
@ -0,0 +1,8 @@ |
|||
--- |
|||
twig: |
|||
default_path: '%kernel.project_dir%/templates' |
|||
|
|||
when@test: |
|||
twig: |
|||
strict_variables: true |
|||
... |
@ -0,0 +1,5 @@ |
|||
<?php |
|||
|
|||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) { |
|||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php'; |
|||
} |
@ -0,0 +1,6 @@ |
|||
--- |
|||
app.swagger_ui: |
|||
path: /api/doc/{area} |
|||
methods: GET |
|||
defaults: { _controller: nelmio_api_doc.controller.swagger_ui, area: default } |
|||
... |
@ -0,0 +1,9 @@ |
|||
--- |
|||
controllers: |
|||
resource: ../../src/Controller/ |
|||
type: annotation |
|||
|
|||
kernel: |
|||
resource: ../../src/Kernel.php |
|||
type: annotation |
|||
... |
@ -0,0 +1,9 @@ |
|||
--- |
|||
web_profiler_wdt: |
|||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml' |
|||
prefix: /_wdt |
|||
|
|||
web_profiler_profiler: |
|||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml' |
|||
prefix: /_profiler |
|||
... |
@ -0,0 +1,6 @@ |
|||
--- |
|||
when@dev: |
|||
_errors: |
|||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml' |
|||
prefix: /_error |
|||
... |
@ -0,0 +1,11 @@ |
|||
--- |
|||
app.swagger: |
|||
path: /api/doc.json |
|||
methods: GET |
|||
defaults: { _controller: nelmio_api_doc.controller.swagger } |
|||
|
|||
app.swagger_ui: |
|||
path: /api/doc |
|||
methods: GET |
|||
defaults: { _controller: nelmio_api_doc.controller.swagger_ui } |
|||
... |
@ -0,0 +1,29 @@ |
|||
--- |
|||
parameters: |
|||
app.mattermost.url: '%env(resolve:MATTERMOST_URL)%' |
|||
app.mattermost.uri: '%env(resolve:MATTERMOST_URI)%' |
|||
app.mattermost.channel_name: '%env(resolve:MATTERMOST_CHANNEL_NAME)%' |
|||
app.mattermost.bot.name: '%env(resolve:MATTERMOST_BOT_NAME)%' |
|||
app.mattermost.bot.icon: '%env(resolve:MATTERMOST_BOT_ICON)%' |
|||
|
|||
services: |
|||
_defaults: |
|||
autowire: true |
|||
autoconfigure: true |
|||
|
|||
App\: |
|||
resource: '../src/' |
|||
exclude: |
|||
- '../src/DependencyInjection/' |
|||
- '../src/Entity/' |
|||
- '../src/Kernel.php' |
|||
- '../src/Tests/' |
|||
|
|||
App\Service\Mattermost\MattermostService: |
|||
arguments: |
|||
$mattermostUrl: '%app.mattermost.url%' |
|||
$mattermostUri: '%app.mattermost.uri%' |
|||
$channelName: '%app.mattermost.channel_name%' |
|||
$botName: '%app.mattermost.bot.name%' |
|||
$botIcon: '%app.mattermost.bot.icon%' |
|||
... |
@ -0,0 +1,35 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
|
|||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html --> |
|||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" |
|||
backupGlobals="false" |
|||
colors="true" |
|||
bootstrap="tests/bootstrap.php" |
|||
convertDeprecationsToExceptions="false" |
|||
> |
|||
<php> |
|||
<ini name="display_errors" value="1" /> |
|||
<ini name="error_reporting" value="-1" /> |
|||
<server name="APP_ENV" value="test" force="true" /> |
|||
<server name="SHELL_VERBOSITY" value="-1" /> |
|||
<server name="SYMFONY_PHPUNIT_REMOVE" value="" /> |
|||
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" /> |
|||
</php> |
|||
|
|||
<testsuites> |
|||
<testsuite name="Project Test Suite"> |
|||
<directory>tests</directory> |
|||
</testsuite> |
|||
</testsuites> |
|||
|
|||
<coverage processUncoveredFiles="true"> |
|||
<include> |
|||
<directory suffix=".php">src</directory> |
|||
</include> |
|||
</coverage> |
|||
|
|||
<listeners> |
|||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" /> |
|||
</listeners> |
|||
</phpunit> |
@ -0,0 +1 @@ |
|||
/nelmioapidoc |
@ -0,0 +1,9 @@ |
|||
<?php |
|||
|
|||
use App\Kernel; |
|||
|
|||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; |
|||
|
|||
return function (array $context) { |
|||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); |
|||
}; |
@ -0,0 +1,56 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Controller\Api\v1; |
|||
|
|||
use App\Service\Mattermost\MattermostServiceInterface; |
|||
use OpenApi\Annotations as OA; |
|||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
|||
use Symfony\Component\HttpFoundation\Request; |
|||
use Symfony\Component\HttpFoundation\Response; |
|||
use Symfony\Component\Routing\Annotation\Route; |
|||
use Throwable; |
|||
|
|||
class MattermostController extends AbstractController |
|||
{ |
|||
protected MattermostServiceInterface $mattermostService; |
|||
|
|||
public function __construct(MattermostServiceInterface $mattermostService) |
|||
{ |
|||
$this->mattermostService = $mattermostService; |
|||
} |
|||
|
|||
/** |
|||
* Send message to a mattermost chat. |
|||
* |
|||
* Docs https://docs.mattermost.com/developer/webhooks-incoming.html |
|||
* |
|||
* @Route("/api/v1/send_message", methods={"POST"}) |
|||
* @OA\Tag(name="mattermost") |
|||
* @OA\Parameter( |
|||
* name="message", |
|||
* in="query", |
|||
* required=true, |
|||
* @OA\Schema(type="string") |
|||
* ) |
|||
* @OA\Response( |
|||
* response=200, |
|||
* description="Success delivery" |
|||
* ) |
|||
*/ |
|||
public function sendMessage(Request $request): Response |
|||
{ |
|||
try { |
|||
$message = $request->query->get('message'); |
|||
$response = $this->mattermostService->sendMessage($message); |
|||
|
|||
return new Response($response->getBody()->getContents()); |
|||
} catch (Throwable $e) { |
|||
return new Response( |
|||
$e->getMessage(), |
|||
0 === $e->getCode() ? Response::HTTP_INTERNAL_SERVER_ERROR : $e->getCode() |
|||
); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
<?php |
|||
|
|||
namespace App; |
|||
|
|||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; |
|||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; |
|||
use Symfony\Component\HttpKernel\Kernel as BaseKernel; |
|||
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; |
|||
|
|||
class Kernel extends BaseKernel |
|||
{ |
|||
use MicroKernelTrait; |
|||
|
|||
protected function configureContainer(ContainerConfigurator $container): void |
|||
{ |
|||
$container->import('../config/{packages}/*.yaml'); |
|||
$container->import('../config/{packages}/'.$this->environment.'/*.yaml'); |
|||
|
|||
if (is_file(\dirname(__DIR__).'/config/services.yaml')) { |
|||
$container->import('../config/services.yaml'); |
|||
$container->import('../config/{services}_'.$this->environment.'.yaml'); |
|||
} else { |
|||
$container->import('../config/{services}.php'); |
|||
} |
|||
} |
|||
|
|||
protected function configureRoutes(RoutingConfigurator $routes): void |
|||
{ |
|||
$routes->import('../config/{routes}/'.$this->environment.'/*.yaml'); |
|||
$routes->import('../config/{routes}/*.yaml'); |
|||
|
|||
if (is_file(\dirname(__DIR__).'/config/routes.yaml')) { |
|||
$routes->import('../config/routes.yaml'); |
|||
} else { |
|||
$routes->import('../config/{routes}.php'); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
<?php |
|||
|
|||
namespace App\Service; |
|||
|
|||
use GuzzleHttp\Client; |
|||
|
|||
abstract class BaseService |
|||
{ |
|||
protected Client $client; |
|||
|
|||
public function __construct(string $baseUri) |
|||
{ |
|||
$this->client = new Client(['base_uri' => $baseUri]); |
|||
} |
|||
} |
@ -0,0 +1,55 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Service\Mattermost; |
|||
|
|||
use App\Service\BaseService; |
|||
use GuzzleHttp\Exception\GuzzleException; |
|||
use GuzzleHttp\Psr7\Request; |
|||
use Psr\Http\Message\ResponseInterface; |
|||
|
|||
class MattermostService extends BaseService implements MattermostServiceInterface |
|||
{ |
|||
protected string $mattermostUri; |
|||
protected string $channelName; |
|||
protected string $botName; |
|||
protected string $botIcon; |
|||
|
|||
public function __construct( |
|||
string $mattermostUrl, |
|||
string $mattermostUri, |
|||
string $channelName, |
|||
string $botName, |
|||
string $botIcon |
|||
) { |
|||
parent::__construct($mattermostUrl); |
|||
$this->mattermostUri = $mattermostUri; |
|||
$this->channelName = $channelName; |
|||
$this->botName = $botName; |
|||
$this->botIcon = $botIcon; |
|||
} |
|||
|
|||
/** |
|||
* @throws GuzzleException |
|||
* @throws \JsonException |
|||
*/ |
|||
public function sendMessage(string $message): ResponseInterface |
|||
{ |
|||
$request = new Request('POST', $this->mattermostUri); |
|||
|
|||
$options = [ |
|||
'headers' => [ |
|||
'Content-Type' => 'application/json', |
|||
], |
|||
'body' => json_encode([ |
|||
'channel' => $this->channelName, |
|||
'username' => $this->botName, |
|||
'icon_url' => $this->botIcon, |
|||
'text' => $message, |
|||
], JSON_THROW_ON_ERROR), |
|||
]; |
|||
|
|||
return $this->client->send($request, $options); |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Service\Mattermost; |
|||
|
|||
use Psr\Http\Message\ResponseInterface; |
|||
|
|||
interface MattermostServiceInterface |
|||
{ |
|||
public function sendMessage(string $message): ResponseInterface; |
|||
} |
@ -0,0 +1,433 @@ |
|||
{ |
|||
"composer/semver": { |
|||
"version": "3.2.5" |
|||
}, |
|||
"composer/xdebug-handler": { |
|||
"version": "2.0.2" |
|||
}, |
|||
"doctrine/annotations": { |
|||
"version": "1.0", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "1.0", |
|||
"ref": "a2759dd6123694c8d901d0ec80006e044c2e6457" |
|||
}, |
|||
"files": [ |
|||
"config/routes/annotations.yaml" |
|||
] |
|||
}, |
|||
"doctrine/instantiator": { |
|||
"version": "1.4.0" |
|||
}, |
|||
"doctrine/lexer": { |
|||
"version": "1.2.1" |
|||
}, |
|||
"ergebnis/composer-normalize": { |
|||
"version": "2.13.4" |
|||
}, |
|||
"ergebnis/json-normalizer": { |
|||
"version": "1.0.3" |
|||
}, |
|||
"ergebnis/json-printer": { |
|||
"version": "3.1.1" |
|||
}, |
|||
"fakerphp/faker": { |
|||
"version": "v1.16.0" |
|||
}, |
|||
"friendsofphp/php-cs-fixer": { |
|||
"version": "3.0", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "3.0", |
|||
"ref": "be2103eb4a20942e28a6dd87736669b757132435" |
|||
}, |
|||
"files": [ |
|||
".php-cs-fixer.dist.php" |
|||
] |
|||
}, |
|||
"guzzlehttp/guzzle": { |
|||
"version": "7.3.0" |
|||
}, |
|||
"guzzlehttp/promises": { |
|||
"version": "1.4.1" |
|||
}, |
|||
"guzzlehttp/psr7": { |
|||
"version": "2.0.0" |
|||
}, |
|||
"justinrainbow/json-schema": { |
|||
"version": "5.2.11" |
|||
}, |
|||
"localheinz/diff": { |
|||
"version": "1.1.1" |
|||
}, |
|||
"myclabs/deep-copy": { |
|||
"version": "1.10.2" |
|||
}, |
|||
"nelmio/api-doc-bundle": { |
|||
"version": "3.0", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes-contrib", |
|||
"branch": "master", |
|||
"version": "3.0", |
|||
"ref": "c8e0c38e1a280ab9e37587a8fa32b251d5bc1c94" |
|||
}, |
|||
"files": [ |
|||
"config/packages/nelmio_api_doc.yaml", |
|||
"config/routes/nelmio_api_doc.yaml" |
|||
] |
|||
}, |
|||
"nikic/php-parser": { |
|||
"version": "v4.13.0" |
|||
}, |
|||
"phar-io/manifest": { |
|||
"version": "2.0.3" |
|||
}, |
|||
"phar-io/version": { |
|||
"version": "3.1.0" |
|||
}, |
|||
"php-cs-fixer/diff": { |
|||
"version": "v2.0.2" |
|||
}, |
|||
"php-parallel-lint/php-parallel-lint": { |
|||
"version": "v1.2.0" |
|||
}, |
|||
"phpdocumentor/reflection-common": { |
|||
"version": "2.2.0" |
|||
}, |
|||
"phpdocumentor/reflection-docblock": { |
|||
"version": "5.2.2" |
|||
}, |
|||
"phpdocumentor/type-resolver": { |
|||
"version": "1.5.0" |
|||
}, |
|||
"phpspec/prophecy": { |
|||
"version": "1.14.0" |
|||
}, |
|||
"phpunit/php-code-coverage": { |
|||
"version": "9.2.7" |
|||
}, |
|||
"phpunit/php-file-iterator": { |
|||
"version": "3.0.5" |
|||
}, |
|||
"phpunit/php-invoker": { |
|||
"version": "3.1.1" |
|||
}, |
|||
"phpunit/php-text-template": { |
|||
"version": "2.0.4" |
|||
}, |
|||
"phpunit/php-timer": { |
|||
"version": "5.0.3" |
|||
}, |
|||
"phpunit/phpunit": { |
|||
"version": "9.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "9.3", |
|||
"ref": "a6249a6c4392e9169b87abf93225f7f9f59025e6" |
|||
}, |
|||
"files": [ |
|||
".env.test", |
|||
"phpunit.xml.dist", |
|||
"tests/bootstrap.php" |
|||
] |
|||
}, |
|||
"psr/cache": { |
|||
"version": "2.0.0" |
|||
}, |
|||
"psr/container": { |
|||
"version": "1.1.1" |
|||
}, |
|||
"psr/event-dispatcher": { |
|||
"version": "1.0.0" |
|||
}, |
|||
"psr/http-client": { |
|||
"version": "1.0.1" |
|||
}, |
|||
"psr/http-factory": { |
|||
"version": "1.0.1" |
|||
}, |
|||
"psr/http-message": { |
|||
"version": "1.0.1" |
|||
}, |
|||
"psr/log": { |
|||
"version": "2.0.0" |
|||
}, |
|||
"ralouphie/getallheaders": { |
|||
"version": "3.0.3" |
|||
}, |
|||
"roave/security-advisories": { |
|||
"version": "dev-latest" |
|||
}, |
|||
"sebastian/cli-parser": { |
|||
"version": "1.0.1" |
|||
}, |
|||
"sebastian/code-unit": { |
|||
"version": "1.0.8" |
|||
}, |
|||
"sebastian/code-unit-reverse-lookup": { |
|||
"version": "2.0.3" |
|||
}, |
|||
"sebastian/comparator": { |
|||
"version": "4.0.6" |
|||
}, |
|||
"sebastian/complexity": { |
|||
"version": "2.0.2" |
|||
}, |
|||
"sebastian/diff": { |
|||
"version": "4.0.4" |
|||
}, |
|||
"sebastian/environment": { |
|||
"version": "5.1.3" |
|||
}, |
|||
"sebastian/exporter": { |
|||
"version": "4.0.3" |
|||
}, |
|||
"sebastian/global-state": { |
|||
"version": "5.0.3" |
|||
}, |
|||
"sebastian/lines-of-code": { |
|||
"version": "1.0.3" |
|||
}, |
|||
"sebastian/object-enumerator": { |
|||
"version": "4.0.4" |
|||
}, |
|||
"sebastian/object-reflector": { |
|||
"version": "2.0.4" |
|||
}, |
|||
"sebastian/recursion-context": { |
|||
"version": "4.0.4" |
|||
}, |
|||
"sebastian/resource-operations": { |
|||
"version": "3.0.3" |
|||
}, |
|||
"sebastian/type": { |
|||
"version": "2.3.4" |
|||
}, |
|||
"sebastian/version": { |
|||
"version": "3.0.2" |
|||
}, |
|||
"symfony/asset": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/browser-kit": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/cache": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/cache-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/config": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/console": { |
|||
"version": "5.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "5.3", |
|||
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047" |
|||
}, |
|||
"files": [ |
|||
"bin/console" |
|||
] |
|||
}, |
|||
"symfony/css-selector": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/dependency-injection": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/deprecation-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/dom-crawler": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/dotenv": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/error-handler": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/event-dispatcher": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/event-dispatcher-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/filesystem": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/finder": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/flex": { |
|||
"version": "1.0", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "1.0", |
|||
"ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e" |
|||
}, |
|||
"files": [ |
|||
".env" |
|||
] |
|||
}, |
|||
"symfony/framework-bundle": { |
|||
"version": "5.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "5.3", |
|||
"ref": "414ba00ad43fa71be42c7906a551f1831716b03c" |
|||
}, |
|||
"files": [ |
|||
"config/packages/cache.yaml", |
|||
"config/packages/framework.yaml", |
|||
"config/preload.php", |
|||
"config/routes/framework.yaml", |
|||
"config/services.yaml", |
|||
"public/index.php", |
|||
"src/Controller/.gitignore", |
|||
"src/Kernel.php" |
|||
] |
|||
}, |
|||
"symfony/http-client-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/http-foundation": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/http-kernel": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/options-resolver": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/phpunit-bridge": { |
|||
"version": "5.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "5.3", |
|||
"ref": "97cb3dc7b0f39c7cfc4b7553504c9d7b7795de96" |
|||
}, |
|||
"files": [ |
|||
".env.test", |
|||
"bin/phpunit", |
|||
"phpunit.xml.dist", |
|||
"tests/bootstrap.php" |
|||
] |
|||
}, |
|||
"symfony/polyfill-intl-grapheme": { |
|||
"version": "v1.23.1" |
|||
}, |
|||
"symfony/polyfill-intl-normalizer": { |
|||
"version": "v1.23.0" |
|||
}, |
|||
"symfony/polyfill-mbstring": { |
|||
"version": "v1.23.1" |
|||
}, |
|||
"symfony/polyfill-php73": { |
|||
"version": "v1.23.0" |
|||
}, |
|||
"symfony/polyfill-php80": { |
|||
"version": "v1.23.1" |
|||
}, |
|||
"symfony/polyfill-php81": { |
|||
"version": "v1.23.0" |
|||
}, |
|||
"symfony/process": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/property-info": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/routing": { |
|||
"version": "5.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "5.3", |
|||
"ref": "44633353926a0382d7dfb0530922c5c0b30fae11" |
|||
}, |
|||
"files": [ |
|||
"config/packages/routing.yaml", |
|||
"config/routes.yaml" |
|||
] |
|||
}, |
|||
"symfony/runtime": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/service-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/stopwatch": { |
|||
"version": "v5.3.4" |
|||
}, |
|||
"symfony/string": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/translation-contracts": { |
|||
"version": "v2.4.0" |
|||
}, |
|||
"symfony/twig-bridge": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/twig-bundle": { |
|||
"version": "5.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "5.3", |
|||
"ref": "3dd530739a4284e3272274c128dbb7a8140a66f1" |
|||
}, |
|||
"files": [ |
|||
"config/packages/twig.yaml", |
|||
"templates/base.html.twig" |
|||
] |
|||
}, |
|||
"symfony/var-dumper": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/var-exporter": { |
|||
"version": "v5.3.7" |
|||
}, |
|||
"symfony/web-profiler-bundle": { |
|||
"version": "3.3", |
|||
"recipe": { |
|||
"repo": "github.com/symfony/recipes", |
|||
"branch": "master", |
|||
"version": "3.3", |
|||
"ref": "6bdfa1a95f6b2e677ab985cd1af2eae35d62e0f6" |
|||
}, |
|||
"files": [ |
|||
"config/packages/dev/web_profiler.yaml", |
|||
"config/packages/test/web_profiler.yaml", |
|||
"config/routes/dev/web_profiler.yaml" |
|||
] |
|||
}, |
|||
"symfony/yaml": { |
|||
"version": "v5.3.6" |
|||
}, |
|||
"theseer/tokenizer": { |
|||
"version": "1.2.1" |
|||
}, |
|||
"twig/extra-bundle": { |
|||
"version": "v3.3.3" |
|||
}, |
|||
"twig/twig": { |
|||
"version": "v3.3.3" |
|||
}, |
|||
"webmozart/assert": { |
|||
"version": "1.10.0" |
|||
}, |
|||
"zircote/swagger-php": { |
|||
"version": "3.2.3" |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>{% block title %}Welcome!{% endblock %}</title> |
|||
{# Run `composer require symfony/webpack-encore-bundle` |
|||
and uncomment the following Encore helpers to start using Symfony UX #} |
|||
{% block stylesheets %} |
|||
{#{{ encore_entry_link_tags('app') }}#} |
|||
{% endblock %} |
|||
|
|||
{% block javascripts %} |
|||
{#{{ encore_entry_script_tags('app') }}#} |
|||
{% endblock %} |
|||
</head> |
|||
<body> |
|||
{% block body %}{% endblock %} |
|||
</body> |
|||
</html> |
@ -0,0 +1,19 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Tests\Unit\Controller\Api\v1; |
|||
|
|||
use App\Controller\Api\v1\MattermostController; |
|||
use App\Tests\Unit\UnitTester; |
|||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
|||
|
|||
class MattermostControllerTest extends UnitTester |
|||
{ |
|||
public function testIsExtends(): void |
|||
{ |
|||
$stub = $this->createStub(MattermostController::class); |
|||
|
|||
self::assertTrue(is_subclass_of($stub, AbstractController::class)); |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Tests\Unit; |
|||
|
|||
use App\Kernel; |
|||
use PHPUnit\Framework\TestCase; |
|||
use Symfony\Component\HttpKernel\Kernel as BaseKernel; |
|||
|
|||
class KernelTest extends TestCase |
|||
{ |
|||
public function testIsExtends(): void |
|||
{ |
|||
$kernelStub = $this->createStub(Kernel::class); |
|||
|
|||
self::assertTrue(is_subclass_of($kernelStub, BaseKernel::class)); |
|||
} |
|||
} |
@ -0,0 +1,102 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Tests\Unit\Service\Mattermost; |
|||
|
|||
use App\Service\BaseService; |
|||
use App\Service\Mattermost\MattermostService; |
|||
use App\Service\Mattermost\MattermostServiceInterface; |
|||
use Faker\Factory; |
|||
use GuzzleHttp\Client; |
|||
use GuzzleHttp\Psr7\Request; |
|||
use App\Tests\Unit\UnitTester; |
|||
use Psr\Http\Message\ResponseInterface; |
|||
|
|||
class MattermostServiceTest extends UnitTester |
|||
{ |
|||
public function testIsExtends(): void |
|||
{ |
|||
$stub = $this->createStub(MattermostService::class); |
|||
|
|||
self::assertTrue(is_subclass_of($stub, BaseService::class)); |
|||
} |
|||
|
|||
public function testIsImplements(): void |
|||
{ |
|||
$stub = $this->createStub(MattermostService::class); |
|||
|
|||
self::assertInstanceOf(MattermostServiceInterface::class, $stub); |
|||
} |
|||
|
|||
/** |
|||
* @dataProvider sendMessageDataProvider |
|||
* @throws \ReflectionException |
|||
*/ |
|||
public function testSendMessage( |
|||
string $mattermostUrl, |
|||
string $mattermostUri, |
|||
string $channelName, |
|||
string $botName, |
|||
string $botIcon, |
|||
string $message, |
|||
array $options |
|||
): void |
|||
{ |
|||
$mattermostService = new MattermostService( |
|||
$mattermostUrl, $mattermostUri, $channelName, $botName, $botIcon |
|||
); |
|||
$clientMock = $this->getMockBuilder(Client::class) |
|||
->disableOriginalConstructor() |
|||
->onlyMethods(['send']) |
|||
->getMock(); |
|||
$clientProperty = $this->getClassProperty($mattermostService, 'client'); |
|||
$clientProperty->setValue($mattermostService, $clientMock); |
|||
$responseMock = $this->getMockForAbstractClass(ResponseInterface::class); |
|||
$request = new Request('POST', $mattermostUri); |
|||
|
|||
$clientMock->expects(self::once()) |
|||
->method('send') |
|||
->with($request, $options) |
|||
->willReturn($responseMock); |
|||
|
|||
self::assertEquals( |
|||
$responseMock, |
|||
$mattermostService->sendMessage($message) |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* @throws \JsonException |
|||
*/ |
|||
public function sendMessageDataProvider(): array |
|||
{ |
|||
$faker = (Factory::create('en_EN')); |
|||
$channelName = $faker->sha256(); |
|||
$botName = $faker->sha256(); |
|||
$botIcon = $faker->sha256(); |
|||
$message = $faker->sha256(); |
|||
|
|||
return [ |
|||
[ |
|||
'mattermostUrl' => $faker->sha256(), |
|||
'mattermostUri' => $faker->sha256(), |
|||
'channelName' => $channelName, |
|||
'botName' => $botName, |
|||
'botIcon' => $botIcon, |
|||
'message' => $message, |
|||
'options' => [ |
|||
'headers' => [ |
|||
'Content-Type' => 'application/json', |
|||
], |
|||
'body' => json_encode([ |
|||
'channel' => $channelName, |
|||
'username' => $botName, |
|||
'icon_url' => $botIcon, |
|||
'text' => $message, |
|||
], JSON_THROW_ON_ERROR), |
|||
] |
|||
] |
|||
]; |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Tests\Unit; |
|||
|
|||
use PHPUnit\Framework\TestCase; |
|||
use ReflectionClass; |
|||
use ReflectionException; |
|||
use ReflectionProperty; |
|||
|
|||
class UnitTester extends TestCase |
|||
{ |
|||
/** |
|||
* @throws ReflectionException |
|||
*/ |
|||
public function getClassProperty( |
|||
mixed $classObject, string $propertyName |
|||
): ReflectionProperty |
|||
{ |
|||
$reflector = new ReflectionClass($classObject); |
|||
$property = $reflector->getProperty($propertyName); |
|||
$property->setAccessible(true); |
|||
|
|||
return $property; |
|||
} |
|||
} |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,11 @@ |
|||
<?php |
|||
|
|||
use Symfony\Component\Dotenv\Dotenv; |
|||
|
|||
require dirname(__DIR__).'/vendor/autoload.php'; |
|||
|
|||
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) { |
|||
require dirname(__DIR__).'/config/bootstrap.php'; |
|||
} elseif (method_exists(Dotenv::class, 'bootEnv')) { |
|||
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); |
|||
} |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,2 @@ |
|||
* |
|||
!.gitignore |
@ -0,0 +1,27 @@ |
|||
server { |
|||
set $projectLocation /var/www/localhost; |
|||
server_name localhost; |
|||
|
|||
client_max_body_size 10M; |
|||
client_body_buffer_size 1024k; |
|||
|
|||
location / { |
|||
root $projectLocation/public; |
|||
error_log /var/log/nginx/localhost-error.log; |
|||
access_log /var/log/nginx/localhost-access.log; |
|||
|
|||
location ~ ^/(.*)$ { |
|||
try_files $uri /index.php =404; |
|||
fastcgi_pass app:9000; |
|||
include fastcgi_params; |
|||
fastcgi_split_path_info ^(.+\.php)(/.*)$; |
|||
fastcgi_param PATH_INFO $fastcgi_path_info; |
|||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; |
|||
fastcgi_param DOCUMENT_ROOT $realpath_root; |
|||
|
|||
location ~* \.(jpg|gif|png|css|js|jpeg|pdf|doc|docx|map|ico|eof|woff|woff2|ttf|svg|xls|xlsx|pptx|odt|ods|odp|txt)$ { |
|||
try_files $uri $uri/ /$1 =404; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
FROM php:8.0-fpm-alpine3.14 AS base |
|||
|
|||
RUN apk update && apk upgrade && \ |
|||
apk add --no-cache $PHPIZE_DEPS libzip-dev && \ |
|||
docker-php-ext-install zip pcntl |
|||
|
|||
RUN php -r "readfile('https://getcomposer.org/installer');" \ |
|||
| php -- --install-dir=/usr/local/bin --version=2.1.6 --filename=composer |
|||
|
|||
RUN mkdir -p /var/www/localhost |
|||
WORKDIR /var/www/localhost |
|||
COPY ./app . |
|||
|
|||
|
|||
FROM base AS test |
|||
|
|||
ARG XDEBUG_VERSION=3.0.4 |
|||
RUN curl --proto =https --tlsv1.2 "https://pecl.php.net/get/xdebug-${XDEBUG_VERSION}.tgz" && \ |
|||
pecl install xdebug-${XDEBUG_VERSION}.tgz && \ |
|||
rm -rf xdebug-${XDEBUG_VERSION}.tgz && \ |
|||
rm -rf /tmp/pear && \ |
|||
docker-php-ext-enable xdebug |
|||
COPY devops/docker/php/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini |
|||
COPY env/app/app.env-dist .env |
|||
RUN composer install |
|||
|
|||
|
|||
FROM test AS local |
|||
|
|||
ARG HOME=/home/fedy95 |
|||
ARG USER=fedy95 |
|||
ARG UID=1000 |
|||
ARG GID=1000 |
|||
RUN addgroup --gid ${GID} -S ${USER} && \ |
|||
adduser --uid ${UID} -S ${USER} -G ${USER} |
|||
USER ${USER} |
@ -0,0 +1,9 @@ |
|||
zend_extension=xdebug.so |
|||
xdebug.client_host=host.docker.internal |
|||
xdebug.mode=coverage,debug,profile |
|||
xdebug.discover_client_host=1 |
|||
xdebug.start_with_request=yes |
|||
xdebug.client_port=9000 |
|||
xdebug.extended_info=1 |
|||
xdebug.idekey="PHPSTORM" |
|||
xdebug.log_level=0 |
@ -0,0 +1,22 @@ |
|||
--- |
|||
build-test: |
|||
stage: build-test |
|||
only: |
|||
- merge_requests |
|||
tags: |
|||
- docker |
|||
image: docker |
|||
services: |
|||
- name: docker:dind |
|||
alias: dockerhost |
|||
before_script: |
|||
- echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin "$DOCKER_URL" |
|||
script: |
|||
- | |
|||
docker build --file devops/docker/php/Dockerfile \ |
|||
--tag "$PROJECT_IMAGE_TEST" \ |
|||
--target=test . |
|||
- docker push "$PROJECT_IMAGE_TEST" |
|||
after_script: |
|||
- docker logout "$DOCKER_URL" |
|||
... |
@ -0,0 +1,19 @@ |
|||
--- |
|||
release-tag: |
|||
stage: release |
|||
only: |
|||
- tags |
|||
tags: |
|||
- docker |
|||
image: docker |
|||
services: |
|||
- name: docker:dind |
|||
alias: dockerhost |
|||
before_script: |
|||
- echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin "$DOCKER_URL" |
|||
script: |
|||
- docker build -t ${PROJECT_IMAGE}:latest image -f image/Dockerfile |
|||
- docker push ${PROJECT_IMAGE}:latest |
|||
after_script: |
|||
- docker logout "$DOCKER_URL" |
|||
... |
@ -0,0 +1,19 @@ |
|||
--- |
|||
deploy: |
|||
stage: deploy |
|||
only: |
|||
- tags |
|||
tags: |
|||
- ssh-1.160 |
|||
variables: |
|||
GIT_STRATEGY: none |
|||
before_script: |
|||
- echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin "$DOCKER_URL" |
|||
script: |
|||
- cd /home/fedy95/gitlab/${CI_PROJECT_PATH} |
|||
- git pull |
|||
- make restart |
|||
- make cleanup |
|||
after_script: |
|||
- docker logout "$DOCKER_URL" |
|||
... |
@ -0,0 +1,35 @@ |
|||
--- |
|||
version: "3.4" |
|||
|
|||
services: |
|||
app: |
|||
build: |
|||
context: . |
|||
dockerfile: devops/docker/php/Dockerfile |
|||
target: local |
|||
restart: unless-stopped |
|||
|
|||
env_file: |
|||
- env/app/app.env |
|||
environment: |
|||
COMPOSER_MEMORY_LIMIT: "-1" |
|||
PHP_IDE_CONFIG: "serverName=notification-provider_php" |
|||
volumes: |
|||
- ./app:/var/www/localhost |
|||
- ${HOME}/.composer:${HOME}/.composer |
|||
- ${HOME}/.ssh:${HOME}/.ssh |
|||
expose: |
|||
- "9000" |
|||
|
|||
nginx: |
|||
image: nginx:1.21-alpine |
|||
restart: unless-stopped |
|||
|
|||
depends_on: |
|||
- app |
|||
volumes: |
|||
- ./app:/var/www/localhost |
|||
- ./devops/docker/nginx/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf |
|||
ports: |
|||
- "8054:80" |
|||
... |
@ -0,0 +1,27 @@ |
|||
--- |
|||
version: "3.4" |
|||
|
|||
services: |
|||
app: |
|||
image: registry.fedy95.com/dev/notification-provider:latest |
|||
restart: unless-stopped |
|||
|
|||
env_file: |
|||
- env/app/app.env |
|||
environment: |
|||
COMPOSER_MEMORY_LIMIT: "-1" |
|||
expose: |
|||
- "9000" |
|||
|
|||
nginx: |
|||
image: nginx:1.21-alpine |
|||
restart: unless-stopped |
|||
|
|||
depends_on: |
|||
- app |
|||
volumes: |
|||
- ./app:/var/www/localhost |
|||
- ./devops/docker/nginx/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf |
|||
ports: |
|||
- "8054:80" |
|||
... |
@ -0,0 +1 @@ |
|||
app.env |
@ -0,0 +1,8 @@ |
|||
APP_ENV=dev |
|||
APP_SECRET=a1desf1573d162b7d97ed994df9dd37949 |
|||
|
|||
MATTERMOST_URL= |
|||
MATTERMOST_URI= |
|||
MATTERMOST_CHANNEL_NAME= |
|||
MATTERMOST_BOT_NAME= |
|||
MATTERMOST_BOT_ICON= |
Write
Preview
Loading…
Cancel
Save
Reference in new issue